Werken met opsommingen

Inleiding

Niveau

Door het declareren van opsommingen oftewel enumerations, kunnen we erg veel profeit hebben. In deze les leren we wat het zijn, hoe we ze declareren en hoe we ze kunnen gebruiken. In overige voorbeelden op de website zal je meer inspiratie opdoen.

Algemeen

Het Enum statement declareert een lijst met constanten. De leden van de lijst zijn constanten van het type Long, vandaar de naam Enum. Met constanten kunnen we veel doen, maar als we lijsten maken creëren we voor onszelf middelen waardoor de toepassingsmogelijkheden nog meer zullen toenemen.

Normaalgesproken plaats je de opsomming in een standaardmodule, maar in alle gevallen boven de procedures.

In veel gevallen is het niet nodig de leden te nummeren. In andere gevallen is het handig - of zelfs nodig - om meer controle te hebben. Het is allemaal afhankelijk van waarvoor en hoe je de lijsten gaat gebruiken.

Wanneer geen van de leden genummerd zijn, wordt door VBA aan het eerste lid in de lijst automatisch de waarde 0 toegekend. Het volgende lid in de lijst krijgt steeds een nummer dat met 1 is verhoogd aan het lid dat vooraf gaat. In het volgende voorbeeld zal FoodCatTest de waarde 101 krijgen en FoodCatTest2 de waarde 4. (Het is ongebruikelijk een lijst zo te maken, maar dit is slechts ter demonstratie van hoe VBA waarden aan leden toekend indien geen waarde is gedefinieerd.)

Enum opFoodCategory

    FoodCatAll = 0

    FoodCatBread = 100

    FoodCatTest

    FoodCatPotatoes = 2

    FoodCatVegetables = 3

    FoodCatTest2

End Enum

Tip

De nummers die je kiest hoeven niet opeenvolgend te zijn. Je mag ook gerust 100, 200, 300 etc. gebruiken. Dit kan belangrijk zijn voor als het later misschien nodig is nummers toe te voegen (of tussenliggende waarden) zonder dat je een bestaand nummer hoeft te wijzigen. Dat is belangrijk want het zijn immers niet voor niets constanten. Een gebruik van 100, 200, 300 etc. is in sommige gevallen ook nuttig om een bepaald bereik te kunnen bepalen, bijvoorbeeld boven 200 en lager dan 300. Negatieve en dubbele waarden in dezelfde lijst zijn ook toegestaan.

Kies goede namen

Het maakt niet uit welke namen je gebruikt, maar het is wel zaak dat je ze goed kiest, omdat ze uniek moeten zijn. Als je er steeds vanuit gaat dat de lijst en de leden (en afzonderlijke constanten) die je maakt in alle applicaties uniek moeten zijn, kom je later nooit in de problemen. De naam van de opsomming wordt een klasse, de leden zoals gezegd constanten.

De naam opFoodCategory in het volgende voorbeeld is zorgvuldig gekozen: de prefix op is gekozen omdat deze voor Office Programs staat én omdat dit ons overzicht tengoede komt (zie VBE-Verkennen). De reeksen Food en Category geven de specifieke lijst aan, in dit geval een lijst van voedselcategorieën. De namen van de leden moeten ook uniek zijn. Want of constanten nu afzonderlijk of in een lijst zijn opgenomen, maakt niet uit (m.a.w.: de lijst maakt ze niet uniek). Om die reden hebben we de constanten een dusdanige naam gegeven dat duidelijk is dat ze tot een categorie van voedsel behoren. Bread, Potatoes en Vegetables kunnen immers ook tot andere lijsten behoren. En wat gedacht van All... Met dit lid hebben we een speciale bedoeling zoals je in andere lessen zal zien. Het heeft namelijk de standaardwaarde van het type Long, en daar kunnen we wel wat mee. Maar goed, niet alles tegelijk.

Is het nu zo dat je het altijd zo moet doen? Nee, natuurlijk niet. Het is slechts een hulpmiddel om het goed te doen. En ook een aanwijzing dat je soms de tijd moet nemen om goed over dingen na te denken. Echter, als je bijvoorbeeld opsommingen maakt met leden waarvan het zeker is dat ze nooit voor iets anders gebruikt zullen worden én onder voorwaarde dat de namen heel duidelijk zijn zodát je ze niet elders gebruikt, dan hoef je de namen zo niet op te bouwen. Als het altijd maar uniek is. Een voorbeeld hiervan zijn de opsommingen van de functie ParsePath.

