|
楼主 |
发表于 2023-2-26 19:57
|
显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件 ★ 免费下载 ★ ★ 使用帮助★
之前两种写法都需要排序数据,乱序数据不合适,换一种写法
- Sub Main_CreateTree()
- Dim ar, Coll As Collection
- ''' 读入父子结构数据数组,一对一
- ar = ReadFatherSon
- ''' 数据整理到节点集合
- Set Coll = Father_SonToCollection(ar)
- ''' 输出节点数据到表格
- PrintTree Coll, Range("h2")
- End Sub
- Function Father_SonToCollection(ar) As Collection
- Dim fD As Dictionary, sD As Dictionary
- Dim Father$, Son$, i&, j&, x
- Set fD = New Dictionary
- Set sD = New Dictionary
- ''' 父子关系读入字典
- For i = 1 To UBound(ar)
- Father = ar(i, 1)
- Son = ar(i, 2)
- If fD.Exists(Father) Then
- Else
- Set fD(Father) = New Dictionary
- End If
- fD(Father).Add Son, Father
- sD.Add Son, Father
- Next
- ''' 节点整理
- Dim Tree As Collection, Node As ClassNode
- Set Tree = New Collection
- ''' 根节点=============================================================pause
- i = 0: j = 0
- For Each x In fD.Keys
- If Not sD.Exists(x) Then
- i = i + 1 ''' 唯一编号
- j = j + 1 ''' 层内编号
- '''树编码,两位递进默认同一级不超过99个节点
- Set Node = New ClassNode
- Node.addDetail i, 1, 0, Format(j, "00"), x
- Tree.Add Node, CStr(i)
- DFSNode Tree, fD, fD(x), i, 1, Format(j, "00") & "01"
- End If
- Next
- Set Father_SonToCollection = Tree
- exitLine:
- Set fD = Nothing
- Set sD = Nothing
- End Function
- Private Function DFSNode(Tree As Collection, fD As Dictionary, _
- d As Object, nCode&, Level&, strName$)
- Level = Level + 1
- fathercode& = nCode
-
- Dim Node As ClassNode
- Dim fatherNode As ClassNode
- For Each x In d.Keys
- nCode = nCode + 1
- Set Node = New ClassNode
- Node.addDetail nCode, Level, fathercode, strName, x
- Set fatherNode = Tree.Item(CStr(fathercode))
- fatherNode.Children.Add Node
- Tree.Add Node, CStr(nCode)
-
- If fD.Exists(x) Then ''' 不是末级节点,进入下一级节点
- DFSNode Tree, fD, fD(x), nCode, Level, strName & "01"
- Level = Level - 1
- End If
- strName = Left(strName, Len(strName) - 2) & _
- Format(val(Right(strName, 2)) + 1, "00")
- Next
- End Function
- Function PrintTree(Tree As Collection, rangeTopLeft As Range)
- Dim ar(), x As ClassNode
- n = Tree.Count
- ReDim ar(1 To n, 1 To 20)
- For Each x In Tree
- r = r + 1
- With x
- br = Array(.Code, .text, .Level, .Parent, .ChildrenCount, "BM" & .Name)
- For j = 0 To UBound(br)
- ar(r, j + 1) = br(j)
- Next
- ar(r, j + .Level) = .text
- End With
- Next
- rangeTopLeft.CurrentRegion.ClearContents
- rangeTopLeft.Resize(n, UBound(ar, 2)).Value = ar
- End Function
复制代码
- ''' Class Name : ClassNode
- Public Code As Long ''' 节点编号,在全部节点中唯一
- Public Level As Long ''' 所在层级
- Public Name As String ''' ROOT_节点编号_所在层级_目录编码
- Public text As String ''' 文本值
- Public Parent As Long ''' 父节点的编号
- Public Children As Collection
- Public Property Get ChildrenCount() As Long
- ChildrenCount = Children.Count
- End Property
- Public Function addDetail(code0&, level0&, parent0&, name0$, text0)
- Code = code0
- Level = level0
- Parent = parent0
- Name = name0
- text = text0
- End Function
- Private Sub Class_Initialize()
- Set Children = New Collection
- End Sub
复制代码 |
|