11
BESTURINGSELEMENTEN EN FORMULIEREN De belangrijkste punten van hoofdstuk 11 Besturingselementen zoals knoppen, lijsten invulvakken, keuzerondjes en dergelijke. Er zijn vele dialoogvensters in Excel beschikbaar die u als VBA-programmeur kunt benutten. Mogelijkheden om eigen dialoogvensters samen te stellen. Besturingselementen direct in een werkblad te gebruiken. Interactie met de gebruiker. Gegevens uit een dialoogvenster overbrengen naar een werkblad.
DB_Macros_boek.indb 260
10/11/06 12:00:04
Wat leert u in dit hoofdstuk? Ingebouwd dialoogvenster benutten. De werkbalk Besturingselementen. Een ‘Userform’.
DB_Macros_boek.indb 261
10/11/06 12:00:06
MACRO’S EN VBA IN EXCEL de basis
11.1 Ingebouwde dialoogvensters De ingebouwde dialoogvensters van Excel kent u zeer waarschijnlijk al. Als u bijvoorbeeld in het menu Opmaak de optie Celeigenschappen kiest en een van de tabbladen selecteert, ziet u zo’n dialoogvenster; zie afbeelding 11.1
Afbeelding 11.1 Het dialoogvenster Celeigenschappen, tabblad Uitlijning.
In VBA kunt u zo’n dialoogvenster ook makkelijk oproepen, maar het ziet er dan wel iets anders uit. Laten we dit eens proberen met een eerste oefening.
Oefening 11.1
Ingebouwd dialoogvenster oproepen
1 Open een lege map. 2 Ga naar de VBA-editor en voeg een module toe. 3 Neem de volgende procedure over in de module: C
Sub Dialoogvensters_1() Application.Dialogs(xlDialogAlignment).Show End Sub
4 Klik in de regel Application…en start de uitvoering van de macro met F5. Afbeelding 11.2 geeft het dialoogvenster weer met slechts dat ene tabblad.
262
DB_Macros_boek.indb 262
10/11/06 12:00:06
11 Besturingselementen en formulieren
Afbeelding 11.2 Het dialoogvenster Uitlijning.
5 U mag ook met een objectvariabele werken, dan ziet het er zo uit: C
Dim dlgD As Dialog Set dlgD = Application.Dialogs(xlDialogAlignment) With dlgD .Show End With
De vraag is nu hoe we de door de gebruiker te kiezen informatie aan het dialoogvenster kunnen ontfutselen. Welnu, dat hóeft helemaal niet! Als u vanuit een macro een dialoog laat verschijnen, worden eenvoudig direct de gemaakte keuzes toegepast op de geselecteerde cellen. Elk ingebouwd dialoogvenster bezit tal van parameters. Deze kunt u in de Help vinden als u zoekt naar Dialog Object en dan op de helppagina klikt op Lijst van argumenten voor ingebouwde dialoogvensters. In de lijst zijn tevens alle constanten te vinden voor de ingebouwde dialoogvensters. Veel argumenten zijn niet instelbaar, maar soms is dat wel het geval, bijvoorbeeld bij het dialoogvenster Openen dat de volgende argumenten kent: file_text, update_links, read_only, format, prot_pwd, write_res_pwd, ignore_rorec, file_origin, custom_delimit, add_logical, editable, file_access, notify_logical, converter. Deze argumenten zijn genummerd: file_text is argument nummer 1, read_only is argument 3. Als u de macro samenstelt zoals hierna is aangegeven, dan zult u ook zien dat als u de Show-methode invoert, VBA reageert met de lijst die u in afbeelding 11.3 ziet 263
DB_Macros_boek.indb 263
10/11/06 12:00:07
MACRO’S EN VBA IN EXCEL de basis
Afbeelding 11.3 De argumentenlijst van de methode Show.
Het is een beetje omslachtig in VBA dat we deze argumenten gewoon moeten aftellen. U mag dus schrijven: blnR = .Show(arg3:=True) of blnR = .Show(, , True)
In het laatste geval moet u genoeg komma’s zetten om daarmee aan te geven dat u het derde argument de waarde True wilt geven. De elders in VBA wel geaccepteerde schrijfwijze met benoemde argumenten, levert hier een foutmelding op. Het is grappig om te zien dat wat dit betreft, een - overigens ook weinig gebruikt - deel van de programmeertaal niet af is: blnR = .Show(read_only:=True)
Wilt u een gebruiker dit dialoogvenster tonen met als vaste waarde om een bestand alleen als read-only oftewel alleen-lezen te openen, dan moet dat zo:
Oefening 11.2
Parameter ingebouwd dialoogvenster instellen
1 Neem de volgende procedure over: C
Sub Dialoogvensters_2() Dim blnR As Boolean Dim dlgD As Dialog Set dlgD = Application.Dialogs.Item(xlDialogOpen)
264
DB_Macros_boek.indb 264
10/11/06 12:00:08
11 Besturingselementen en formulieren
With dlgD blnR = .Show(arg3:=True) End With If Not (blnR) Then MsgBox "De gebruiker heeft op annuleren gedrukt" End If End Sub
2 Start de procedure. 3 Selecteer een bestand in het dialoogvenster Openen en klik op de knop Openen. 4 Vergelijk uw resultaat met dat van afbeelding 11.4 en controleer of het geopende bestand in de Excel-titelbalk de aanduiding [Alleen lezen] gekregen heeft.
Afbeelding 11.4 Een bestand is als ‘alleen lezen’ geopend.
Waarom zouden we ons toch met deze dialoogvensters bezighouden? Het is bijvoorbeeld mogelijk om de totale Excel-interface weg te halen (zie hoofdstuk 12) en alleen díe dialogen aan de gebruiker voor te schotelen waarvan u wilt dat ze gebruikt kunnen worden. Het mooie aan het vorige voorbeeld is dat de gebruiker bij het kiezen en openen van het bestand helemaal geen indicatie krijgt dat het bestand als alleen lezen geopend wordt.
11.2 Besturingselementen Besturingselementen zijn onderdelen die normaal in dialoogvensters aangetroffen worden. Voorbeelden van deze elementen zijn: knoppen, lijsten, keuzevakjes en keuzerondjes In tabel 11.1 ziet u een compleet overzicht van de besturingselementen die u in Excel en VBA kunt toepassen.
265
DB_Macros_boek.indb 265
10/11/06 12:00:08
MACRO’S EN VBA IN EXCEL de basis
Tabel 11.1 Afbeelding
Overzicht van besturingselementen Besturingselement
VBA benaming
Toepassing
Selectievakje
CheckBox
Voor het presenteren van niet-unieke keuzes. Er kan bijvoorbeeld gekozen worden voor Vet en Cursief, een van beiden of geen van beiden.
Tekstvak
TextBox
Een kader waar tekst ingevoerd kan worden door de gebruiker of via programmacode.
Keuzerondje
OptionButton
Keuzerondjes staan altijd in groepen bij elkaar en worden gebruikt voor het presenteren van keuzes die elkaar uitsluiten. U kunt bijvoorbeeld kiezen voor liggend of staand afdrukken, maar niet voor beide.
Knop
CommandButton
Een drukknop zoals we die in talloze dialogen aantreffen, met als meest bekende voorbeeld de Annuleren-knop.
Keuzelijst
ListBox
Een kader waarin een lijstje met mogelijkheden gepresenteerd kan worden. Afhankelijk van de instellingen kan de gebruiker uit de lijst een of meer mogelijkheden kiezen. De keuzelijst heeft vaste afmetingen.
Keuzelijst met invoervak
ComboBox
Dit is een combinatie van een eenregelig tekstvak en een lijst. Naast het tekstvak dat hier aangeduid wordt met invoervak vinden we een menusymbool Als de gebruiker hierop klikt valt de lijst open en toont de beschikbare keuzes. Het is mogelijk dat de gebruiker items aan de lijst toevoegt omdat in het invoervak iets getypt kan worden. Via wat programmacode kan het getypte aan de lijst toegevoegd worden.
WisselKnop
ToggleButton
Wisselt tussen twee toestanden.
Kringveld
Spinbutton
Klein knopje met twee pijltjes die omhoog en omlaag wijzen. Erop klikken doet meestal een waarde op- of weer aflopen.
Schuifbalk
ScrollBar
De bekende schuiven die u ook in Excel rechts en onderaan in een documentvenster ziet.
Label
Label
Een label wordt gebruikt om verklarende teksten bij andere besturingselementen te zetten of om eenvoudige mededelingen aan de gebruiker te doen.
Afbeelding
Image
Een kader dat u kunt gebruiken om afbeeldingen in te plaatsen.
266
DB_Macros_11.indd 266
10/11/06 12:11:40
11 Besturingselementen en formulieren
Afbeelding 11.5 Alle gangbare besturingselementen in een werkblad getekend.
In afbeelding 11.5 ziet u enkele belangrijke onderdelen: Rechtsonder de werkbalk Besturingselementen. Alle gangbare besturingselementen die op deze werkbalk te vinden zijn, zijn in dezelfde volgorde als ze op de werkbalk hebben, in het werkblad getekend. Bij besturingselementen waarvan de VBA-benaming niet in het element genoemd wordt, is een kader geplaatst waarin u de naam kunt aflezen. Deze naam is via tabel 11.1 te herleiden naar de benaming op de tooltips van werkbalk. Rechtsboven het dialoogvenster Eigenschappen waarmee u elk individueel besturingselement kunt instellen. De eigenschappen van de CommandButton worden weergegeven omdat deze geselecteerd is. Er is wel een bepaalde volgorde die u dient aan te houden om succesvol met besturingselementen te kunnen werken: 1 Zet de werkbalk Besturingselementen op het scherm via het menu Beeld,Werkbalken; 2 Klik op de knop Ontwerpmodus;
267
DB_Macros_boek.indb 267
10/11/06 12:00:12
MACRO’S EN VBA IN EXCEL de basis
3 Selecteer een besturingselement en teken het op het werkblad op dezelfde manier zoals u met een tekenprogramma werkt. 4 Klik op de knop Eigenschappen om de kenmerken van het getekende element in te kunnen stellen;
5 Klik op de knop Programmacode weergeven om bij de standaardgebeurtenis te komen dat bij het besturingselement hoort. Indien nodig voegt u daar de gewenste programmacode toe of verwijst u naar een procedure (macro) die uitgevoerd moet worden.
11.2.1 Besturingselementen in een werkblad Het plaatsen van besturingselementen in het werkblad is een vrij eenvoudige procedure. Volg deze stappen om een besturingselement in het werkblad te plaatsen, de eigenschappen ervan in te stellen en er een macro aan te koppelen. De macro die bij een besturingselement hoort, wordt in een specifieke procedure geplaatst die een gebeurtenisprocedure of event genoemd wordt; daarover in paragraaf 11.2.3 meer.
Oefening 11.3
Besturingselement in een werkblad plaatsen
1 Selecteer een leeg werkblad. 2 Kies in het menu Beeld,Werkbalken en selecteer in het uitvouwmenu Werkset Besturingselementen; zie afbeelding 11.6. 3 Klik op de knop Opdrachtknop en trek ergens op het werkblad een kader. Als u de muisknop los laat, tovert Excel een knopje op de plaats van het kader; zie afbeelding 11.7.
Het is belangrijk dat u even goed naar de werkbalk Werkset Besturingselementen kijkt. De knop Ontwerpmodus heet nu Ontwerpmodus afsluiten. Dit verschil lijkt klein, maar de effecten zijn groot. Zie hiervoor ook tabel 11.2.
268
DB_Macros_boek.indb 268
10/11/06 12:00:13
11 Besturingselementen en formulieren
Afbeelding 11.6 De werkbalk Werkset Besturingselementen op het scherm zetten
Afbeelding 11.7 Een knop in het werkblad
269
DB_Macros_boek.indb 269
10/11/06 12:00:14
MACRO’S EN VBA IN EXCEL de basis
Tabel 11.2 Pictogram
ONTBREEKT>
***knop-ontwerpmodusafsluiten.jpg
Instellingen van de Ontwerpmodus Knop naam
Effect
Ontwerpmodus
Besturingselementen in een werkblad kunnen gebruikt worden voor het doel waarvoor ze ontworpen zijn. De knop kan nu bijvoorbeeld met de muis ingedrukt worden.
Ontwerpmodus afsluiten
Nu kunt u elk besturingselement in het werkblad selecteren, de afmetingen aanpassen, het element verslepen, eigenschappen instellen en er een macro aan koppelen.
4 Het besturingselement kan verplaatst worden door de muiscursor er midden op zetten en het te verslepen.
5 Het aanpassen van de afmetingen gebeurt door een handvat te verslepen.
6 Klik in de werkbalk Werkset Besturingselementen op de knop Ontwerpmodus afsluiten. 7 Klik nu met de muis op de knop die in het werkblad getekend is. U ziet dat de knop nu ‘ingedrukt’ wordt. Er gebeurt echter nog niets omdat we er nog een macro aan moeten koppelen. Bovendien moet de standaardtekst op de knop vervangen worden. We kunnen dit doen door de eigenschappen van dit besturingselement aan te passen.
11.2.2 Eigenschappen van een besturingselement instellen Eerst worden de eigenschappen van het besturingselement ingesteld. Afhankelijk van het type besturingselement, zijn er per element soms wel tientallen eigenschappen. In tabel 11.3 zijn een aantal veelgebruikte eigenschappen van de knop op een rijtje gezet om een idee te geven. Er is één eigenschap die uitermate belangrijk is bij het werken met besturingselementen en dat is de eigenschap Name. De Name property bepaalt de naam waaronder het element binnen de macro bekend is. Het is namelijk vaak nodig om ook in een macro een besturingselement aan te kunnen spreken. U kunt daar verder in dit hoofdstuk een voorbeeld van zien. Belangrijk is dat u de Name property altijd opgeeft. Laat u dit na, dan krijgt het besturingselement een generieke naam op het moment dat het getekend wordt. In dit geval is dat CommandButton1. U ziet deze naam ook op de 270
DB_Macros_boek.indb 270
10/11/06 12:00:15
11 Besturingselementen en formulieren
knop staan. Wellicht verwarrend, maar het opschrift van de knop wordt weer door een andere eigenschap bepaald, namelijk de eigenschap Caption. VBA (of zo u wilt: Excel) maakt de caption van een knop echter standaard identiek aan de generieke naam.
Oefening 11.4
Eigenschappen van een besturingselement vinden
1 Klik in de werkbalk Werkset Besturingselementen op de knop Ontwerpmodus. 2 Selecteer de eerder aangemaakte CommandButton1-knop of maak deze alsnog aan. U ziet nu de handvaten verschijnen. 3 Klik op de werkbalk op de knop Eigenschappen. Het gelijknamige venster verschijnt.
4 Bekijk de inhoud; er moeten vijfentwintig eigenschappen zijn die alle bij de commandbutton horen. 5 Bekijk tabel 11.3 voor een uitleg van de eigenschappen. Tabel 11.4
Eigenschappen van de knop (CommandButton)
Eigenschap
Functie
(Name)
Bepaalt de naam van een besturingselement zoals het in de programmacode bekend zal staan.
Accelerator
Een van de letters van het opschrift van de knop. De knop kan dan ook ’ingedrukt’ worden met de toetsencombinatie Alt + deze letter. Kies een letter die niet als Accelerator in een van de menu’s gebruikt wordt!
AutoSize
De afmeting van het besturingselement wordt automatisch aangepast aan de hoeveelheid gegevens als de waarde True aangegeven wordt. Voor de knop betekent dat aanpassing van de afmeting aan de hoeveel tekst van de eigenschap Caption.
BackColor
De achtergrondkleur. Deze eigenschap geeft twee paletten: Palet en Systeem. Via Palet kunt u willekeurige kleuren kiezen, via de keuze Systeem alleen Windows systeem kleuren die in te stellen zijn via het configuratiescherm.
BackStyle
Knoppen kunnen opaque (ondoorzichtig) of transparant zijn.
Caption
Dit is het opschrift op de knop.
Enabled
Een eigenschap die bepaald of een knop ingedrukt kan worden of niet. Soms is het nodig een knop (tijdelijk) uit te schakelen tot de gebruiker een bepaalde handeling verricht of een bepaald gegeven verstrekt heeft. Dat kan met Knop.Enabled = False. Aanzetten gebeurt met Knop.Enabled = True.
271
DB_Macros_11.indd 271
10/11/06 12:50:34
MACRO’S EN VBA IN EXCEL de basis
Eigenschap
Functie
ForeColor
De kleur van het opschrift op de knop.
Height
De hoogte van de knop opgegeven in pixels.
Left
De positie in het werkblad of het formulier ten opzichte van de linkerrand. Zie paragraaf ?? voor het werken met formulieren.
Locked
Bepaalt met de booleaanse waarden True en False of een besturingselement bewerkt kan worden of niet.
MouseIcon
Kies een bepaalde afbeelding die verschijnt als u met de muis boven de knop komt én als de volgende eigenschap hierna ingesteld wordt op 99-frmMousePointerCustom.
MousePointer
Kies een van de ingebouwde muiscursors of de waarde 99-frmMousePointerCustom als u bij de vorige eigenschap een afbeelding hebt opgegeven.
Picture
Zet een afbeelding op de knop. Vaak worden hiervoor pictogrammen gebruikt.
PicturePosition
Plek van de afbeelding.
Placement
Bepaalt hoe het object zich gedraagt ten opzichte van de onderliggende cellen.
PrintObject
Bij het afdrukken van een werkblad bepaalt de waarde in deze eigenschap of de knop mee afgedrukt wordt (True) of niet (False).
Shadow
Geeft met de waarde True een schaduw onder de knop.
TakeFocusOnClick
Indien er meer elementen in het werkblad liggen, kan dit element de focus krijgen als er op geklikt wordt. Een knop die de ’focus‘ heeft is te herkennen aan het stippellijntje rond het opschrift op de knop.Een knop met focus kan ook geactiveerd worden met de spatiebalk of de Enter-toets. Hebt u een textbox en een knop in het werkblad en wilt u dat de textbox altijd geselecteerd blijft, ook al wordt er op de knop geklikt, dan geeft u deze property voor de knop de waarde False en voor de Textbox de waarde True.
Top
De afstand van de knop tot de bovenzijde van het werkblad.
Visible
Met Visible = True is de knop zichtbaar in het werkblad, met Visible = False is de knop er wel, maar niet zichtbaar. Een knop die onzichtbaar is, kunt u vanuit een macro wél benaderen om bijvoorbeeld het opschrift te wijzigen.
Width
De breedte van de knop uitgedrukt in pixels.
WordWrap
Met de waarde True kunt u meer regels kwijt in een element. Voor het opschrift op een knop wellicht niet zo heel interessant, maar bijvoorbeeld wel voor een textbox als u de gebruiker de mogelijkheid wilt geven meer regels tekst in te voeren.
Oefening 11.5
Eigenschappen van een besturingselement instellen
Het instellen van de eigenschappen is erg eenvoudig omdat u van de meeste eigenschappen direct het effect ziet. Microsoft stopt soms enorm veel cosmetische zaken in de software en daarvan zien we vooral ook hier het directe resultaat. Enkele eigenschappen zijn natuurlijk erg belangrijk. 1 Selecteer de knop indien dit nodig is.
272
DB_Macros_boek.indb 272
10/11/06 12:00:16
11 Besturingselementen en formulieren
2 Geef als Name-property cmdKnop. 3 De Accelerator wordt f. 4 De Caption wordt Afsluiten. U ziet een streepje verschijnen onder de letter f; dat is de accelerator Hierdoor kan de knop ook ingedrukt worden met Alt + f. Dit is ook bekend als de sneltoets. 5 Experimenteer zelf met verschillende andere eigenschappen om er een gevoel voor te krijgen. Van sommige eigenschappen zoals Enabled ziet u pas het effect als u in de werkbalk Werkset Besturingselementen eerst op de knop Ontwerpmodus afsluiten klikt! 6 Bekijk ook de werking van het tabblad Alfabetisch en Gecategoriseerd in het venster Eigenschappen.
HONGAARSE NOTATIE Het is een goede gewoonte besturingselementen een naam te geven die begint met drie letters waaruit u kunt afleiden om welk type besturingselement het gaat, zoals: cmd voor CommandButton; txt voorTextBox; cmb voor ComboBox; scr voor ScrollBar. Elders in het boek hebt u gezien dat ik die gewoonte ook toepas bij namen van variabelen: int: Integer; lng: Long; str: String; var: Variant. De programmacode wordt daardoor beter leesbaar en u weet later als er onderhoud gepleegd moet worden onmiddellijk om welk type object of variabele het gaat. We noemen deze notatiewijze zo omdat naar verluidt een Microsoft-programmeur van Hongaarse afkomst er mee op de proppen kwam.
11.2.3 Gebeurtenisprocedures Als u een besturingselement aan een werkblad hebt toegevoegd, zal er nog geen actie aan gekoppeld zijn. Om wel iets te laten gebeuren, moeten we een macro programmeren of verwijzen naar een bestaande macro. De vraag is: wanneer willen we dat er iets gebeurt? Daartoe moeten we eerst weten wat de mogelijkheden van het besturingselement zijn.
273
DB_Macros_boek.indb 273
10/11/06 12:00:16
MACRO’S EN VBA IN EXCEL de basis
Elk besturingselement is standaard voorzien van een aantal uit te voeren gebeurtenissen. Voor een knop is dat bijvoorbeeld de klik op de knop wat tot het Click event leidt. Dat is een gebeurtenis waar de knop voor is uitgevonden en het is dan ook het standaard event van dit besturingselement. Voor een tekstvak is dat weer het Change event, er verandert iets in het tekstvak. Elk besturingselement heeft zijn standaard event, maar daarnaast ook nog enkele andere mogelijkheden. Hoe komen we bij de events van een besturingselement?
Oefening 11.6
Gebeurtenissen van een besturingselement vinden
1 Zet Excel in de ontwerpmodus door te klikken op de knop Ontwerpmodus in de werkbalk Werkset Besturingselementen.
2 Selecteer de knop. 3 Klik op de werkbalk op de knop Programmacode weergeven. Dubbel klikken op de knop mag ook.
De VBA-editor verschijnt automatisch. Het blad waar de knop aangemaakt is wordt geselecteerd en het standaard event wordt klaar gezet. U ziet dan ook de procedure die aangemaakt is: Private Sub cmdKnop_Click() End Sub
U herkent de Name property (cmdKnop), de naam van het event (Click) en de aanduiding voor een procedure die van het type Private is wat wil zeggen dat de procedure alleen bekend is binnen deze werkmap.
Als u afbeelding 11.8 bekijkt, ziet u dat het vak Procedure geopend is waar alle andere beschikbare events voor dit besturingselement te zien zijn. Er zijn er dertien. Voor een ander type besturingselement kunnen er andere events zijn, hoewel er bijvoorbeeld wel bepaalde gebeurtenissen door verschillende besturingselementen gedeeld worden. Zo zijn er verschillende besturingselementen waarbij er een Click-event optreedt als er met de muis op geklikt wordt. In tabel 11.5 zijn de events van de command button gerubriceerd.
274
DB_Macros_boek.indb 274
10/11/06 12:00:17
11 Besturingselementen en formulieren
Afbeelding 11.8 Events van de command button.
Tabel 11.5
Toepassing van events van de commandbutton
Event
Toepassing
BeforeDragOver
Treedt op net op het moment dat de muis over het object bewogen wordt. Dit event heeft een gecompliceerde structuur met verschillende parameters: Private Sub object_BeforeDragOver( ByVal Cancel As MSForms.ReturnBoolean, ByVal gegevens As DataObject, ByVal X As Single, ByVal Y As Single, ByVal DragState As fmDragState, ByVal Effect As MSForms.ReturnEffect, ByVal Shift As fmShiftState). U herkent onder meer de positiegegevens van de muiscursor in X en Y, en Shift waarmee bepaald wordt welke toets (Ctrl, Shift of Alt) er tijdens het slepen ingedrukt is. Daarmee krijgen we in Windows immers een ander effect. De waarde in Dragstate bepaalt de positie boven het object en gegevens bepaalt het object dat gesleept wordt.
BeforDropOrPaste
Als de gebruiker op het punt staat gegevens met de muis neer te zetten of te plakken in een object. Ook hier vinden we vele parameters.
Click
Het standaard event van de knop; er zijn geen parameters.
DblClick
Het doubleclick event treedt op als de gebruiker binnen een halve seconde tweemaal op de muisknop drukt terwijl de muiscursor zich boven de knop bevindt.
275
DB_Macros_boek.indb 275
10/11/06 12:00:18
MACRO’S EN VBA IN EXCEL de basis
Event
Toepassing
Error
Er treedt een fout op bij het besturingselement en er is geen programmacode beschikbaar om naar terug te keren. We zien dit in elke willekeurige applicatie wel eens waarbij meestal een foutmelding verschijnt in de trant van ‘Er treedt een fout op die niet door de applicatie verwerkt kan worden, neem contact op met de leverancier’. Als dit bij een van uw macro’s gebeurt, bent u de leverancier.
GotFocus
Het besturingselement heeft de focus gekregen. Deze gebeurtenis kunt u heel goed gebruiken bij bijvoorbeeld een tekstvak waar een gebruiker iets moet invullen. Een veel voorkomende waarde of een waarde die een relatie heeft met wat eerder ingevuld was, kunt u in dit event dan alvast invullen. Denk bijvoorbeeld aan het invullen van de plaatsnaam op basis van de eerder ingevulde postcode. Voor een knop kunt u in dit event bijvoorbeeld controleren of alle andere elementen wel de juiste informatie bevatten en of er niets vergeten is.
KeyDown
Dit event treedt op als een toets op het toetsenbord wordt ingedrukt terwijl het besturingselement de focus heeft.
KeyPress
In het KeyPress event krijgen we alle toetsen binnen die worden ingedrukt. U kunt het event bijvoorbeeld gebruiken om de invoer in een tekstvak te controleren op het niveau van een enkel teken.
KeyUp
Dit event treedt op als een ingedrukte toets op het toetsenbord wordt losgelaten terwijl het besturingselement de focus heeft.
LostFocus
Het besturingselement verliest de focus. Dit event is handig om de totale invoer in een tekstvak te controleren.
MouseDown
De muisknop wordt ingedrukt boven het besturingselement. Ook hier een gecompliceerde constructie: Private Sub Chart_MouseDown(ByVal Button As Long, _ ByVal Shift As Long, ByVal X As Long, ByVal Y As Long). X en Y bevatten de coördinaten van de muiscursor boven het besturingselement. Shift de tegelijkertijd ingedrukte toets op het toetsenbord en Button bevat de ingedrukte muisknop.
MouseMove
De muis wordt boven het besturingselement verplaatst. Dit event treedt ongeveer vijftien maal per seconde op en de programmacode hierin is dan ook waanzinnig lastig foutloos te maken…
MouseUp
De muisknop wordt weer losgelaten.
U hebt bij de bespreking van de events in de tabel gezien dat er ook gerefereerd werd aan andere besturingselementen. Besturingselementen delen dan ook vaak verschillende events.
11.2.4 Gebeurtenis programmeren Om succesvol een gebeurtenisprocedure te kunnen programmeren is het noodzakelijk dat u zich eerst afvraagt wat de gebruiker met de besturingselementen zal doen die u in een formulier of in het werkblad getekend hebt. Houd er rekening mee dat gebrui276
DB_Macros_boek.indb 276
10/11/06 12:00:18
11 Besturingselementen en formulieren
kers zeer onvoorspelbaar zijn en dat u dus met zoveel mogelijk ‘gebruikersdwalingen’ rekening moet houden. In de tweede plaats is het programmeren met behulp van events lastig omdat de volgorde waarin ze optreden door het besturingssysteem (Windows) bepaald wordt. Het is niet aan ú als programmeur om te bepalen in welke volgorde ze optreden. Het is zelfs zo dat als u in het ene event iets programmeert dat van invloed is op een ander besturingselement of object, er een keten van nieuwe events getriggerd kunnen worden die op hun beurt nieuwe events triggeren. Dit maakt het debuggen, het zoeken van fouten een ware uitdaging. Indien u voor een bepaald besturingselement wilt weten welke events in welke volgorde optreden, kunt u dat het beste met de volgende truc achterhalen. We nemen hierbij weer de knop als voorbeeld.
Oefening 11.6
Volgorde van gebeurtenissen
1 Dubbelklik op de knop. Het Click event wordt klaargezet. 2 Typ in dit event MsgBox
"klik".
3 Laat via het vak Procedure een aantal andere events klaarzetten die u wilt onderzoeken. 4 Typ hierin dezelfde coderegel waarbij u de tekst natuurlijk aanpast; zie afbeelding 11.9. 5 Ga naar Excel en voeg een extra knop toe zodat de focus verschoven kan worden. 6 Voer allerlei handelingen uit; u ziet nu de events langskomen. 7 Schakel events ook eens uit door er een quote-teken voor te zetten.
Oefening 11.7
Een event programmeren
Voor de knop in het formulier programmeren we een mogelijkheid om de werkmap af te sluiten en de inhoud al dan niet op te slaan. 1 Ga naar de VBA-editor. 2 Selecteer in het Projectvenster het blad waar de knop in getekend is. 3 Neem de volgende macro over in het Click event van de knop: C
Private Sub cmdKnop_Click() Dim intR As Integer
277
DB_Macros_boek.indb 277
10/11/06 12:00:18
MACRO’S EN VBA IN EXCEL de basis
Afbeelding 11.9 Events op een rij.
Dim strN As String strN = ThisWorkbook.Name intR = MsgBox("Wilt u deze werkmap opslaan?", vbYesNo _ Or vbQuestion) If intR = vbOK Then Workbooks(strN).Close savechanges:=True Else Workbooks(strN).Close savechanges:=False End If End Sub
4 Sla eerst zelf de macro op. 5 Test de macro.
278
DB_Macros_boek.indb 278
10/11/06 12:00:19
11 Besturingselementen en formulieren
Afbeelding 11.10 Meldingen van optredende events.
U ziet hier hoe een reactie van de gebruiker aan de hand van de knop die in een messagebox wordt ingedrukt, opgevraagd en verwerkt kan worden. Tabel 11.6 geeft een overzicht van alle knoppen en pictogrammen die in een messagebox toegepast kunnen worden. U kunt met behulp van de Or-functie elke knop, pictogram, focusaanduidingen of systeeminstelling toevoegen. Met de volgende regel heeft de box naast de bood-
Afbeelding 11.11 Een compleet uitgevoerde messagebox.
279
DB_Macros_boek.indb 279
10/11/06 12:00:20
MACRO’S EN VBA IN EXCEL de basis
schap (de prompt) ook een Ja, Nee en een Annuleren-knop, de laatste heeft de focus en kan dus met de spatiebalk ’ingedrukt‘ worden. De knop die de focus heeft, is voorzien van een stippellijntje; zie afbeelding 11.11 Tevens is er een vraagtekenpictogram. Als u de knop test, zult u merken dat u in geen enkele andere applicatie kunt werken, totdat een knop van de box is ingedrukt. Pas dan zal deze verdwijnen. Dit is een effect van de toevoeging van de constante vbSystemModal. MsgBox "Mededeling aan de gebruiker", _ vbYesNoCancel Or vbDefaultButton3 _ Or vbQuestion Or vbSystemModal
Tabel 11.6
Alle knoppen, pictogrammen en instellingen voor de messagebox
Constante
Betekenis
Knoppen vbOKOnly
OK-knop.
vbOKCancel
De knoppen OK en Annuleren.
vbAbortRetryIgnore
Afbreken, Opnieuw en Negeren.
vbYesNoCancel
De knoppen Ja, Nee en Annuleren.
vbYesNo
Ja en Nee.
vbRetryCancel
De knoppen Opnieuw en Annuleren.
Pictogrammen vbCritical
- Ernstige boodschappen.
vbQuestion - Aanduiding voor een vraag. vbExclamation – Waarschuwing. vbInformation – Informatie. Knopfocus vbDefaultButton1
De eerste knop heeft de focus.
vbDefaultButton2
De tweede knop heeft de focus.
vbDefaultButton3
De derde knop heeft de focus.
vbDefaultButton4
De vierde knop heeft de focus.
280
DB_Macros_boek.indb 280
10/11/06 12:00:21
11 Besturingselementen en formulieren
Constante
Betekenis
Systeeminstellingen vbApplicationModal
De gebruiker moet op het berichtvenster reageren voordat er in Excel verder gewerkt kan worden.
vbSystemModal
Alle toepassingen worden onderbroken totdat de gebruiker op het berichtvenster heeft gereageerd. Dit geldt dus ook voor andere programma’s dan Excel!
vbMsgBoxHelpButton
Voegt de knop Help aan het berichtvenster toe.
VbMsgBoxSetForeground
Het berichtvenster wordt op de voorgrond getoond.
vbMsgBoxRight
Tekst wordt rechts uitgelijnd.
vbMsgBoxRtlReading
Geeft op dat tekst op Hebreeuwse en Arabische systemen van rechts naar links moet worden weergegeven.
Retourwaarden Constante
Waarde
Beschrijving
vbOK
1
OK is ingedrukt.
vbCancel
2
Annuleren is ingedrukt.
vbAbort
3
Afbreken is ingedrukt.
vbRetry
4
Opnieuw is ingedrukt.
vbIgnore
5
Negeren is ingedrukt.
vbYes
6
Ja is ingedrukt.
vbNo
7
Nee is ingedrukt
11.2.5 Gebeurtenissen van andere objecten Niet alleen besturingselementen kennen events, ook andere objecten kunnen events hebben. In dit voorbeeld gebruiken we een event van het werkblad. Het werkblad kent negen events. We gebruiker er een: het Change event. Dit treedt op telkens wanneer er iets aangepast wordt in het werkblad. U kunt deze gebeurtenis benutten om een controle uit te voeren op datgene wat ingevoerd wordt. Om nu te voorkomen dat de programmacode telkens maar uitgevoerd wordt, wordt in een parameter het bereik meegegeven dat gewijzigd werd. Op dat bereik kunt u nu een test uitvoeren om te zien of er een wijziging is geweest waarvoor de programmacode geldig is.
Oefening 11.8
Events van andere objecten
1 Voeg een leeg werkblad toe.
281
DB_Macros_boek.indb 281
10/11/06 12:00:22
MACRO’S EN VBA IN EXCEL de basis
2 Noem het werkblad op de werkbladtab Gebeurtenissen. 3 Zet in cel B3 de tekst Postcode. 4 Geef cel B4 de naam Postcode. 5 Ga naar de VBA-editor. 6 Zoek in de Projectverkenner het blad Gebeurtenissen op en dubbelklik erop. 7 Selecteer in het vak Object in plaats van (Algemeen) het blad, Worksheet; zie afbeelding 11.12. 8 Selecteer in het vak Procedures het event Change; zie afbeelding 11.13.
Afbeelding 11.12 Selecteer het werkblad.
Afbeelding 11.13 En de juiste eventprocedure.
9 De procedure wordt klaargezet en u ziet de parameter Target in het argument van de procedure gedefinieerd. Neem de volgende programmacode over: C
'Declaraties Dim intT As Integer Dim blnFout As Boolean blnFout = False 'Alleen als het een cel betreft If Target.Rows.Count = 1 And Target.Columns.Count = 1 Then 'Ga na of het de cel is met de postcode If Target = Range("Postcode") Then 'Zo ja, test de postcode If Len(Target.Value) <> 7 Then blnFout = True Else 'Ga na of de eerste vier cijfers zijn
282
DB_Macros_boek.indb 282
10/11/06 12:00:22
11 Besturingselementen en formulieren
For intT = 1 To 4 If Mid(Target.Value, intT, 1) < 0 _ Or Mid(Target.Value, intT, 1) > 9 Then blnFout = True End If Next 'Dan een spatie If Mid(Target.Value, 5, 1) <> " " Then blnFout = True End If 'Rechter twee moeten letters zijn For intT = 6 To 7 If Mid(Target.Value, intT, 1) < A _ And Mid(Target.Value, intT, 1) > Z Then blnFout = True End If Next End If End If If blnFout Then MsgBox "Een postcode bestaat uit 4 cijfers, " _ & "een spatie en twee letters!", _ vbCritical Or vbOKOnly Target.Font.Color = vbRed Else 'Alleen postcodecel mag groen worden If Target = Range("Postcode") Then Target.Font.Color = vbGreen End If End If End If End Sub
De verklarende tekst in de code moet wel genoeg zijn om de werking te begrijpen. U ziet dat de parameter Target eigenlijk een Range object mee krijgt vanuit het werkblad en dat dit object dezelfde methoden en eigenschappen heeft als het normale object Range. Met een eerste If clausule wordt gecontroleerd of het om slechts een cel gaat en met de tweede If-clause wordt er gekeken of het range object in Target gelijk is aan de cel met de naam Postcode. Alleen dan wordt de rest van de procedure uitgevoerd. 10 Ga terug naar het werkblad en voer een correcte postcode in. De tekst in de cel wordt onmiddellijk in groen weergegeven als de invoer bevestigd wordt met Enter. 11 Voer in een andere cel iets in. Er gebeurt niets.
283
DB_Macros_boek.indb 283
10/11/06 12:00:23
MACRO’S EN VBA IN EXCEL de basis
12 Voer in B4 een foutieve postcode in. De procedure reageert met een messagebox; zie afbeelding 11.14. 13 Klik de messagebox weg en merk op dat de tekst in de cel in rood wordt weergegeven.
OPMERKING Wees erop verdacht dat als de knop Ontwerpmodus op de werkbalk is ingedrukt, de events van het werkblad onderdrukt worden en er niets zal gebeuren!
Afbeelding 11.14 Het event is getriggerd en de procedure is in werking.
11.2.6 Combobox Een laatste voorbeeld van events van andere objecten gebruiken we om een keuzelijst met invoervak (combobox) van inhoud te voorzien. U zou ook een gewone keuzelijst (listbox) op dezelfde manier kunnen gebruiken, maar het aardige van een combobox is dat de gebruiker de lijst kan uitbreiden. De uitgebreide lijst blijft echter alleen maar bestaan zolang de werkmap geopend is. Bij het afsluiten van de werkmap of eventueel zelfs bij het activeren van een ander werkblad in de map, moet de inhoud van de combobox ergens worden vastgelegd. Dat kunt u overal doen: in een bestand op de vaste schijf, in een andere werkmap, een ander werkblad of om het simpel te houden - zoals we hier zullen doen - in hetzelfde werkblad.
284
DB_Macros_boek.indb 284
10/11/06 12:00:23
11 Besturingselementen en formulieren
Afbeelding 11.15 Uitbreiding in het werkblad.
Oefening 11.9
Events van andere objecten
1 Breidt het werkblad uit met hetgeen u in afbeelding 11.15 ziet. 2 I3 heeft de naam Plaatsnamen. 3 De (Name) property van de combobox is cmdPlaatsnamen. Stel deze eigenschap in door de combobox te selecteren en in het snelmenu voor Eigenschappen te kiezen. 4 Ga naar de VBA-editor en selecteer in het Projectvenster het werkblad waar de combobox in getekend is. 5 Kies in het venster Object het werkblad, Worksheet. 6 Kies in het vak Procedure het Activate event en neem de volgende macro over: C
Private Sub Worksheet_Activate() 'Declaraties Dim intAR As Integer 'Aantal rijen
285
DB_Macros_boek.indb 285
10/11/06 12:00:24
MACRO’S EN VBA IN EXCEL de basis
'Zoek het aantal rijen onder plaatsnamen Range("Plaatsnamen").Select intAR = ActiveCell.CurrentRegion.Rows.Count 'Maak de combobox leeg cmbPlaatsnamen.Clear For intT = 1 To intAR - 1 cmbPlaatsnamen.AddItem Range("Plaatsnamen").Offset(intT, 0).Value Next cmbPlaatsnamen.Text = "Kies de plaats" End Sub
De cel met de naam Plaatsnamen wordt in de macro geselecteerd. Vervolgens wordt het aantal rijen in het huidige gebied opgevraagd. In een For… Next-lus wordt elke plaatsnaam toegevoegd aan de combobox met de methode AddItem. Tot slot wordt een tekst met een aanwijzing voor de gebruiker toegevoegd aan het tekstvak in de box. Het toevoegen van items aan een listbox werkt net zo. 7 Selecteer een ander werkblad en selecteer vervolgens dit werkblad weer. Hierdoor wordt de lijst gevuld met de plaatsnamen die in het werkblad staan. 8 Selecteer in het vak Object in de VBA-editor cmbPlaatsnamen. 9 Selecteer in vak Procedures het event Keydown. Neem daarin de volgende procedure over: C
Private Sub cmbPlaatsnamen_KeyDown(ByVal KeyCode _ As MSForms.ReturnInteger, ByVal Shift As Integer) If KeyCode = vbKeyReturn Then cmbPlaatsnamen.AddItem cmbPlaatsnamen.Text Range("Plaatsnamen").Select Selection.End(xlDown).Select ActiveCell.Offset(1, 0).Select ActiveCell.Value = cmbPlaatsnamen.Text cmbPlaatsnamen.Text = "" End If End Sub
VBA heeft een groot aantal Keycode constants. Deze constanten waarvan u er hier één ziet, kunt u in dit event gebruiken om toetsen te detecteren zoals Backspace, Enter, functietoetsen of bijvoorbeeld Shift, Alt, etcetera. Als u iets met de normale letter en cijfertoetsen van het toetsenbord wilt doen, kunt u beter het Keypress-event daarvoor gebruiken. Wat willen we hier? We willen dat als de gebruiker in het tekstvak van de combobox een naam typt en op de Enter-toets drukt, deze wordt toegevoegd aan de lijst in de combobox en óók aan de lijst in het werkblad. De combobox heeft als eigenschap dat de lijst uitgebreid kan worden, maar dan moet die lijst wel ergens vastgelegd kunnen worden.
286
DB_Macros_boek.indb 286
10/11/06 12:00:25
11 Besturingselementen en formulieren
NUMMER ÉÉN IS SOMS NUMMER NUL Het is in VBA soms verwarrend welk nummer het eerste item eigenlijk heeft. Vanuit onze menselijke optiek is het eerste item altijd nummer één. Bij lijsten is dat niet zo. Het eerste item heeft in dat geval volgnummer nul. ComboBox.Item(0) is dus het eerste nummer uit de lijst. Wanneer we echter vragen hoeveel items er in een lijst staan met de Count methode, dan krijgen we bijvoorbeeld als antwoord tien. Dat betekent echter dat het laatste nummer volgnummer negen heeft en niet tien omdat er immers bij nul wordt begonnen met tellen. Met de Offset-methode in VBA is net zoiets aan de hand. OffSet(0, 0) is de huidige cel. Om die reden begint de lus in de voorgaande procedure bij 1 (omdat de tekst Plaatsnamen op de nulpositie staat en dat willen we niet in de combobox hebben. De lus loopt derhalve ook tot AR – 1 in de CurrentRegion. Als u programmeert in VBA is het mogelijk bovenaan in een module nog voor de eerste procedure Option Base 1 op te nemen. Dat betekent dat VBA standaard zal gaan tellen vanaf een en niet vanaf nul. Dit is vooral van belang bij het werken met arrays. Dit zijn tabellen met gegevens in het geheugen van de pc, waarbij standaard ook het eerste element in zo’n tabel volgnummer nul krijgt, maar met Option Base 1 een ’menselijke‘ één. Helaas heeft dat geen enkele invloed op lijsten en andere elementen. Option Base of niet; daarbinnen wordt gewoon geteld vanaf nul. Daarom laten we het meestal maar achterwege omdat het de verwarring vaak alleen maar groter maakt en daardoor lastig te debuggen is. De beste tip die we u kunnen geven, is gewoon een macro stap voor stap uitvoeren met slechts enkele gegevens in lijsten, in het werkblad en in comboboxes en dergelijke en goed controleren welke waarde telvariabelen moeten hebben.
10 Vervolgens moet een door de gebruiker geselecteerde plaatsnaam ergens in het werkblad geplaatst worden. Hiervoor gebruiken we het Click-event van de combobox. Zoek dit op en neem de volgende code op: Private Sub cmbPlaatsnamen_Click() Range("D5").Value = cmbPlaatsnamen.Text End Sub
Dit ziet er erg eenvoudig uit en dat ís het ook. 11 Tot slot moeten we er steeds rekening mee houden dat de gebruiker namen heeft toegevoegd en dat deze namen vastgelegd moeten worden. We léggen ze al vast in het werkblad, maar als de gebruiker de werkmap niet opslaat, gaan de toegevoegde gegevens alsnog verloren. Wij slaan de map dus steeds op en we zullen daarvoor het Deactivate event van het Worksheet gebruiken: Private Sub Worksheet_Deactivate() Workbooks(ThisWorkbook.Name).Save End Sub
287
DB_Macros_boek.indb 287
10/11/06 12:00:25
MACRO’S EN VBA IN EXCEL de basis
Dus telkens wanneer een ander werkblad in de map geselecteerd wordt, wordt de hele werkmap automatisch opgeslagen. Als u dit onwenselijk vindt, kunt u de gebruiker natuurlijk om toestemming vragen. Wijs dan wel netjes op de consequenties als hij of zij ervoor kiezen om de map niet op te slaan.
Opdracht 11.1
Probleem oplossen
Er zit nog een klein probleempje in deze macro’s. Selecteert u het werkblad waar de combobox in staat maar eens en sla vervolgens de werkmap op via het menu Bestand. Sluit de werkmap en open deze opnieuw. De combobox blijft nu leeg en wordt pas gevuld als u eerst een ander werkblad opent en vervolgens weer het werkblad met de combobox selecteert. Los dit op! Er zijn enkele oplossingen waarvan u er een aan het eind van dit hoofdstuk aantreft.
Opdracht 11.2
Lijst sorteren
Het zou wel fijn zijn als de lijst met plaatsnamen gesorteerd werd, want dan wordt deze ook gesorteerd in de combobox weergegeven. Misschien hebt u een idee hoe dat te doen?
11.3 User forms User forms zijn formulieren die door de gebruiker ontworpen worden. U zou hiervoor ook de term dialoogvensters kunnen gebruiken, want een formulier is niets anders dan een dialoogvenster waar u net zoveel besturingselementen op kwijt kunt als u maar wilt. Er is natuurlijk wel een praktische grens aan het aantal, vanwege de beschikbare ruimte op het beeldscherm. Een userform heeft enkele belangrijke methoden en eigenschappen. We zetten ze op een rijtje in tabel 11.7. Tabel 11.7
Eigenschappen en methoden van een userform
Eigenschap
Omschrijving
(Name)
De naam waaronder het userform in de programmacode kan worden herkend en aangesproken.
Caption
De tekst in de titelbalk van het formulier.
Enabled
De waarde True houdt in dat het formulier actief is en gebruikt kan worden, bij False is dat niet het geval. Een handige manier om een formulier even buiten werking te stellen.
Height
De hoogte van het formulier.
Left
De afstand tot de bovenzijde van het scherm.
288
DB_Macros_11.indd 288
10/11/06 12:15:06
11 Besturingselementen en formulieren
Eigenschap
Omschrijving
ShowModal
Deze eigenschap kan alleen ingesteld worden zolang het formulier niet geladen is, daarna is het een alleen-lezen eigenschap. Een modaal formulier (True) moet eerst ingevuld en gesloten worden voordat de gebruiker verder kan. Voor een non-modaal formulier (False) geldt dat niet.
StartUpPosition
Deze eigenschap bepaalt waar het formulier op het scherm verschijnt. Met Manual bepaalt u zelf met behulp van de eigenschappen Top en Left de positie. CenterOwner betekent gecentreerd ten opzichte van de eigenaar (in dit geval de werkmap waartoe het formulier behoort), CenterScreen is midden op het beeldscherm en WindowsDefault is meestal in de linker bovenhoek van het scherm.
Top
Zie Left.
Width
De breedte van het formulier.
Methode
Omschrijving
Load
Het formulier wordt alleen in het geheugen geladen, maar wordt niet zichtbaar.
Hide
Het formulier wordt verborgen, maar blijft wel in het geheugen.
PrintForm
Een handige methode om de totale inhoud van een formulier af te drukken.
Show
Met deze methode wordt het formulier in het geheugen geladen als het nog niet is geladen. Daarna wordt het op het scherm getoond.
Unload
Het formulier wordt uit het geheugen verwijderd.
Oefening 11.10 User form 1 Zorg voor een nieuw werkblad met daarin een eenvoudige database bestaande uit een kolom voor namen en een kolom voor telefoonnummers. 2 Voeg een knop Naam toevoegen toe. 3 Ga naar de VBA-editor en kies in het menu Invoegen, User form. 4 Er wordt een leeg formulier toegevoegd en een werkbalk Werkset; zie afbeelding 11.17. Deze werkset is vergelijkbaar met die u bij het tekenen van besturingselementen in een Excel-werkblad hebt gezien. 5 Teken twee labels, twee tekstvakken en twee knoppen; zie afbeelding 11.17. 6 Pas de captions van de beide labels aan, in afbeelding 11.18 ziet u hoe dat voor het tweede label wordt uitgevoerd. 7 De overige gegevens ziet u in de volgende tabel, terwijl afbeelding 11.19 het aangepaste formulier toont op het moment dat net in de eigenschappenlijst de Caption van het formulier wordt ingevuld. Ook een formulier heeft een opschrift; dat is namelijk de tekst in de titelbalk. 289
DB_Macros_11.indd 289
10/11/06 12:17:01
MACRO’S EN VBA IN EXCEL de basis
Afbeelding 11.16 Een userform is toegevoegd.
Tabel 11.8
De eigenschappen van het formulier
Besturingselement
Eigenschap
Instelling
Label1
(Name)
Label1
Caption
Naam:
(Name)
Label2
Caption
Telefoonnummer:
Textbox1
(Name)
txtNaam
Txtbox2
(Name)
txtTelNum
Commandbutton1
(Name)
cmdOK
Caption
OK
(Name)
cmdAnnuleren
Caption
Annuleren
(Name)
frmNT
Caption
Invoer naam en telefoonnummer
Label2
Commandbutton2
UserForm1
290
DB_Macros_boek.indb 290
10/11/06 12:00:27
11 Besturingselementen en formulieren
Afbeelding 11.17 De besturingselementen worden getekend.
Afbeelding 11.18 Een userform is toegevoegd.
291
DB_Macros_boek.indb 291
10/11/06 12:00:28
MACRO’S EN VBA IN EXCEL de basis
De niet-genoemde properties houden hun standaard waarde (default).
Afbeelding 11.19 De Caption (=titelbalk) van het formulier wordt ingevuld.
11.3.1 Het formulier tonen Er zijn verschillende manier om met het formulier te werken: U kunt het eerst in het geheugen laden met Load frmFormName. Dit heeft als voordeel dat ingewikkelde formulieren of formulieren met netwerkkoppelingen op de achtergrond geladen kunnen worden zonder dat gebruikers hier hinder van ondervinden. Op het moment dat we het formulier nodig hebben, gebruiken we de Show-methode. Het is ook mogelijk het formulier direct op het scherm te zetten met de Show-methode. Als het formulier op dat moment nog niet is geladen, zal het alsnog automatisch in het geheugen worden geladen. Met een eenvoudig formulier zoals we hier hebben behandeld is dat de aanbevolen methode. Als het formulier even niet nodig is, kunt u het verbergen met de Hide-methode. Het blijft dan wél in het geheugen geladen. Met Unload frmFormName kunt u het hele formulier uit het geheugen verwijderen. Als het vaak nodig is en een ingewikkeld formulier betreft, is dit niet aan te raden. Een verborgen formulier is wel toegankelijk vanuit de programmacode, evenals alle besturingselementen daarop. U kunt dus eerst al van alles invullen en klaarzetten, voordat u het formulier toont. Het is mogelijk in een van de ’opstartevents‘ van werkmap of blad het formulier te 292
DB_Macros_boek.indb 292
10/11/06 12:00:29
11 Besturingselementen en formulieren
laden, maar u kunt het ook gewoon aan een macro koppelen die met een toets of een knop of menuopdracht wordt gestart.
11.3.2 Programmacode voor het formulier Als u in de Projectverkenner kijkt, dan ziet u dat het formulier onder een apart kopje Formulieren is toegevoegd aan de werkmap. Dubbelklikken op de vermelding in de Projectverkenner opent slechts het formulier zelf en niet het bijbehorende codevenster. Daarvoor zijn twee manieren: Kies in het snelmenu Programmacode weergeven, zoals in afbeelding 11.20 te zien is; Of dubbelklik ergens in het formulier. Dubbelklikt u op een besturingselement in het formulier, dan ziet u ook de code en wordt onmiddellijk het standaard event van dat besturingselement afgehandeld.
Afbeelding 11.20 Programmacode vinden bij het formulier.
11.3.3 Programmacode aan het formulier toevoegen U weet inmiddels hoe u de diverse objecten en de bijbehorende events kunt vinden. We behandelen nog even alle programmacode bij de beide knoppen in dit formulier.
293
DB_Macros_boek.indb 293
10/11/06 12:00:30
MACRO’S EN VBA IN EXCEL de basis
C
Private Sub cmdAnnuleren_Click() If Len(txtNaam.Text) > 0 Or Len(txtTelNum.Text) > 0 Then If MsgBox("Er staan nog gegevens in het formulier" _ & vbCrLf & "Wilt u deze bewaren?", _ vbYesNo Or vbQuestion) = vbYes Then Exit Sub End If End If Unload frmNT End Sub
Als er op de Annuleren-knop wordt geklikt, dan zal eerst worden gecontroleerd of er nog iets in een van beide tekstvakken staat. Is dat het geval, dan wordt de gebruiker de vraag voorgeschoteld of de inhoud van het formulier moet worden bewaard. Klikt de gebruiker op de Ja-knop, dan wordt de procedure verlaten. Bij een Nee moet met Unload frmNT het formulier uit het geheugen worden verwijderd. C
Private Sub cmdOK_Click() 'Declaraties Dim blnFout As Boolean If Len(txtNaam.Text) = 0 Or Len(txtTelNum.Text) = 0 Then blnFout = True End If 'Breng gegevens over naar werkblad If Not (blnFout) Then Workbooks("v-11.xls").Worksheets("NaamTelNum").Select Range("A65536").End(xlUp).Select 'Ga een rij omlaag ActiveCell.Offset(1, 0).Select 'Vul de naam in ActiveCell.Value = txtNaam.Text 'Ga een kolom naar rechts ActiveCell.Offset(0, 1).Select 'Vul het telefoonnummer in ActiveCell.Value = txtTelNum.Text Range("NaamTelNum").Select txtNaam.Text = "" txtTelNum.Text = "" txtNaam.SetFocus End If End Sub
Wordt op de OK-knop geklikt, dan wordt ook weer gecontroleerd of er wel iets in de tekstvakken staat. Als deze leeg zouden zijn, dan zou de integriteit van onze ’database‘ in het gevaar komen, omdat er dan een leeg veld zou worden toegevoegd. U kunt natuurlijk veel uitgebreidere controles inbouwen! Staat er iets in een van beide tekst294
DB_Macros_boek.indb 294
10/11/06 12:00:30
11 Besturingselementen en formulieren
vakken, dan wordt de informatie aan de lijst toegevoegd op dezelfde manier zoals in hoofdstuk 9 al uitgebreid is doorgenomen. U ziet dat aan het eind van de procedure de beide tekstvakken leeg gemaakt worden en de cursor weer in het naamvak geplaatst wordt met txtNaam.SetFocus. C
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer) If CloseMode = vbFormControlMenu Then MsgBox "U kunt dit formulier alleen sluiten met de Annuleren-knop", _ vbOKOnly Or vbInformation Cancel = True End If End Sub
Elk formulier heeft net zoals alle andere Windows-vensters een pictogram Sluiten in de rechter bovenhoek. Als u niet wilt dat de gebruiker hiermee het venster kan sluiten, kunt u dat verhinderen door de Cancel-parameter op True te zetten. Hiermee geeft u het besturingssysteem een seintje dat het formulier niet opgeruimd mag worden.
Opdracht 11.3 1 Waar zou u een controle inbouwen op een correcte invoer van een tekstvak? U kunt bij het telefoonnummer denken aan een beperking van de invoer tot cijfers en een liggend streepje. 2 Bouw zo’n controle in.
11.4 Oplossing opdracht 11.1 Hoewel u in het event Workbook_Open natuurlijk de combobox net zo kunt vullen als dat in het event Worksheet_Activate gebeurde waarbij wel de naam van het werkblad toegevoegd moet worden, kan het ook op een elegante manier zonder twee keer hetzelfde te moeten programmeren. We weten dat als een procedure benoemd wordt met het woord Private, dat die procedure alleen herkenbaar is binnen het werkblad of de module waar ze in is opgeslagen. Als u in het blad Gebeurtenissen Private Sub Worksheet_Activate() wijzigt in Public Sub Worksheet_Activate(), is de procedure ineens in alle werkbladen en -mappen herkenbaar. Het Workbook_Open event wordt dan: C
Private Sub Workbook_Open() With Worksheets("Gebeurtenissen") .Select .Worksheet_Activate End With End Sub
295
DB_Macros_boek.indb 295
10/11/06 12:00:31