Het volgende voorbeeld is het exemplaar dat we zullen gaan gebruiken.

Enum opFoodCategory

    FoodCatAll = 0

    FoodCatBread = 1

    FoodCatPotatoes = 2

    FoodCatVegetables = 3

End Enum

Opmerking De sortering van de lijst, ook bij het aanroepen, is altijd gebaseerd op de naam.

Wanneer de lijst is gedeclareerd, verschijnt deze in het Objectoverzicht (zie VBE-Verkennen) net zoals ingebouwde klassen, constanten en objecten. Het is een onderdeel van de bibliotheek van ons project geworden. Dit betekent dan ook dat we de lijst op dezelfde wijze kunnen gebruiken zoals alle objecten.

Opmerking Alles wat we zelf hebben gedeclareerd wordt vet weergegeven.

Cursussen: klasse FoodCategory in VBE

Lijsten gebruiken

IntelliSense

We hebben de Enum opFoodCategory gedeclareerd. We kunnen er nu op dezelfde manier gebruik van maken als van alle andere objecten. Handig is IntelliSense: door een punt achter een naam te typen, verschijnt er een lijst met leden. In dit geval typen we de naam van de Enum klasse opFoodCategory en de lijst met leden verschijnt.

Het weergeven van de Enum naam in de code (zoals opFoodCategory.FoodCatBread), is - in dit geval - louter om makkelijk een lid (een constante) te kunnen kiezen. Alleen de naam van de constante in de code opnemen (zoals FoodCatBread) geeft hetzelfde resultaat. Want de waarde van een constante die een lid van een Enum is, verschilt niet van de waarde van een constante die geen lid van een Enum is. Een Enum maakt het ons gewoon een stuk makkelijker en de code duidelijker.

Cursussen: IntelliSense algemeen

De klasse gebruiken in de argumentenlijst

Laten we onze techniek wat gaan uitbreiden door de Enum klasse opFoodCategory in een argumentenlijst van een procedure op te nemen. We gaan eerst een procedure maken die we daarna aanroepen. Hoe we dat moeten doen hebben we al eerder in de lessen gehad, maar nu gaan we op een nieuwe wijze een argument aan de argumentenlijst toevoegen.

We gaan een procedure Sub maken, maar het zou net zo goed een procedure Function kunnen zijn. De variabele geven we weer een prefix lng, want de constante die het argument moet vertegenwoordigen is van het type Long. In dit geval noemen we de variabele lngFCat. Handig is een korte naam want dat is makkelijker; het moet wel duidelijk zijn wat de variabele vertegenwoordigt. Zoals gezegd hebben we onze klassen een prefix op (Office Programs) gegeven omdat dat dat ten goede komt aan ons overzicht. De prefix bepaal je uiteraart zelf of je gebruikt hem niet. Na As typ je een spatie en dan opf en de lijst verschijnt. Nu is het nog een kwestie van Pijltje naar beneden en op Tab drukken om het lid te selecteren.

We hebben nu een Long in de argumentenlijst gedeclareerd waarvan de waarde op dezelfde wijze werkt als normaal. Echter, nu hebben we een waarde uit een bestaande lijst gekozen. Dat is op zich al handig, maar er zijn meer voordelen.

Cursussen: IntelliSense in procedurelijst

Neem de volgende voltooide procedure over. In dit voorbeeld wordt met het statement Select Case lngFCat getest op de waarde van het argument lngFCat. Ook hier hoeft je niet per sé opFoodCategory in de code op te nemen.

Opmerking Houdt er altijd rekening mee dat zodra een Case aan de voorwaarde voldoet, code alleen voor dat geval wordt uitgevoerd. Daarna wordt de test Select Case onmiddellijk verlaten en gaat de uitvoering na End Select verder.

Sub ProcName(lngFCat As opFoodCategory)

    

    On Error GoTo Bye_Err

    

    Select Case lngFCat

        Case opFoodCategory.FoodCatAll

            MsgBox "All"

            ' Instructies hier

        Case opFoodCategory.FoodCatBread

            MsgBox "Bread"

            ' Instructies hier

        Case opFoodCategory.FoodCatPotatoes

            MsgBox "Potatoes"

            ' Instructies hier

        Case opFoodCategory.FoodCatVegetables

            MsgBox "Vegetables"

            ' Instructies hier

        Case Else

            MsgBox "Anders instructies"

            ' Instructies hier

    End Select

    

