![Excel 父子层次结构](https://linux22.com/image/1608555/Excel%20%E7%88%B6%E5%AD%90%E5%B1%82%E6%AC%A1%E7%BB%93%E6%9E%84.png)
我有一些数据,我需要创建数据层次结构。
prdCode是孩子和的ID;
prdParent 显示数据的父级;
prdLevel 显示数据必须处于什么级别。0 是最高级。
我需要得到这样的结果:
孩子 | 父母
数据 A | 数据 B1
数据 A1 | 数据 A
数据 B1 | 默认
更改为:
Data B1 Data A Data A1
我需要一个最好使用公式的解决方案。
这棵树可以深达 5 层
答案1
我相信以下程序可以满足您的要求。解决方案分为 4 个部分(常量、辅助函数、函数和触发器)。重要信息请参阅底部的注释
常量
我声明了一个常量来限制我正在检查的行数。
Const ROWMAX As Integer = 12
辅助函数
我创建了一个辅助函数,可以根据级别缩进文本。
Function Indent(level As Integer) As String
Dim result As String
Dim i As Integer
result = ""
i = 1
Do While i <= level - 1
result = result & " "
i = i + 1
Loop
Indent = result
End Function
主功能
这是一个递归函数,从树的根(由调用者指定)开始并打印出该树。
Function Printout2(level As Integer, parentID As String) As String
'Hard-coded range to columns A-G and rows 1-1000.
Dim origData As Range
Set origData = Worksheets(1).Range("A1:G" & ROWMAX)
'Where we store our result from this call.
Dim result As String
'Convenience variable to use during looping operations
Dim currentID As String
Dim currentName As String
If level < 1 Or level >= 6 Then
'If there should be a blank line between "groupings", then replace "" with vbnewline
Printout2 = ""
Else
For i = 1 To ROWMAX
If origData.Rows(i).Columns(4).Value = parentID Then
currentID = origData.Rows(i).Columns(2).Value
currentName = origData.Rows(i).Columns(3).Value
result = result & Indent(level) & currentID & " " & currentName & vbNewLine
result = result & Printout2(level + 1, currentID)
End If
Next i
Printout2 = result
End If
End Function
扳机
最后,我使用 ActiveX 控件(按钮)添加了一个触发器。请注意,我必须指定第一个父级,即字符串"-1"
。如果您有多个根父级,您可以重写此代码以查找所有行prdLevel = 0
,然后对每个根调用Printout2
。
Private Sub CommandButton1_Click()
Worksheets(2).Range("A1").Value = Printout2(1, "-1")
End Sub
输出
这是我执行该程序的输出。
1087 Consumer Electronics
17422 Retail Data Checks
17591 Consumer Electronics Total Retailing
21342 Consumer Electronics (Retail)
16467 In-Home Consumer Electronics
16485 Home Audio and Cinema
23711 Home Video
16500 Portable Consumer Electronics
16521 In-Car Entertainment
17545 Computers and Peripherals
杂项
最后说明一下:
A1
假设所有数据都在第一个工作表上,从带有标题的单元格开始- 假定结果将放置在第二张工作表的单元格中
A1
。 - 当前代码假设只有 1 个根父条目。如果有多个,请更改触发器(或编写另一个函数),该触发器会查找所有根并
Printout2
为每个根调用一次。 - 我做到了不是依赖于
prdLevel
列,因为它可能是错误的,并且仅依赖于父级和子级之间的关系。如果某一行的prdParent
值不正确,则不会将其打印在结果中。