Suggesties |
voorbeeldbestand
ListView
|
1. Wat is een ListView ? 1.2 Waarvoor ListView ? 1.3 ListView achtergrond 2. ListView maken 2.1 Userform 2.1.1 Ontwerpmodus 2.1.2 Geopend Userform 2.1.3 Voorbeeldbestand 2.2 In werkblad 2.2.1 ListView opruimen 2.2.2 ListView weergeven 2.2.3 ListView positie 2.2.4 Voorbeeldbestand 2.3 In werkgeheugen 3. Kolomkoppen aanmaken 3.1 Real-time 3.2 Ontwerpmodus 3.3 VBA ontwerp 4. ListItems 4.1 toevoegen 4.2 ListSubItems toevoegen 4.3 Vullen met Array 4.4 Vullen met Listobject 4.5 ListView omvang 5 ListItem lezen en wijzigen 5.1 ListItem lezen 5.2 ListItem wijzigen 5.3 ListSubItem lezen 5.4 ListSubItem wijzigen 5.5 ListSubItem rechtstreeks 5.6 ListSubItem rechtstreeks wijzigen 6 Elementen verwijderen 6.1 ListItem 6.2 Alle ListItems 6.3 ListSubItem 6.4 Alle ListSubItems 7. Afbeeldingen in de ListView 7.1 kolomkop 7.2 ListItem 7.2.1 Verwijderen uit ListItem 7.3 ListSubItem 7.3.1 Verwijderen uit ListSubItem 8 ListView weergeven 8.1 Iconen 8.2 kleine Iconen 8.3 lijst 8.4 rapport 9. Sorteren 9.1 Op datum 9.2 Op getal 9.3 Interaktief sorteren 9.4 Interaktief op datum 9.5 Interaktief op getal 10 ListView gegevens opslaan |
Een ListView in VBA is een verzamelobject: je kunt er teksten in opbergen. De Listbox bevat 'records' (rijen) met 'velden' (kolommen). De bestandenlijst in de Verkenner is zo'n ListView. VBA heeft verschillende andere mogelijkheden om gegevens op te slaan: - een dictionary - een collection - een array variabele - een ActiveX ComboBox - een ActiveX ListBox - een ListBox in een Userform - een sortedlist De keuze voor een van deze methoden is afhankelijk van het te bereiken doel. In deze pagina wordt geen poging gedaan al deze methoden met elkaar te vergelijken. We beperken ons tot een bespreking van de mogelijkheden van de ListView. Zo'n ListView kan deel uitmaken van een userform, van een werkblad als ActiveX-object of volledig in het werkgeheugen. De ListView heeft 4 onderscheidende kenmerken. In de ListView kun je gegevens per record sorteren op iedere gewenste eigenschap. In de ListView kun je gegevens op 4 verschillende manieren zichtbaar maken. In de ListView kun je grafische elementen aan elementen in de ListView toevoegen. Ieder element in de ListView kan direkt benaderd worden met een sleutel (key). 1.2 Waarvoor kun je een ListView gebruiken ? Je kunt de ListView gebruiken om gegevens bij elkaar te zetten en snel te bewerken.Via de ListView zijn ze nl. in het werkgeheugen geladen. In plaats van gegevens te bewerken in een Excel-werkblad, een Word Document, een Powerpointpresentatie, doe je dat in het werkgeheugen. Daarvoor hoeft bijv. geen scherm ververst te worden, hoeven geen berekeningen uitgevoerd te worden. 1.3 Waar komt de ListView vandaan ? De ListView maakt geen deel uit de VBA-bibliotheek (Visual Basic for Applications), de Excel-VBA-bibliotheek (Microsoft Excel x.0 Object Library) of de 'Userform'-bibliotheek (Microsoft Forms 2.0 Object Library).De ListView bevindt zich in de Windows controls bibliotheek (Miocrosoft Windows Common Controls 6.0 (SP6)). Deze bibliotheek is niet standaard geladen. Je kunt de bibliotheek laden in de VBEditor, tabblad 'Extrs' ('Tools'), optie 'references'. In de lijst met bibliotheken tref je deze bibliotheek alfabetisch aan. Vink de de bibliotheek aan om hem te laden. In VBA kun je de bibliotheek op 2 verschillende manieren laden: als GUID en als bestand. GUID ThisWorkbook.VBProject.References.AddFromGuid "{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}", 0, 2 ThisWorkbook.VBProject.References.AddFromFile Replace(Environ("comspec"), "cmd.exe", "MSCOMCTL.OCX") Dat kan in de ontwerpmodus of wanneer het Userform geladen wordt/is. Ook in een werkblad kun je een ListView opnemen. Wanneer je een ListView alleen maar wil gebruiken als hulpmiddel voor opslag/manipulatie van gegevens in het werkgeheugen kan dat ook, volledig onzichtbaar voor de gebruiker. Een ListView in een Userform is altijd leeg en bevat geen gegevens. Daarin komt de ListView overeen met de ComboBox en ListBox in een Userform. Alle eigenschappen van de Userformcontrol die je in ontwerpmodus instelt worden met het Userform bewaard. De gegevens echter niet. 2.1.1 ListView in Ontwerpmodus In de ontwerpmodus van een Userform kun je met behulp van de 'Toolbox' een ListView invoegen.Als de listview niet in de toolbox staat kun je hem toevoegen: - zet de cursor in de toolbox - klik rechter muisknop - klik additional controls .. - vink aan: Microsoft ListView Control, version 6.0 Nadat je de ListView aan het Userform hebt toegevoegd kun je meteen ook een groot aantal eigenschappen instellen. Dat is handig als je vooraf weet welke gegevens je in de ListView wil opnemen. Met de ColumnHeaders kun je bijv. de omvang (het aantal kolommen) van de ListView en eventueel de kolomnamen tevoren vastleggen. Alle eigenschappen kunnen vooraf vastgelegd worden. Het vullen van de ListView met gegevens kan alleen maar bij opening/geopend Userform. 2.1.2 ListView in geopend Userform Om een ListView te kunnen invoegen hoeft de referentie naar de Bibliotheek van de ListView niet geladen te zijn.Deze code is voldoende: Private Sub Userform_Initialize()
Controls.Add "MSComctlLib.ListViewCtrl.2", "snb"
End SubHet is handiger meteen de plaats te bepalen voor de ListView: Private Sub Userform_Initialize()
With Controls.Add("MSComctlLib.ListViewCtrl.2", "snb")
End Sub.Top = 70
End With.Left = 20 .Height = 90 .Width = 120 2.1.3 ListView in voorbeeldbestand Het voorbeeldbetand bevat een Userform.Ter illustratie bevat de Userform_Inititialize gebeurtenis alle code die nodig is om de Listvoiw correct te tonen. Alle eigenschappen kunnen echter beter in de Ontwerpmodus ingesteld worden. Het vullen van de ListView, inclusief de toekenning van iconen, dient altijd met code te gebeuren. Het voorbeeld toont het gebruik van iconen en smallicons voor kolomkoppen, ListItems en ListSubitems. Het voorbeeld bevat ook code om te schakelen tussen de verschillende weergave-opties. Daarvoor hoef je slechts in het getoonde userform te klikken. De _ColumnClick gebeurtenis soreert de kolommen op-/aflopend. Je kunt een ListView als ActiveX-control in een werkblad plaatsen. Daarvoor moet je het 1e argument (Class Type) van de methode 'Add' instellen als "MSComctlLib.ListViewCtrl.2". De overige argumenten zijn niet verplicht. Sheet1.OLEObjects.Add "MSComctlLib.ListViewCtrl.2" Om de lokatie en het formaat van de ListView te bepalen: Sheet1.OLEObjects.Add("MSComctlLib.ListViewCtrl.2", , , , , , , columns(6).left, rows(1).top, 300, 300).name = "snb" 2.2.1 ListView in werkblad opruimen Bij het opslaan van het werkboek blijft de ListView niet behouden.Wil je een ListView gebruiken in een werkblad, dan zul je dat iedere keer bij opening van het werkboek moeten maken. De OLEobject-container van de ListView blijft behouden, het ListView-object in het OLEobject niet. Die OLEobject-container moet je opruimen voordat je een nieuwe ListView kunt maken. Als de naam van de ListView niet bekend is: On Error Resume Next For Each it In Sheet1.OLEObjects x3 = TypeName(it.Object) = "ListView"
NextIf Err.Number <> 0 Then it.Delete Err.Clear Private Sub Workbook_Open()
On Error Resume Next
End SubSheet1.OLEObjects("LV_00").Delete 2.2.2 ListView in werkblad weergeven Er gebeurt bij de aanmaak van een ListView in een werkblad iets vreemds: het OLEobject wordt getoond, maar de ListView niet.Je kunt dit oplossen door eerst van werkblad te wisselen en vervolgens met PgUp en PgDn te scrollen. Je hebt hiervoor dus een werkboek met 2 werkbladen nodig. In VBA Sheet1.OLEObjects.Add("MSComctlLib.ListViewCtrl.2", , , , , , , columns(6).left, rows(1).top, 300, 300).name = "snb" Sheet2.Activate Sheet1.Activate ActiveWindow.LargeScroll 1 ActiveWindow.LargeScroll , 1 2.2.3 ListView in werkblad positie Een ListView maakt deel uit van een OLE-object.Die maakt op zijn beurt weer deel uit van de verzameling afbeeldingen (Shapes) van een werkblad. Een 'Shape' wordt automatisch gekoppeld aan een cel-positie en cel-omvang. Een ListView die voor positie en grootte afhankelijk is van een gekoppelde cel is niet handig. Met de eigenschap .placement = 3 kun je de ListView als een onafhankelijk object in een werkblad zetten. With Sheet1.OLEObjects.Add("MSComctlLib.ListViewCtrl.2", , , , , , , columns(6).left, rows(1).top, 300, 300)
.Name = "snb"
End With.Placement=3 Sheet2.Activate Sheet1.Activate ActiveWindow.LargeScroll 1 ActiveWindow.LargeScroll , 1 2.2.4 ListView in voorbeeldbestand In het voorbeeldbestand bij deze pagina staat in de gebeurteniscode Workbook_Open de code om een Listview in een werkblad te zetten.Alle elementen die ook in het Userform getoond worden zijn in het werkblad zichtbaar. Voor de sorteerroutine zet de macro in Workbook_open de code voor de gebeurtenis _ColumnClick in de macromodule van werkblad Sheet1. In dit geval werk je met de CLSID (ClassIdentification). Je kunt een virtuele ListView aanmaken in het werkgeheugen met de code. With GetObject("New:{996BF5E0-8044-4650-ADEB-0B013914E99C}")
.....
End WithKolomkoppen kun je aan de ListView toevoegen om de 'velden' te benoemen. Kolomkoppen zijn onafhankelijk van het aantal velden van records. - een ListView kan meer kolomkoppen bevatten dan enig record velden heeft. - een ListView kan minder kolomkoppen bevatten dan het aantal velden van een record. Je hebt kolomkoppen nodig: - om de rapportweergave van de ListView te tonen - om de gegevens in de ListView te kunnen sorteren - om de eigenschap .Subitems van een ListItem (= record) te kunnen gebruiken Afzonderlijke kolommen tonen/verbergen Het object 'ColumnHeader' van de ListView heeft geen eigenschap .Visible. Met de eigenschap .Width kun je een kolom afzonderlijk zichtbaar/onzichtbaar maken. Als de eigenschap .Width 0 is, is de kolom niet zichtbaar in de rapportweergave (.View = 3) Alle kolomkoppen tonen De ListView bevat de mogelijkheid in de rapprtweergave wel/geen kolomkoppen te tonen. Of de koppen getoond worden heeft verder geen invloed op het sorteergedrag van de ListView. Toon alle kolomkoppen .HideColumnHeaders =False .HideColumnHeaders =True 3.1 Kolomkoppen aanmaken real-time De methode om kolomkoppen aan te maken bevat 4 argumenten- de index; hiermee kun je de volgorde (van links naar rechts) van de kolom aangeven - de sleutel (key); hiermee kun je met VBA-code rechtstreeks verwijzen naar deze kolom - de koptekst: dit is de tekst die in de ListView als kolomkoptekst wordt getoond - de breedte: hiermee kun je de breedte van de kolom instellen. als je het breedte-argument leeg laat, berekent VBA zelf de kolombreedte op basis van de breedte van de ListView en het aantal kolommen alleen als je daarvan afwijkende breedtes wil hanteren is het gebruik van het breedte-argument zinvol. het effekt van de breedte-instelling is alleen zichtbaar in de weergave van de ListView als 'rappport' (.View = 3) Stel een Userform bevat de ListView 'LV_00'. Je wil kolom 1,2,3 en 4 respektievelijk de breedte 60,30,90 en 60 geven. With LV_00
for jj = 1 to 4
end with.ColumnHeaders.Add , "K_" & jj,"Kolom " & jj, choose(jj, 60, 30, 90, 60)
next.HideColumnHeaders = False 3.2 Kolomkoppen aanmaken in ontwerpmodus Ook in de ontwermodus (Design Mode) kun je de kolomkoppen van de ListView instellen.Klik in het subscherm 'Properties' in de 2e optie 'Custom'. Activeer vervolgens het tabblad 'Column Headers'. 3.3 Kolomkoppen ontwerp vastleggen met VBA Wil je de eigenschappen van de kolomkoppen met VBA voor de ListView met VBA vastleggen dan kan dat met:Sub M_snb()
With ThisWorkbook.VBProject.VBComponents("Userform1").Designer
End SubFor jj = 1 To 4
End With.Controls("LV_00").ColumnHeaders.Add , "K_" & jj, "kolom " & jj, choose(jj, 60, 30, 90, 60)
NextPrivate Sub Userform_Initialize()
For jj = 1 To 4
End SubLV_00.ColumnHeaders(jj).Text = "Kamer " & jj
Next In een ListView heten de 'records' ListItems. De ListView bestaat bestaat dus uit een verzameling (Collection) ListItems. De 'velden' van de records heten in een ListView 'ListSubItems'. Ieder record bestaat uit een verzameling (Collection) ListSubItems. Een record voeg je toe met de opdracht .ListItems.Add De eerste ListItem krijgt de index 1. De methode 'ListItems.Add' heeft 5 argumenten - de positie van het record via het indexnummer als je dit argument weglaat, komt de index overeen met de volgorde waarin de records aan de ListView zijn toegevoegd.
- de unieke sleutel (key) voor het record; niet verplicht- de tekst van het record; niet verplicht - de koppeling aan een afbeelding (icon); niet verplicht - de koppeling aan een kleine afbeelding (smallicon); niet verplicht Het gebruik van afbeeldingen komt later aan bod. Een aantal records invoeren: Private Sub Userform_Initialize()
For j = 1 To 4
End SubLV_00.ListItems.Add , "Sleutel_" & j , "Tekst " & j
Next Sleutels moeten voor ieder ListItem uniek zijn. Als je geen sleutels gebruikt kun je zoveel ListItems met dezelfde tekst toevoegen als je wil. De Index van het ListItem is nu het onderscheidende kenmerk. Vergelijk de Array (zonder sleutels) en de Dictionary (met sleutels). De ListView bevat geen methode om de aanwezigheid van een ListItem met een bepaalde sleutel te testen. Een veld van een record voeg je toe met de opdracht .ListSubItems.Add Het eerste ListSubItem krijgt het indexnummer 1. De methode 'ListSubItems.Add' heeft 5 argumenten - de positie van het veld via het indexnummer
als je dit argument weglaat, komt de index overeen met de volgorde waarin de velden aan de ListView zijn toegevoegd
- de unieke sleutel (key) voor het veld- de tekst van het veld - de koppeling aan een afbeelding (ReportIcon) voor de rapportweergave (.View = 3) het gebruik van afbeeldingen komt later aan bod.
- een tooltip tekst, die getoond wordt als je met de muis boven het veld staatPrivate Sub Userform_Initialize()
With LV_00
End SubFor j = 1 To 4
End WithWith .ListItems.Add( , "Sleutel_" & j , "Tekst " & j)
For jj=1 to 6
Next.ListSubItems.Add ,"Sleutels_" & jj),"Tekst " & jj, ,,"tiptekst " & jj
nextSleutels moeten binnen ieder ListItem uniek zijn. Als je geen sleutels gebruikt kun je zoveel ListSubItems met dezelfde tekst toevoegen als je wil. De Index van het ListSubItem is nu het onderscheidende kenmerk. (Vergelijkbaar met de Array (zonder sleutels) en de Dictionary (met sleutels)). De ListView bevat geen methode om de aanwezigheid van een ListSubItem met een bepaalde sleutel te testen. 4.3 ListView vullen met een Array In veel gevallen zul je gegevens uit een Excel werkblad willen invoeren in een ListView.Als de eerste rij van het werkblad namen voor kolomkoppen bevat kun je deze code gebruiken: Private Sub Userform_Initialize()
sn = Sheet1.Cells(1).CurrentRegion
End SubWith LV_00 For jj = 1 To UBound(sn, 2)
End With.ColumnHeaders.Add , , sn(1, jj)
Next.HideColumnHeaders = False For j = 2 To UBound(sn) With .ListItems.Add(, , sn(j, 1))
NextFor jj = 2 To UBound(sn, 2)
End With.ListSubItems.Add , , sn(j, jj)
Next4.4 ListView vullen met een Listobject Als het werkblad een Listobject ('Tabel') bevat kun je deze code gebruiken:Private Sub Userform_Initialize()
sp = Sheet1.ListObjects(1).HeaderRowRange
End Subsn = Sheet1.ListObjects(1).DataBodyRange With LV_00 For jj = 1 To UBound(sp, 2)
End With.ColumnHeaders.Add , , sp(1, jj)
Next.HideColumnHeaders = False For j = 2 To UBound(sn) With .ListItems.Add(, , sn(j, 1))
NextFor jj = 2 To UBound(sn, 2)
End With.ListSubItems.Add , , sn(j, jj)
Next4.5 De omvang van een ListView De ListView heeft geen eigenschap om de omvang van het aantal records weer te geven.Je gebruikt daarvoor de collectie van ListItems. Msgbox LV_00.ListItems.count Het aantal SubListItems is daarom niet geschikt om het aantal velden weer te geven. Het aantal kolomkoppen bepaalt in ieder geval het aantal kolommen dat in de rapportweergave getoond kan worden. Msgbox LV_00.ColumnHeaders.Count 5.1 ListItem eigenschappen lezen Ieder ListItem heeft eigenschappen, bijv.:- de index
Die kun je per ListItem uitlezen.- de sleutel - de tekst - een gekoppelde afbeelding - een gekoppelde kleine afbeelding for each it in LV_00.ListItems
MsgBox join(array(it.Index,it.Key, it.Text,it.Icon,it.SmallIcon, vbLf)
next5.2 ListItem-eigenschappen wijzigen Ieder ListItem heeft eigenschappen die je kunt wijzigen:- de sleutel
- de tekst - een gekoppelde afbeelding - een gekoppelde kleine afbeelding With LV_00.ListItems("Rob")
it.Key = "Nieuwe Sleutel"
End Withit.Text = "Nieuwe tekst" it.Icon = "peer" it.SmallIcon = "appel" 5.3 ListSubItem-eigenschappen lezen Ieder ListSubItem heeft eigenschappen, bijv.:- de index
Die kun je per ListSubItem uitlezen.- de sleutel - de tekst - een gekoppelde afbeelding voor in de rapportweergave - een popup-tekst bij cursorselectie for each it in LV_00.ListItems("Rob").ListSubItems
MsgBox join(array(it.Index,it.Key, it.Text,it.ReportIcon,it.Tooltiptext, vbLf)
next5.4 ListSubItem-eigenschappen wijzigen Ieder ListSubItem heeft eigenschappen, die je kunt wijzigen bijv.:- de sleutel - de tekst - een gekoppelde afbeelding voor in de rapportweergave - een popup-tekst bij cursors lectie Bijvoorbeeld zo: With LV_00.ListItems("Rob").ListSubItems(1)
it.Key = "Nieuwe Veldsleutel"
End Withit.Text = "Nieuwe veldtekst" it.ReportIcon = "peer" it.ToolTipText = "andere tekst" 5.5 ListSubItem-inhoud rechtstreeks lezen In een ListView kun je aan ieder ListItem ('record') een sleutel toewijzen.In een ListView kun je aan ieder ListSubItem ('veld') van een record een sleutel toewijzen. Op die manier kun je met twee sleutels ieder veld in de ListView direkt lezen. MsgBox LV_00.ListItems("Rob").ListSubItems("Department") Dan kun je gebruik maken van de eigenschap .SubItems of van de verzameling .ListSubItems For j = 1 To LV_00.ListItems("Rob").ListSubItems.Count
msgbox LV_00.ListItems("Rob").ListSubItems(j)
Nextmsgbox LV_00.ListItems("Rob").SubItems(j) For each it in LV_00.ListItems("Rob").ListSubItems
msgbox it
Next5.6 ListSubItem-inhoud rechtstreeks wijzigen In een ListView kun je aan ieder ListItem ('record') een sleutel toewijzen.In een ListView kun je aan ieder ListSubItem ('veld') van een ListItem een sleutel toewijzen. Op die manier kun je met twee sleutels ieder ListSubItem ('veld') in de ListView direkt benaderen en wijzigen. Een ListSubItem kun je wijzigen door de eigenschap .Text te wijzigen. LV_00.ListItems("Rob").ListSubItems("Department").Text = "Magazijn" Dan kun je gebruik maken van de verzameling .ListSubItems. For j = 1 To LV_00.ListItems("Rob").ListSubItems.Count
LV_00.ListItems("Rob").ListSubItems(j).Text = "nieuwe tijd"
NextFor each it in LV_00.ListItems("Rob").ListSubItems
it.Text = it.Text & " nieuw"
NextWelk item verwijderd moet worden geef je aan met de index van het te verwijderen item. Het eerste item heeft indexnummer 1 Dat kan op 2 manieren: - geef direkt het indexnummer door
- roep het indexnummer van het ListItem via de sleutel van het ListItem op With LV_00.ListItems
.Remove 3
End With.Remove LV_00.ListItems("Rob").Index 6.2 Alle ListItems uit de ListView verwijderen Met de opdracht .Clear verwijder je alle ListItems uit de ListView.With LV_00.ListItems
.Clear
End With6.3 Een ListSubItem van een record verwijderen Een ListSubItem kun je verwijderen met de opdracht .Remove.Welk item verwijderd moet worden geef je aan met de index van het te verwijderen item. Het eerste item heeft indexnummer 1 Dat kan op 2 manieren: - geef direkt het indexnummer door
- roep het indexnummer van het ListSubItem via de sleutel van het ListSubItem op With LV_00. ListItems("Rob").ListSubItems
.Remove 3
End With.Remove LV_00.ListItems("Rob").ListSubItems("Department").Index 6.4 Alle ListSubItems uit een ListItem verwijderen Met de opdracht .Clear verwijder je alle ListSubItems uit een ListItem.With LV_00.ListItems("Rob")
.Clear
End With7. Afbeeldingen in de ListView Aan 3 elementen van de ListView kun je afbeeldingen toevoegen:- de ColumnHeader - een ListItem - een ListSubItem Dat betekent dat je naast de tekst van het element ook een afbeelding te zien krijgt. Die afbeeldingen maken geen deel uit van de ListView zelf. Ze bevinden zich in een aparte Control in het Userform of het werkblad. Voor een virtuele ListView is dit niet van toepassing, omdat die volledig onzichtbaar blijft. De control die de afbeeldingen bevat is een ImageList control. Deze control maakt deel uit van dezelfde VBA-bibliotheek als de ListView. In de ListView heten de afbeeldingen Icons. De ListView maakt onderscheid tussen Icons, SmallIcons en ReportIcons. Voor ieder van deze Icons heb je een aparte Imagelist nodig, omdat een Imagelist slechts afbeeldingen van 1 formaat kan bevatten. Een Imagelist kan deel uitmaken van een Userform of een werkblad. Om afbeeldingen te gebruiken dient ieder element van de ListView: ColumnHeader, ListItem of ListSubItem aan een Imagelist gekoppeld te zijn. Het maakt niet uit of die Imagelist zich in een Userform of een werkblad bevindt. 7.1 Afbeeldingen in de kolomkop Kolomkoppen kunnen alleen maar zichtbaar zijn in de rapport-weergave van de ListView.Iconen in kolomkoppen hebben dan ook alleen maar zin als - de rapportweergave wordt gebruikt (.View = 3) - de kolomkoppen ook daadwerkelijk worden getoond ( .HideColumnHeaders = False ) Om iconen aan een kolomkop te 'hechten', leg je een koppeling met de Imagelist met de iconen. Als de ListView in het Userform LV_00 heet en de ImageList in het Userform IL_00: LV_00.ColumnHeaderIcons = IL_00 Dat gebeurt met de eigenschap .Icon van .ColumnHeader. Dat kan voor iedere kolomkop een ander icoon zijn, inclusief geen icoon. Je kunt de naam van het icoon in de Imagelist gebruiken. Bij de aanmaak van een kolomkop LV_00.ColumnHeaders.Add , "sleutel 1", "Tekst 1", 120, "appel" LV_00.ColumnHeaders("sleutel 1").Icon ="appel" Bij de aanmaak van een kolomkop LV_00.ColumnHeaders.Add , "sleutel 1", "Tekst 1", 120, 2 LV_00.ColumnHeaders("sleutel 1").Icon = 2 7.2 Afbeeldingen in een ListItem ListItems kunnen grote en kleine iconen bevatten.De ListView kent nl. een weergave met iconen: .View = 0. De ListView heeft ook een weergave met kleiene iconen: .View = 1. Als je van dat onderscheid gebruik wil maken heb je twee afzonderlijke Imagelists nodig met iconen van verschillende afmetingen. Om iconen aan een kolomkop te 'hechten', leg je een koppeling met de Imagelist met de iconen. Als de ListView LV_00 heet en de ImageList met 'grote' iconen IL_00: LV_00.Icons = IL_00 LV_00.SmallIcons = IL_01 Dat gebeurt met de eigenschap .Icon van .ListItem en/of de eigenschap .SmallIcon. Dat kan voor ieder ListItem een ander icoon zijn, inclusief geen icoon. De afbeeldingen van .Icon en .SmallIcon kunnen eenzelfde afbeelding in een ander formaat zijn, maar het kunnen ook totaal verschillende afbeeldingen zijn. Een Imagelist bevat iconen met een indexnummer en een unieke sleutel. De tekst in de eigenschap .Icon verwijst naar de sleutels van de iconen in de gekoppelde Imagelist. De tekst in de eigenschap .SmallIcon verwijst naar de sleutels van de iconen in de gekoppelde Imagelist. Je kunt de sleutel van het icoon in de Imagelist gebruiken. Bij de aanmaak van het ListItem LV_00.ListItems.Add , "sleutel 1", "tekst 1", "aardbei_groot", "aardbei_klein" LV_00.ListItems("sleutel 1").Icon ="aardbei_groot" LV_00.ListItems("sleutel 1").SmallIcon = "aardbei_klein" Een Imagelist bevat iconen met een indexnummer en een unieke sleutel. Een nummer in de eigenschap .Icon verwijst naar de indexnummers van de iconen in de gekoppelde Imagelist. Een nummer in de eigenschap .SmallIcon verwijst naar de indexnummers van de iconen in de gekoppelde Imagelist. Bij de aanmaak van het ListItem LV_00.ListItems.Add, "sleutel 1", "tekst 1", 3, 7 LV_00.ListItems("sleutel 1").Icon = 3 LV_00.ListItems("sleutel 1").SmallIcon = 7 7.2.1 Afbeelding uit een ListItem verwijderen Je kunt de verwijzing naar een icoon in de eigenschap .Icon verwijderen door aan de eigenschap .Icon de waarde Empty toe te wijzen.LV_00.ListItems("sleutel 1").Icon = Empty LV_00.ListItems("sleutel 1").SmallIcon = Empty Voor de .Icon eigenschap: LV_00.ListItems.Add , "sleutel 1", "tekst 1", iif(LV_00.ListItems.Count mod 2 =0,"aardbei_groot",Empty) Voor de .SmallIcon eigenschap: LV_00.ListItems.Add , "sleutel 1", "tekst 1", , iif(LV_00.ListItems.Count <5,"aardbei_klein",Empty) 7.3 Afbeeldingen in een ListSubItem ListSubItems ('velden' van een ListItem kunnen iconen bevatten.Die zijn, net zoals kolomkoppen, alleen zichtbaar in de rapport-weergave van de ListView. Een ListSubItem maakt geen onderscheid tussen Icons en SmallIcons. Het ListSubItem maakt gebruik van de Imagelist die aan de eigenschap .SmallIcons van de ListView is toegekend. Daarmee bepaal je zelf hoe groot de te tonen iconen zijn. LV_00.SmallIcons = IL_01 Je kunt de naam van de icoon opgeven. Bij de aanmaak van een ListSubItem LV_00.ListItems("Rob").ListSubItems.Add , "sleutel 1", "tekst 1", "appel", "tooltiptekst 1" LV_00.ListItems("Rob").ListSubItems.ReportIcon = "appel" Bij de aanmaak van het ListSubItem: LV_00.ListItems("Rob").ListSubItems.Add , "sleutel 1", "tekst 1", 3, "tooltiptekst 1" LV_00.ListItems("Rob").ListSubItems.ReportIcon = 3 7.3.1 Afbeelding uit een ListSubItem verwijderen Je kunt de verwijzing naar een icoon in de eigenschap .ReportIcon verwijderen door aan de eigenschap .ReportIcon de waarde Empty toe te wijzen.LV_00.ListItems("sleutel 1").ListSubItems(1).ReportIcon = Empty Voor de .ReportIcon eigenschap: LV_00.ListItems("Rob").ListSubItems.Add , "sleutel 1", "tekst 1", IIf(LV_00.ListItems.Count>4, 3, Empty), "tooltiptekst 1" De ListView heeft 4 weergave-opties. In alle weergaven zijn de ListItems zichtbaar. In de rapport-weergave kunnen ook alle ListSubItems ('velden') en kolomkoppen zichtbaar zijn. De eigenschap ListView.View bepaalt de weergave van de ListItems. De ListView.View eigenschap kan de waarde lvwIcon of 0 bevatten voor deze weergave-optie. De teksten van de ListItems verschijnen van linksboven naar rechtsonder. De iconen van de ListItems zie je als: - als de Listview gekoppeld is aan een ImageList via de eigenschap ListView.Icons
De ListView eigenschap .Icons legt een koppeling naar een ImageList.- en ieder ListItem een sleutel of indexnummer in de eigenschap .ListItem(j).Icon bevat Die koppeling is uitsluitend van belang voor déze weergave-optie lvwIcon van de ListView. In alle andere gevallen is de Imagelist van .SmallIcons bepalend. 8.2 ListView weergave: kleine Iconen De ListView.View eigenschap kan de waarde lvwSmallIcon of 1 bevatten voor deze weergave-optie.De teksten van de ListItems verschijnen van linksboven naar rechtsonder. De kleine iconen van de ListItems zie je als: - als de Listview gekoppeld is aan een ImageList via de eigenschap ListView.SmallIcons
De ListView.View eigenschap kan de waarde lvwList of 2 bevatten voor deze weergave-optie.- en ieder ListItem een sleutel of indexnummer in de eigenschap .ListItem(j).SmallIcon bevat De teksten van de ListItems verschijnen van boven naar beneden. Vervolgens van boven naar beneden in kolommen van links naar rechts. De kleine iconen van de ListItems zie je als: - als de Listview gekoppeld is aan een ImageList via de eigenschap ListView.SmallIcons
- en ieder ListItem een sleutel of indexnummer in de eigenschap .ListItem(j).SmallIcon bevat 8.4 ListView weergave: rapport De ListView.View eigenschap kan de waarde lvwReport of 3 bevatten voor deze weergave-optie.De weergave is die van een tabel. kolomkoppen - alle teksten kunnen zichtbaar zijn. - alle iconen kunnen zichtbaar zijn. ListItems - alle teksten kunnen zichtbaar zijn. - alle iconen kunnen zichtbaar zijn. ListSubItems - alle teksten kunnen zichtbaar zijn. - alle iconen kunnen zichtbaar zijn. Welke elementen zichtbaar zijn is afhankelijk van: Kolom: - als de breedte-eigenschap .Width van de kolomkop groter is dan 0 Kolomkop: - als de eigenschap ListView.HideColumnHeaders de waarde False heeft Kolomkop icoon: - als de eigenschap ListView.ColumnHeaderIcons gekoppeld is een aan geldige ImageList - als de eigenschap .Icon van de ColumnHeader een geldige Index of sleutel uit de Imagelist heeft Listitem tekst: - als de corresponderende ColumnHeader zichtbaar is ListItem icoon: - als de corresponderende ColumnHeader zichtbaar is - als de eigenschap ListView.SmallIcons gekoppeld is aan een geldige Imagelist - als de eigenschap .SmallIcon van het ListItem een geldige Index of sleutel uit de Imagelist heeft ListSubItem tekst: - als de corresponderende ColumnHeader zichtbaar is ListSubItem icoon: - als de corresponderende ColumnHeader zichtbaar is - als de eigenschap ListView.SmallIcons gekoppeld is aan een geldige Imagelist - als de eigenschap .ReportIcon van het ListSubItem een geldige Index of sleutel uit de Imagelist heeft De ListView heeft een eigen sorteermethode. De ListView wordt altijd per ListItem ('record') gesorteerd. De sortering maakt gebruik van de indices van de kolomkoppen. Zonder kolomkoppen kun je de ListView niet sorteren. Drie eigenschappen van de ListView bepalen de sortering. - ListView.Sorted de ListView wel/niet sorteren: waarden 0 of 1. - ListView.SortKey geeft de sorteeerkolom aan: indexnummer van een kolom. De eerste kolom van de ListView (met de ListItems) heeft de index 0.
- ListView.SortOrder oplopende of aflopende sortering: waarden 0 of 1.Alle 'velden' in de ListView bevatten tekst. De sortering benut de eigenschap .Text van ListItems en ListSubItems. Een sortering is dan ook altijd een tekstsortering. Hoe getallen en datums gesorteerd kunnen worden komt in 9.1 aan bod. Een ListView op ListItem sorteren With LV_00
For jj = 1 To 4
End With .ColumnHeaders.Add , "Sleutel " & jj, "Tekst " & jj, 80
Next' . . . voeg gegevens in .Sorted = 1 .SortKey = 0 .SortOrder = 0 .SorOrder = lvwascending .SortOrder = 1 .Sortorder = lvwdescending With LV_00
For jj = 1 To 4
End With.ColumnHeaders.Add , "Sleutel " & jj, "Tekst " & jj, 80
Next' . . . voeg gegevens in .Sorted = 1 .SortKey = 3 .SortOrder = 1 Als je een datum weergeeft in de ISO-notatie yyyy-mm-dd (de 'small-endian' weergave) kun je iedere datum correct sorteren. De tekstsortering sorteert nl. van links naar rechts. In VBA zijn datums getallen. Het getal 1 staat voor 01-01-1900. Getallen kun je alleen maar correct als tekst sorteren als ze evenveel posities hebben. Van links naar rechts sorterend is 61 nl. groter dan 567. Alle data tussen 18-05-1927 (10000) en 13-10-2137 (99999) hebben als getal 5 posities; tekstsortering geeft dan hetzelfde resultaat als getalsortering. Wil je in de rapportweergave datums in de vorm dd-mm-yyyy tonen, dan zul je voor de sortering een extra 'kolom' moeten aanmaken. Het is voor de hand liggend om die sorteerkolom te verbergen in de rapportweergave. De sortering vindt dan in de datumsorteerkolom plaats, de weergave is de 'gewone' datumkolom. Sorteren op format De ListView krijgt 3 zichtbare kolommen en 2 niet zichtbare. De eerste kolom bevat het ListItem met een tekst. De tweede, verborgen, datumsorteerkolom bevat de datum uit kolom 4 in de opmaak yyyymmdd. De derde, verborgen, kolom is een sorteerkolom voor getallen. De vierde kolom bevat de datum met de datumopmaak: dd-mm-yyyy. De vijfde kolom is de tekst van het departement. Gegevens worden - gesorteerd, vanwege .Sorted = 1, - oplopend gesorteerd, vanwege .Sortorder = 0 - gesorteerd op de kolom met indexnummer 2, vanwege .SortKey = 2 Private Sub UserForm_Initialize()
sn = Split("naam sorteerdatum sorteergetal datum departement")
End SubWith LV_00 for jj = 0 to 4
End With.ColumnHeaders.Add , sn(jj), sn(jj), iif(jj<2, 0, 60)
NextFor j = 0 To 4 With .ListItems.Add(, , "Naam " & j)
NextFor jj = 1 To 3
End With.ListSubItems.Add , , Choose(jj, Format(Date - j, "yyyymmdd"),"",Date - j, sn(jj) & " " & j,)
Next.Sorted = 1 .SortKey = 2 .SortOrder = 0 .View = 3 De ListView krijgt 3 zichtbare kolommen en 2 niet zichtbare. De eerste kolom bevat het ListItem met een tekst. De tweede, verborgen datumsorteerkolom met de datum uit kolom 4 als getal: CLng(Date –j) De derde, verborgen getalsorteerkolom blijft leeg. De vierde kolom is een datum in gewone datumopmaak: dd-mm-yyyy. De vijfde kolom is de tekst van het departement. Gegevens worden - gesorteerd, vanwege .Sorted = 1, - oplopend gesorteerd, vanwege .Sortorder = 0 - gesorteerd op de kolom met indexnummer 2, vanwege .SortKey = 2 Private Sub UserForm_Initialize()
sn = Split("naam sorteerdatum sorteergetal datum departement")
End SubWith LV_00 For jj = 0 To 4
End With.ColumnHeaders.Add , sn(jj), sn(jj), iif(jj<2, 0, 60)
NextFor j = 0 To 4 With .ListItems.Add(, , "Naam " & j)
NextFor jj = 1 To 4
End With.ListSubItems.Add , , Choose(jj, CLng(Date - j),"",Date - j, sn(jj) & " " & j)
Next.Sorted = 1 .SortKey = 2 .SortOrder = 0 .View = 3 Die beschouwt 61 als een groter getal dan 287. Alleen als alle te sorteren getallen hetzelfde aantal posities hebben komt de tekstsortering overeen met numerieke sortering. Om te zorgen dat tekstsortering van getallen toch de gewenste uitkomst heeeft kunnen we gebruik maken van format. Met format kunnen we nl. alle getallen een gelijk aantal posities geven. Format(61,"000") leidt tot '061" en format(287,"000") tot "287". De tekstsorteermethode beschouwt nu "287" als een groter getal dan "061". Wil je in de rapportweergave getallen als getallen tonen, dan zul je voor de sortering een extra 'kolom' moeten aanmaken. Het is voor de hand liggend om die sorteerkolom te verbergen in de rapportweergave. De sortering vindt dan in de getalsorteerkolom plaats, de weergave is de 'gewone' getalkolom. Sorteren op format De ListView krijgt 3 zichtbare kolommen en 2 niet zichtbare. De eerste kolom bevat het ListItem met een tekst. De tweede, verborgen datumsorteerkolom blijft leeg. De derde, verborgen getalsorteerkolom bevat het getal uit kolom 5 in de opmaak "00000". De vierde kolom is een datum in gewone datumopmaak: dd-mm-yyyy. De vijfde kolom is het nummer van het departement. Gegevens worden - gesorteerd, vanwege .Sorted = 1, - aflopend gesorteerd, vanwege .Sortorder = 1 - gesorteerd op de kolom met indexnummer 3, vanwege .SortKey = 3 Private Sub UserForm_Initialize()
sn = Split("naam sorteerdatum sorteergetal datum departement")
End SubWith LV_00 For jj = 0 To 5
End With.ColumnHeaders.Add , sn(jj), sn(jj), iif(jj<2,0,60)
NextFor j = 0 To 4 With .ListItems.Add(, , "Naam " & j)
NextFor jj = 1 To 4
End With.ListSubItems.Add , , Choose(jj, "", Format(12^j, string(15,"0")),format(Date –j,"dd-mm-yyyy"), 12^j)
Next.Sorted = 1 .SortKey = 2 .SortOrder = 1 .View = 3 Dat is ook in de ListView eenvoudig te realiseren. De ListView bevat de gebeurtenis _ColumnClick Private Sub ListView_ColumnClick(ByVal ColomnHeader As MSComctlLib.ColumnHeader) Iedere kolomkop heeft de eigenschap .SubItemIndex. De eigenschap .SubItemIndex geeft aan aan welke ListSubItem (kolom) de kolomkop gekoppeld is. Als je de kolomkop als schakelknop wil gebruiken voor oplopend en aflopend sorteren, is deze code voldoende: Private Sub LV_00_ColumnClick(ByVal ColomnHeader As MSComctlLib.ColumnHeader)
With LV_00
End Sub.SortKey = ColomnHeader.SubItemIndex
End With.SortOrder = Abs(.SortOrder = 0) 9.4 Interaktief sorteren op datum Voor een datumsortering hebben we een extra sorteerkolom nodig.Ieder record/ListItem komt in de eerste kolom van de ListView te staan. Voor een consistente systematiek gebruiken we het eerste 'veld'/ListSubItem van het 'record'/ListItem als datumsorteerkolom. Vervolgens gebruiken we het tweede 'veld'/ListSubItem van het 'record'/ListItem als getalsorteerkolom. Als er geen datum en/of getalsortering nodig is blijven deze kolommen leeg. Dat vormt geen belemmering voor het funktioneren van de ListView. Als er meer dan 1 datum of getalkolom gesorteerd moet worden heb je voor elk een aparte sorteerkolom nodig. In de gebeurteniscode ListView_ColumnClick krijgt de eigenschap .Sortkey door welke kolom gesorteerd moet worden. Gebruik daarvoor de eigenschap .SubItemIndex van iedere kolomkop. Bij datumsortering is niet de aangeklikte kolom de sorteerkolom. De kolomkop moet informatie over het indexnummer van de gekoppelde sorteerkolom krijgen. De .Tag-eigenschap van de kolomkop is daarvoor geschikt. De .Tag-eigenschap krijgt het indexnummer van de gekoppelde sorteerkolom. De datumgegevens komen in het ListSubItem. Daarnaast moeten ze geformateerd in het ListSubItem van de sorteerkolom terechtkomen. Voor datumgegevens kan dat met format(datum,"yyyymmdd") of Clng(datum). Private Sub UserForm_Initialize()
sn = Sheet1.Cells(1).CurrentRegion
End SubWith LV_00 For jj = 1 To UBound(sn, 2)
end with.ColumnHeaders.Add(, sn(1, jj), sn(1, jj), Choose(jj, 60, 60, 120, 60)).Tag = IIf(IsDate(sn(2, jj)), 1, IIf(IsNumeric(sn(2, jj)), 2, ""))
NextIf jj = 1 Then .ColumnHeaders.Add , "datum_", , 0
End If.ColumnHeaders.Add , "getal_", , 0 .HideColumnHeaders = False For j = 2 To UBound(sn) With .ListItems.Add(, sn(j, 1), sn(j, 1))
Next.ListSubItems.Add , LV_00.ColumnHeaders(2).Key
.ListSubItems.Add , LV_00.ColumnHeaders(3).Key
End WithFor jj = 2 To UBound(sn, 2) .ListSubItems.Add , sn(1, jj), sn(j, jj), , "tooltiptekst" & jj
NextIf IsDate(sn(j, jj)) Then .ListSubItems(1).Text = CLng(sn(j, jj)) If IsNumeric(sn(j, jj)) Then .ListSubItems(2).Text = Format(sn(j, jj), String(15, "0")) .Sorted = 1 .View = 3 Private Sub LV_00_ColumnClick(ByVal ColomnHeader As MSComctlLib.ColumnHeader)
With LV_00
End Sub.SortKey = IIf(ColomnHeader.Tag = "", ColomnHeader.SubItemIndex, ColomnHeader.Tag)
End With.SortOrder = Abs(.SortOrder = 0) 9.5 Interaktief sorteren op getal Voor de getalsortering hebben we een extra sorteerkolom nodig.Ieder record/ListItem komt in de eerste kolom van de ListView te staan. Voor een consistente systematiek gebruiken we het eerste 'veld'/ListSubItem van het 'record'/ListItem als datumsorteerkolom. Vervolgens gebruiken we het tweede 'veld'/ListSubItem van het 'record'/ListItem als getalsorteerkolom. Als er geen datum en/of getalsortering nodig is blijven deze kolommen leeg. Dat vormt geen belemmering voor het funktioneren van de ListView. Als er meer dan 1 datum of getalkolom gesorteerd moet worden heb je voor elk een aparte sorteerkolom nodig. In de gebeurteniscode ListView_ColumnClick krijgt de eigenschap .Sortkey door welke kolom gesorteerd moet worden. Gebruik daarvoor de eigenschap .SubItemIndex van iedere kolomkop. Bij getalsortering is niet de aangeklikte kolom de sorteerkolom. De kolomkop moet daarom informatie krijgen over het indexnummer van de gekoppelde sorteerkolom. De .Tag eigenschap van de kolomkop is daarvoor geschikt. De .Tag-eigenschap krijgt het indexnummer van de gekoppelde sorteerkolom. De getallen moeten ingevoerd worden in het ListSubItem. Daarnaast moeten ze geformateerd in het ListSubItem van de sorteerkolom terechtkomen. Voor getallen kan dat met format(getal,string(15,"0")). Private Sub UserForm_Initialize()
sn = Sheet1.Cells(1).CurrentRegion
End SubWith LV_00 For jj = 1 To UBound(sn, 2)
end with.ColumnHeaders.Add(, sn(1, jj), sn(1, jj), Choose(jj, 60, 60, 120, 60)).Tag = IIf(IsDate(sn(2, jj)), 1, IIf(IsNumeric(sn(2, jj)), 2, ""))
NextIf jj = 1 Then .ColumnHeaders.Add , "datum_", , 0
End If.ColumnHeaders.Add , "getal_", , 0 .HideColumnHeaders = False For j = 2 To UBound(sn) With .ListItems.Add(, sn(j, 1), sn(j, 1))
Next.ListSubItems.Add , LV_00.ColumnHeaders(2).Key
.ListSubItems.Add , LV_00.ColumnHeaders(3).Key
End WithFor jj = 2 To UBound(sn, 2) .ListSubItems.Add , sn(1, jj), sn(j, jj)
NextIf IsDate(sn(j, jj)) Then .ListSubItems(1).Text = CLng(sn(j, jj)) If IsNumeric(sn(j, jj)) Then .ListSubItems(2).Text = Format(sn(j, jj), String(15, "0")) .Sorted = 1 .View = 3 Private Sub LV_00_ColumnClick(ByVal ColomnHeader As MSComctlLib.ColumnHeader)
With LV_00
End Sub.SortKey = IIf(ColomnHeader.Tag = "", ColomnHeader.SubItemIndex, ColomnHeader.Tag)
End With.SortOrder = Abs(.SortOrder = 0) Ook met VBA kan van alles aan een ListView aangepast worden. Als je de resultaten daarvan wil opslaan moet je de gegevens in de ListView eerst uitlezen. Dat kan met een tekstreeks of met een Array. Vervolgens kun je de Array inlezen in een Excel-werklad. Een tekstreeks kun je bijv. opslaan in een Word, .txt of .csv-bestand. Via een Array With LV_00
ReDim sp(.ListItems.Count, .ColumnHeaders.Count)
End WithFor jj = 0 To .ColumnHeaders.Count - 1 sp(0, jj) = .ColumnHeaders(jj + 1).Text
NextFor j = 1 To UBound(sp) sp(j, 0) = .ListItems(j)
NextFor jj = 0 To UBound(sp, 2) - 1 sp(j, jj + 1) = .ListItems(j).ListSubItems(jj + 1)
NextSheet2.Cells(1).Resize(UBound(sp), UBound(sp, 2) + 1) = sp Als de eerste 2 ListSubItem-kolommen sorteerkolommen zijn: With LV_00
For jj = 1 To .ColumnHeaders.Count
End WithIf .ColumnHeaders(jj).Text <> "" Then c00 = c00 & "," & .ColumnHeaders(jj).Text
NextFor j = 1 To .ListItems.Count c00 = c00 & vbCrLf & .ListItems(j)
NextFor jj = 3 To .ListItems(j).ListSubItems.Count c00 = c00 & "," & .ListItems(j).ListSubItems(jj)
NextMsgBox Mid(c00, 2) CreateObject("scripting.filesytemobject").createtextfile("G:\OF\ListView.csv").write c00 |