Bye_End:

    Exit Sub

Bye_Err:

    MsgBox MsgErr, vbCritical, MT

    Resume Bye_End

End Sub

Nu we de procedure ProcName hebben gemaakt, gaan we een procedure maken die als voorbeeld dient waarin we ProcName aanroepen en het argument lngFCat makkelijk kunnen kiezen. Zoals eerder in de lessen noemen we de aanroepende procedure eenvoudig CallProcName.

Zoals je in het screenhot ziet, hoeven we nu slechts de naam van de procedure te typen en de lijst met constanten verschijnt vanzelf. In de argumentenlijst hebben we opgedragen dat de leden uit opFoodCategory moeten worden weergegeven. Eén van de leden zal dus de waarde voor het argument lngFCat gaan geven. Althans, dat is normaalgesproken het geval, maar dit betekent niet dat we niet een andere waarde kunnen opgeven. De waarde voor lngFCat is niet afhankelijk van de lijst, maar de lijst wordt weergegeven omdat het de bedoeling is dat de waarde in principe moet worden ingesteld op een item in die lijst. Later in de vervolglessen zullen we namelijk ook niets instellen en dan geldt de standaardwaarde voor het argument wat in dit geval 0 zou zijn (lngFCat is een Long). Uiteindelijk gaat het erom dat je rekening houd met het feit dat elke doorgegeven waarde moet kunnen worden geanalyseerd. In ProcName hebben we bijvoorbeeld een Case Else opgenomen. Dat is niet nodig mits je heel zeker weet dat altijd alleen een waard uit de Enum lijst zal worden doorgeven.

Cursussen: argument klasse opFoodCategorie

Zoals eerder gezegd is het niet per sé nodig de naam van de Enum klasse te typen. Want het gaat om de uiteindelijke waarde zoals dit bij het kiezen van het lid in argumentenlijst eveneens duidelijk wordt. Test nu het effect weer door de invoegpositie in de procedure CallProcName te plaatsen en druk op F5. Nogmaals: je kan een procedure ook via het venster Direct aanroepen. Voor meer, zie VBE verkennen.

Sub CallProcName()

    

    On Error GoTo Bye_Err

    

    ProcName FoodCatPotatoes

    

Bye_End:

    Exit Sub

Bye_Err:

    MsgBox MsgErr, vbCritical, MT

    Resume Bye_End

End Sub

Ook bij ingebouwde klassen

Nu we door en door weten hoe het werkt, is het heel makkelijk om ook gebruik te maken van ingebouwde klassen. Daarbij werkt het namelijk exact hetzelfde. Het enige verschil is, dat we dan niet zelf de opsomingen hoeven te declareren en we snel de juiste waarde kunnen kiezen. In het volgende voorbeeld wordt de klasse AcView enumeration van Access in de argumentenlijst gebruikt. In dit geval staat dat voor een geldige waarde waarmee de methode OpenReport van het DoCmd object het rapport kan openen, afdrukken, weergeven.

Eventueel kan lngView worden getest op een specifieke waarde waarbij je iets speciaals wilt doen. Wanneer je If lngView = hebt getypt, verschijnt de lijst met leden weer omdat VBA dit herkent. Het werkt erg gaaf!

Tip Maak op dezelfde wijze vaker gebruik van gebruikers gedefinieerde en ingebouwde klassen in de argumentlijsten.

Sub ProcName(strReport As String, lngView As AcView, Optional strCrit As String)

    

    ' Analyseer eventueel lngView om iets speciaals te doen.

    If lngView = acViewNormal Then

        ' Instructies

    End If

    

    DoCmd.OpenReport strReport, lngView, , strCrit

    

Nabeschouwing

Doordat we in de eerdere lessen behoorlijk zijn uitgewijd door enkele aspecten goed onder de loep te nemen, komen de essentiële middelen nu tot onze beschikking. En deze les heeft ook weer een pad vrijgemaakt naar nog meer mogelijkheden die het programmeren nog leuker en professioneler maken. En daardoor raak je enthousiast wat weer een belangrijke basis is voor de kwaliteit van je werk. Deze dingen gaan altijd samen...

In de lessen die volgen zullen we meer mogelijkheden laten zien met opsommingen. Eens kijken of we het nog wat leuker en nog professioneler kunnen maken...

Cursussen