Nachtrag: besser OHNE Array
03.07.2016 14:29:24
Michael
Das mit dem Array hatte ich mich interessiert, und es ist auch schön, daß es hinhaut, aber in der Praxis genügt EIN Dictionary völlig: man muß nur den Spaltenbuchstaben vorne dranstellen:
Private Sub Userform_initialize()
Dim wkb As Workbook, wks As Worksheet
Dim ndeMain As MSComctlLib.Node, ndeMain1 As MSComctlLib.Node
Dim i&, SpB$(1 To 20) ' &=as long; SpaltenBuchstabe $=as string
Dim vZ&, bZ&, z& ' vZ=von Zeile, bZ=bis Zeile, z=Zeilenzähler
Dim vS&, bS&, s& ' vS, bS, s = von/Spalte, s=Zähler
Dim dic As Object, a ' Variant, a wie "alles" als Array
' Dim sW ' Variant, wie "stringWert" als Array
Dim sWert1 As String, sWert2 As String, swert3 As String
'Spaltenbuchstaben bis max. 20 Spalten; geht immer, auch ab "AA"
For i = 1 To 20: SpB(i) = Split(Columns(i).Address(0, 0), ":")(0): Next
vZ = 3
Set wkb = ThisWorkbook
Set wks = wkb.Worksheets("Autos")
a = wks.Range("A" & vZ).CurrentRegion
vZ = LBound(a): bZ = UBound(a): vS = LBound(a, 2): bS = UBound(a, 2)
' sW = wks.Range("A1").Resize(1, vS)
Set dic = CreateObject("Scripting.Dictionary")
With Me.TreeView1
.Nodes.Clear
.LineStyle = tvwRootLines
'Hauptknoten
Set ndeMain = .Nodes.Add(, , Key:=Replace(wkb.Name, " ", _
"_", 1, -1, vbTextCompare), Text:=wkb.Name)
For z = vZ To bZ
' Die ERSTE Spalte erhält anscheinend eine Sonderbehandlung...
sWert2 = Replace(a(z, vS), " ", "_", 1, -1, vbTextCompare)
swert3 = sWert2
If Not dic.exists(SpB(vS) & sWert2) Then
dic.Add SpB(vS) & sWert2, a(z, vS)
Set ndeMain1 = .Nodes.Add(ndeMain.Key, 4, Key:=sWert2, Text:=a(z, vS))
Else
Set ndeMain1 = .Nodes(sWert2)
End If
ndeMain1.Sorted = True
' Die 2. bis vorletzte sind identisch?!
' nach Bedarf evtl. String-Array verwenden und _
' Einzelteil mit JOIN zusammensetzen?
For s = vS + 1 To bS - 1
sWert1 = a(z, s)
'Key-Werte im Treeview dürfen kein Leerzeichen enthalten
sWert2 = Replace(sWert1, " ", "_", 1, -1, vbTextCompare)
If Not dic.exists(SpB(s) & swert3 & "~" & sWert2) Then
dic.Add SpB(s) & swert3 & "~" & sWert2, sWert1
Set ndeMain1 = .Nodes.Add(ndeMain1.Key, 4, Key:=swert3 & _
"~" & sWert2, Text:=sWert1)
Else
Set ndeMain1 = .Nodes(swert3 & "~" & sWert2)
End If
ndeMain1.Sorted = True
Next
' und die LETZE bekommt auch eine Sonderbehandlung
sWert1 = a(z, bS)
'fehlende Angaben iin der Spalte 'D' nicht verwerten
If Trim(sWert1) "" Then
'Key-Werte im Treeview dürfen kein Leerzeichen enthalten
swert3 = Replace(sWert1, " ", "_", 1, -1, vbTextCompare)
i = i + 1
Set ndeMain1 = .Nodes.Add(ndeMain1.Key, 4, Key:=sWert2 & _
"~" & i, Text:=sWert1)
ndeMain1.Sorted = True
End If
Next
ndeMain.Expanded = True
ndeMain.Sorted = True
End With
Set ndeMain = Nothing: Set ndeMain1 = Nothing
Set wks = Nothing
Set wkb = Nothing
End Sub
Aha, funktioniert so auch mit 5 Spalten: https://www.herber.de/bbs/user/106705.xlsm
Schöne Grüße,
Michael
P.S.: Danke für die Frage; habe mich auch noch nie mit TreeView beschäftigt.
Abgesehen davon: ein Dic ist eigentlich völlig überflüssig, wenn man die Daten zuvor sortiert: key1=SpalteA bis key(x)=Spalte(x); dann braucht man das nur in ein Array laden und Zeile für Zeile nach Änderungen schauen. Naja, ein Dictionary ist schon sauschnell