这是一个受你的图表启发的狂野想法。在VBA中创建以下看似毫无意义的功能:
Function Owns(Owner As String, ParamArray assets() As Variant) As String Owns = Owner End Function
- 写一个宏来根据以下逻辑用公式替换A列中的字符串:
(显然 - 只输入A2-A6中的公式 - A8-A12中的文字只是我的评论)。要获得这些,请循环访问A列 - 通过扫描到C列来查看他们拥有的内容。如果C列中的字符串也在A列中 - 将所有列A(但没有列C)引用到该资产作为参数拥有()。这适用于A列中的前三个条目。如果资产仅在C列中 - 将引用放在该行的C列中。这适用于A中的最后两个条目。
你为什么想这么做?。好吧 - 选择包含比尔盖茨的单元格,转到“公式”选项卡,然后重复调用 Trace Precedents 。你应该看到:
Trace Precedents
Punchline:VBA Range对象有一个方法 .Precedents() 它将这些细胞作为范围对象。列C中的先前单元格是先前树的叶子。还有一种方法 .DirectPrecedents() 可用于逐层处理树级。在这种情况下它是否有用我老实说不知道,但它似乎是一种很好的方法来获得可以在VBA中操作的数据的树状结构。
.Precedents()
.DirectPrecedents()
编辑:跟踪家属可以让你从T-Bonds回到比尔盖茨。有两种VBA方法对应于此。此外,还有类似的方法 .ShowPrecedents 可用于为箭头设置动画,以允许用户查看受抚养者的流动。我还尝试了一种方法(在C中的某些单元格中使用第二个虚函数),它将A列中的单元格直接链接到C列中的单元格,而单元格C中的单元格又与A列中的单元格相链接。 ShowPrecedents 将显示数据的来回流 - 但我认为这会为树添加多余的级别。
.ShowPrecedents
ShowPrecedents
我写了一个宏,它采用与原始设置相似的电子表格,并添加了虚拟公式。要使用它,你需要
1)创建两个命名范围。 “所有者”是所有者名称的列(A2:这个玩具示例中的A6)和“资产”,它是资产栏的相应部分(这里是C2:C6)。
2)包括对Microsoft Scripting Runtime的引用(VBA编辑器中的工具/引用),以便可以使用字典。
为了完整起见,我再次添加“拥有”的代码以及一个名为“restore”的子,它将用显示的字符串(应该是原始字符串)替换添加的公式:
函数拥有(Owner As String,ParamArray assets()As Variant)As String 拥有=所有者 结束功能
Sub tag() Dim Owner As Range, Asset As Range Dim OwnerAddress As New Dictionary Dim OwnerFormula As New Dictionary Dim OwnerRange As Range Dim ocell As Range, acell As Range Dim owner_name As Variant, asset_name As String Dim formula As String Dim shift As Long Set Owner = Range("Owner") Set Asset = Range("Asset") shift = Asset.Column - Owner.Column '2 now, but user might move columns around For Each ocell In Owner owner_name = LCase(Trim(ocell.Value)) If OwnerAddress.Exists(owner_name) Then OwnerAddress(owner_name) = OwnerAddress(owner_name) & ", " & ocell.Address Else OwnerAddress(owner_name) = ocell.Address End If Next ocell For Each owner_name In OwnerAddress.Keys Set OwnerRange = Range(OwnerAddress(owner_name)) 'e.g. all ocells containing "Bill's Fund" formula = "=Owns(" & """" & OwnerRange.Cells(1).Value & """" For Each ocell In OwnerRange Set acell = ocell.Offset(0, shift) asset_name = LCase(Trim(acell.Value)) If OwnerAddress.Exists(asset_name) Then formula = formula & "," & OwnerAddress(asset_name) Else formula = formula & "," & acell.Address End If Next ocell formula = formula & ")" OwnerFormula.Add owner_name, formula Next owner_name For Each ocell In Owner ocell.formula = OwnerFormula(LCase(Trim(ocell.Value))) Next ocell End Sub