2016-12-02 87 views
-12

我尝试使用vba将我的excel数据转换为树数据。在Excel中构建层级类型的数据表示

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 

我的Excel数据这样,

Source data

我尝试使用我的VBA代码树的数据转换这样的。

Output data format

但是上面的代码并没有为我工作。

有人建议我吗?

感谢

+4

我建议你开始编码,然后用回来当您遇到特定问题时提问。这不是一个代码工厂。顺便说一下,你试图制作的树与链接问题中的树不同,所以完全相同的方法不会起作用。 – OpiesDad

+4

当您最初发布问题时,我解决了这个问题,但没有发布我的答案,因为您不会发布您的代码。现在,您将Christian Payne的答案发布到[在Excel中构建像数据表示的树?](http://stackoverflow.com/questions/1074004/build-a-tree-like-representation-of-data-in-excel)就好像它是你自己的! – 2016-12-21 16:20:02

+0

对不使用数据透视表的解决方案感兴趣? – EEM

回答

2

试试这个,它使用一个临时的数据透视表...

Option Explicit 

Sub TestMakeTree() 


    Dim wsData As Excel.Worksheet 
    Set wsData = ThisWorkbook.Worksheets.Item("Sheet1") 

    Dim rngData As Excel.Range 
    Set rngData = wsData.Range("Data") '<----------------- this differs for me 


    Dim vTree As Variant 
    vTree = MakeTreeUsingPivotTable(ThisWorkbook, rngData) 

    '* print it out next to data, you'd choose your own destination 

    Dim rngDestinationOrigin As Excel.Range 
    Set rngDestinationOrigin = wsData.Cells(rngData.Row, rngData.Columns.Count + 2) 

    rngDestinationOrigin.Resize(UBound(vTree, 1), UBound(vTree, 2)) = vTree 


End Sub 

Function MakeTreeUsingPivotTable(ByVal wb As Excel.Workbook, ByVal rngData As Excel.Range) As Variant 


    Dim oPivotCache As PivotCache 
    Set oPivotCache = CreatePivotCache(wb, rngData) 


    Application.ScreenUpdating = False 
    Dim wsTemp As Excel.Worksheet 
    Set wsTemp = wb.Worksheets.Add 


    Dim oPivotTable As Excel.PivotTable 
    Set oPivotTable = CreatePivotTableAndAddColumns(wsTemp, oPivotCache, rngData.Rows(1)) 
    oPivotTable.RowAxisLayout xlOutlineRow 
    oPivotTable.ColumnGrand = False 
    oPivotTable.RowGrand = False 

    MakeTreeUsingPivotTable = oPivotTable.TableRange1.Value2 
    Application.DisplayAlerts = False 
    wsTemp.Delete 
    Application.DisplayAlerts = True 
    Application.ScreenUpdating = True 

End Function 

Function CreatePivotTableAndAddColumns(ByVal wsDestination As Excel.Worksheet, _ 
      ByVal oPivotCache As Excel.PivotCache, ByVal rngColumnHeaders As Excel.Range) 
    Const csTEMP_PIVOT_NAME As String = "TempMakeTreePivot" 
    Dim sThirdRowDown As String 
    sThirdRowDown = "'" & wsDestination.Name & "'!R3C1" 

    Dim oPivotTable As Excel.PivotTable 
    Set oPivotTable = oPivotCache.CreatePivotTable(TableDestination:=sThirdRowDown, _ 
        TableName:=csTEMP_PIVOT_NAME, DefaultVersion:=xlPivotTableVersion15) 

    Dim rngColumnLoop As Excel.Range, lLoop As Long 
    For Each rngColumnLoop In rngColumnHeaders.Cells 
     lLoop = lLoop + 1 
     With oPivotTable.PivotFields(rngColumnLoop.Value2) 
      .Orientation = xlRowField 
      .Position = lLoop 
     End With 

    Next rngColumnLoop 

    Set CreatePivotTableAndAddColumns = oPivotTable 

End Function 

Function CreatePivotCache(ByVal wb As Excel.Workbook, ByVal rngData As Excel.Range) 
    Dim sFullyQualified As String 
    sFullyQualified = "'" & rngData.Parent.Name & "'!" & rngData.Address 

    Dim oPivotCache As PivotCache 
    Set oPivotCache = wb.PivotCaches.Create(SourceType:=xlDatabase, SourceData:= _ 
     sFullyQualified, Version:=xlPivotTableVersion15) 
    Set CreatePivotCache = oPivotCache 
End Function 
+0

@S Meaden我得到错误(运行时1004:对象'_Worksheet'失败的方法'范围')。 – Venkat

+0

@Venkat在哪一行? –

+0

@S Meaden它显示“方法'范围'的对象'_worksheet'”失败“,我在网上搜索这个问题,但没有运气 – Venkat

2

另一项建议

Sub aaargh() 
Dim o(3) 
    Set ws1 = Sheet1 ' source sheet to adapt 
    Set ws2 = Sheet3 ' target sheet to adapt 
    With ws1 
     nv = .Cells(.Rows.Count, 1).End(xlUp).Row 
     .Range("A1:C" & nv).Sort key1:=.Range("a1"), order1:=xlAscending, _ 
           key2:=.Range("B1"), order2:=xlAscending, _ 
           key3:=.Range("C1"), order3:=xlAscending, _ 
           Header:=xlYes 
     ctrl = 0 
     For i = 2 To nv 
      fl = False 
      For j = 1 To 3 
       If o(j) <> .Cells(i, j) Or fl = True Then 
        ctrl = ctrl + 1 
        o(j) = .Cells(i, j) 
        ws2.Cells(ctrl, j) = o(j) 
        fl = True 
       End If 
      Next j 
      ctrl = ctrl + 1 
      ws2.Cells(ctrl, 4) = .Cells(i, 4) 
     Next i 
    End With 
End Sub 
相关问题