Invoer via een boomstructuur
- 10/12/2011
Voorbeeldbestanden bij dit artikel: | |
Inleiding
Enkele jaren terug zette ik een artikel op de site over een treeview control: zie hier. Op een userform konden we dan gemakkelijk een boomstructuur afbeelden, waarbij de gebruiker kan afdalen of opklimmen in de structuur. Onlangs werd ik aan dit artikel herinnerd door een opdracht die ik deed. Ik leg de bedoeling van de opdracht zo uit.
De vraag was om per rij de 6 groene velden in te vullen. Met meer dan 5000 rijen is dat manueel een enorm karwei! De invoer dient te gebeuren volgens een bepaalde structuur:
Eerst kies je uit kolom B een productgroep (zo zijn er 15), vervolgens wil je een selectie maken binnen die productgroep: dit is dan de hoofdgroep uit kolom D. Tot slot kies je een artikelgroep uit kolom F, die horen bij de gekozen hoofdgroep.
Treeview
Dit kan je met een treeview control zeer handig oplossen.
Hierboven zie je hoe de gebruiker de plustekens en mintekens kan aanklikken om naar de gewenste artikelgroep te navigeren. Het maken van keuzes werkt bovenaan in de userform het pad bij, zodat men niet de weg kwijt geraakt. Eenmaal op het laagste niveau, de artikelgroep, aangekomen dan zal de tekst "Zet in cellen" op de knop bovenaan oplichten: in de actieve selectie van het werkblad zullen dan kolommen D tot en met I ingevuld worden met codes en namen. Een dubbelklik op de artikelgroep levert hetzelfde resultaat op.
VBA-code
Wat betreft de VBA-code geeft dat het volgende. Leg een referentie naar Microsoft Windows Common Controls 6.0 Het instellen van de tree doe ik zo (bekijk ook het bestand bovenaan deze pagina, het bevat alle code en de referentie):
Sub StelTreeIn()' Wim Gielis ' https://www.wimgielis.com''''' ' Treeview to ease input ' 10/12/11 '''''Dim rng1 As Range, rng2 As Range, rng3 As Range Dim sLevel1 As String, sLevel2 As String, sLevel3 As String Dim nNode As Node Me.TreeView1.Nodes.Clear With ThisWorkbook.Worksheets(2) 'Productgroep For Each rng1 In .Range("A3").Resize(.UsedRange.Rows.Count).SpecialCells(2) sLevel1 = rng1.Text & "|" & rng1.Offset(, 1).Text '==========' ' SYNTAX 1 ' '==========' With Me.TreeView1.Nodes.Add(, , sLevel1, Split(sLevel1, "|")(1)) .Bold = True End With 'Hoofdgroep For Each rng2 In .Range(rng1, rng1.End(xlDown)).Offset(, 2).SpecialCells(2) sLevel2 = rng2.Text & "|" & rng2.Offset(, 1).Text '==========' ' SYNTAX 2 ' '==========' Me.TreeView1.Nodes.Add sLevel1, tvwChild, sLevel2, Split(sLevel2, "|")(1) 'of: Call Me.TreeView1.Nodes.Add(sLevel1, tvwChild, sLevel2, Split(sLevel2, "|")(1)) 'Artikelgroep For Each rng3 In .Range(rng2, rng2.End(xlDown)).Offset(, 2).SpecialCells(2) sLevel3 = rng3.Text & "|" & rng3.Offset(, 1).Text '==========' ' SYNTAX 3 ' '==========' Set nNode = Me.TreeView1.Nodes.Add(sLevel2, tvwChild, sLevel3, Split(sLevel3, "|")(1)) nNode.Tag = Join(Array(sLevel1, sLevel2, sLevel3), "|") Next Next Next End With Me.cmdZetInCel.Enabled = False Me.Label1.Caption = ""End Sub
Dit is de code die de boomstructuur zal opzetten, gebruik makende van de gegevens in het tweede werkblad. Let op de drievoudige syntax (duidelijk gemarkeerd met groene commentaarregels).
Een treeview laat nog meer eigenschappen, methoden en events toe. De eigenschap FullPath vind ik wel nuttig: dit is het pad naar een bepaalde node / selectie. Bekijk dit in combinatie met de eigenschap PathSeparator (ik stelde die in als: ==> ). Ook de NodeClick en DblClick events van de treeview gebruik ik in de code.Het openklappen of dichtklappen van een niveau kan je ook ondervangen, met de Expand en Collapse events.
Veel leerplezier en tijdswinst gewenst.