我有这样一堆原始数据:
Parent | Data
---------------
Root | AAA
AAA | BBB
AAA | CCC
AAA | DDD
BBB | EEE
BBB | FFF
CCC | GGG
DDD | HHH
需要将其转换为时尚树。 这基本上需要在excel电子表格中结束。 如何将上述数据转换为以下数据:
AAA | |
| BBB |
| | EEE
| | FFF
| CCC |
| | GGG
| DDD |
| | HHH
有没有简单的方法只使用VBA?
答案 0 :(得分:12)
我相信你可以整理一下,但这对你提供的数据集起作用。
在开始之前,您需要定义两个名称(插入/名称/定义)。 “数据”是数据集的范围,“目标”是您希望树到达的位置。
Sub MakeTree()
Dim r As Integer
' Iterate through the range, looking for the Root
For r = 1 To Range("Data").Rows.Count
If Range("Data").Cells(r, 1) = "Root" Then
DrawNode Range("Data").Cells(r, 2), 0, 0
End If
Next
End Sub
Sub DrawNode(ByRef header As String, ByRef row As Integer, ByRef depth As Integer)
'The DrawNode routine draws the current node, and all child nodes.
' First we draw the header text:
Cells(Range("Destination").row + row, Range("Destination").Column + depth) = header
Dim r As Integer
'Then loop through, looking for instances of that text
For r = 1 To Range("Data").Rows.Count
If Range("Data").Cells(r, 1) = header Then
'Bang! We've found one! Then call itself to see if there are any child nodes
row = row + 1
DrawNode Range("Data").Cells(r, 2), row, depth + 1
End If
Next
End Sub
答案 1 :(得分:0)
我今天必须查找这个解决方案,我在其他地方找到了它,以防有人正在寻找这个答案
将您想要的工作表指定为“INPUT”
,输出表格为“LEVEL STRUCTURE”
表单位于parent | child
,因此,如果您的数据是向后的,则只需交换列如果它是最顶层的节点,请将root
作为parent
的名称。
这样,A,B列中的每个单元格都有一些值
运行excel vba
Option Explicit
Sub TreeStructure()
'JBeaucaire 3/6/2010, 10/25/2011
'Create a flow tree from a two-column accountability table
Dim LR As Long, NR As Long, i As Long, Rws As Long
Dim TopRng As Range, TopR As Range, cell As Range
Dim wsTree As Worksheet, wsData As Worksheet
Application.ScreenUpdating = False
'Find top level value(s)
Set wsData = Sheets("Input")
'create a unique list of column A values in column M
wsData.Range("A:A").AdvancedFilter Action:=xlFilterCopy, _
CopyToRange:=wsData.Range("M1"), Unique:=True
'Find the ONE value in column M that reports to no one, the person at the top
wsData.Range("N2", wsData.Range("M" & Rows.Count).End(xlUp) _
.Offset(0, 1)).FormulaR1C1 = "=IF(COUNTIF(C2,RC13)=0,1,"""")"
Set TopRng = wsData.Columns("N:N").SpecialCells(xlCellTypeFormulas, 1).Offset(0, -1)
'last row of persons listed in data table
LR = wsData.Range("A" & wsData.Rows.Count).End(xlUp).Row
'Setup table
Set wsTree = Sheets("LEVEL STRUCTURE")
With wsTree
.Cells.Clear 'clear prior output
NR = 3 'next row to start entering names
'Parse each run from the top level
For Each TopR In TopRng 'loop through each unique column A name
.Range("B" & NR) = TopR
Set cell = .Cells(NR, .Columns.Count).End(xlToLeft)
Do Until cell.Column = 1
'filter data to show current leader only
wsData.Range("A:A").AutoFilter Field:=1, Criteria1:=cell
'see how many rows this person has in the table
LR = wsData.Range("A" & Rows.Count).End(xlUp).Row
If LR > 1 Then
'count how many people report to this person
Rws = Application.WorksheetFunction.Subtotal(103, wsData.Range("B:B")) - 1
'insert that many blank rows below their name and insert the names
cell.Offset(1, 1).Resize(Rws).EntireRow.Insert xlShiftDown
wsData.Range("B2:B" & LR).Copy cell.Offset(1, 1)
'add a left border if this is the start of a new "group"
If .Cells(.Rows.Count, cell.Column + 1).End(xlUp).Address _
<> cell.Offset(1, 1).Address Then _
.Range(cell.Offset(1, 1), cell.Offset(1, 1).End(xlDown)) _
.Borders(xlEdgeLeft).Weight = xlThick
End If
NR = NR + 1 'increment to the next row to enter the next top leader name
Set cell = .Cells(NR, .Columns.Count).End(xlToLeft)
Loop
Next TopR
'find the last used column
i = .Cells.Find("*", .Cells(.Rows.Count, .Columns.Count), _
SearchOrder:=xlByColumns, SearchDirection:=xlPrevious).Column
'format the used data range
With Union(.Range(.[B1], .Cells(1, i)), .Range("B:BB").SpecialCells(xlCellTypeConstants, 23))
.Interior.ColorIndex = 5
.Font.ColorIndex = 2
.Font.Bold = True
.HorizontalAlignment = xlCenter
End With
.Range("B1").Interior.ColorIndex = 53
.Range("B1").Value = "LEVEL 1"
.Range("B1").AutoFill Destination:=.Range("B1", .Cells(1, i)), Type:=xlFillDefault
End With
wsData.AutoFilterMode = False
wsData.Range("M:N").ClearContents
wsTree.Activate
Application.ScreenUpdating = True
End Sub