Vi quizzer
I forrige artikel kiggede vi på sammenhængen imellem VBA-editoren og Office-programmerne. I denne artikel går vi videre med et lidt mere kompliceret eksempel, og derudover stifter vi bekendtskab med VBA-editorens debugger, og viser, hvordan man nemt kan orientere sig i de uundværlige hjælpefiler og benytte objekt-browseren til at aflure programmernes metoder og egenskaber.
En lille quiz
I sidste uges artikel så vi, hvordan man let kan indsætte brugerfladeelementer som knapper, combobokse med videre. I Visual Basic-verden kaldes det kontroller.
Åbn Word og derefter VBA-editoren via menuen Funktioner > Makro > Visual Basic Editor.
Åbn paletten Kontrolpaneler ved at klikke på knappen Design Mode i VBA-editoren, som vi gjorde i forrige artikel. Nu kommer værktøjspaletten Kontrolelementer til syne. Indsæt to gange to radioknapper, og derefter en almindelig knap. Det gøres ved at placere tekstmarkøren (I-beam) på sædvanlig Word-vis og derefter trykke på kontrolelementet i paletten.
Skriv et par spørgsmål til quizzen, og sæt det hele pænt op. Det kan for eksempel se således ud:
Dine knapper bærer formodentlig navne i stil med OptionButton1 og så videre, men det kan du nemt ændre, ved at aktivere et kontrolelement med et enkelt klik. Hop over i VBA-editoren og vælg menuen View > Properties Window. Her kan du sætte egenskaberne på knapperne. Navnet på knappen er ikke den øverste egenskab på listen, (Name), men egenskaben Caption som befinder sig lidt længere nede på listen. Og så skal der programmeres.
Hop over i VBA-editoren.
Ved at hive i listen øverst til venstre, kan man se alle de kontrolelementer, vi har indsat i Word-dokumentet. Listen til højre viser hvilke begivenheder - events - som kontrolelementet kan reagere på. Her skal vi kun benytte Click-begivenheden, der udløses, når man klikker på knappen.
Radioknapper
Ideen bag vores quiz er ganske simpel. Når brugeren klikker på et rigtigt svar, lægger vi et point i en variabel. Når brugeren klikker på et forkert svar, lægger vi nul i samme variabel. Når brugeren klikker på knappen "Find min score", lægger vi pointene sammen og viser resultatet i en dialogboks.
Da vi har to spørgsmål i vores quiz, skal vi benytte to globale variable. Hiv i den venstre liste i kode-vinduet og stil den på General. Nu definerer vi to globale variable ved at skrive følgende på markørens plads:
Public Score1, Score2
Når der klikkes på en radioknap, der korresponderer med et svar, skal Score-variablerne sættes til 0 eller 1 afhængigt af, om det er et rigtigt eller forkert svar. Det gøres simpelthen blot ved at skrive
Score1 = 1
(eller 0) i radioknappens Click-eventhandler. For den første knap ser det sådan ud:
Private Sub OptionButton1_Click()
Score1 = 1
End Sub
En radioknap kaldes for en Option Button. Når brugeren klikker på "Find min score"-knappen, skal vi regne resultatet sammen. I forrige artikel så vi, hvordan man skaber dialogbokse i VBA, så det hele ser nu sådan ud:
Private Sub CommandButton1_Click()
Sum = Score1 + Score2
MsgBox "Du scorede " & Sum & _
"point ud af 2 mulige."
End Sub
Den afsluttende understreg (_) på tredie sidste linie fortæller Visual Basic-fortolkeren, at sætningen forsætter på den efterfølgende linie.
Nu er vi parat til at teste. Slå designtilstand fra ved at klikke på knappen med den turkis vinkel i paletten med kontrolelementer. Det første, vi iagttager, er, at når man klikker på en af radioknapperne til spørgsmål 2, så bliver radioknapperne i spørgsmål 1 slået fra. Det er fordi alle radioknapperne, vi har indsat, som udgangspunkt tilhører samme gruppe.
Radioknapper er grupperede, og brugeren kan kun vælge en radioknap i hver gruppe. Vi skal altså splitte vores radioknapper op i to grupper. Det gøres ved at slå design tilstand til, og klikke på den første radioknap i spørgsmål 1. Hop over i VBA-editoren, og vælg menuen View > Properties Window. Find punktet GroupName og skriv "Gruppe1" i højre kolonne. Det samme gentages med knap 2 i spørgsmål 1. Proceduren gentages nu med knapperne til spørgsmål 2, men her skal GroupName være "Gruppe2".
Nu skulle radioknapperne gerne opføre sig ordentligt. Vi tester igen, og minsandten - det virker.
Hjælpefilerne
Men vi vil godt give quiz-brugerne en chance til, så derfor nulstiller vi alle radioknapperne efter at brugeren har fået sin score at vide. Men hvordan gør man nu det? Det kan VBA-editoren hjælpe os med. Hop over i VBA og vælg menuen View > Object Browser. Her kan vi gennemløbe alle VBA's objekter, og se hvilke metoder og egenskaber, de tilbyder. Objekterne er grupperet i de grupper, som man kan finde i drop-down listen øverst til venstrei objektbrowseren. Brugerfladeelementer kaldes for Forms i Visual Basic-verdenen (og mange andre steder) og i listen finder vi MSForms.
Ved at rulle ned i venstre skakt finder vi OptionButton, og når man klikker på den, får man en liste af de metoder og egenskaber, som objektet har. Nederst i højre skakt har vi egenskaben Value, og mon ikke det skulle være det, vi er på udkig efter. Højreklik på Value og vælg Help i menuen, der dukker frem. Her skal det lige indskydes, at hjælpefilerne til VBA ikke er installeret i en standardinstallation af Office, så find Office-cd'en frem, hvis problemet melder sig.
Hjælpefilerne er meget informative, og her får vi oplyst, at ved at sætte Value til henholdsvis True og False kan knappen slås til og fra.
Derfor indsætter vi nu følgende linier i event-handleren for Command_button-knappen, efter linien hvor vi viser dialogboksen:
OptionButton1.Value = False
OptionButton2.Value = False
OptionButton3.Value = False
OptionButton4.Value = False
Det hele ser nu sådan ud:
Private Sub CommandButton1_Click()
Sum = Score1 + Score2
MsgBox "Du scorede " & Sum & _
" point ud af 2 mulige."
OptionButton1.Value = False
OptionButton2.Value = False
OptionButton3.Value = False
OptionButton4.Value = False
End Sub
Vi tester igen, og det virker - næsten. Knapperne bliver i hvert fald nulstillet, efter at dialogboksen har været fremme. Men nu har vi et nyt problem: Når brugeren klikker på "Find min score" kommer det sidste resultat frem - selv om brugeren slet ikke har svaret på spørgsmål i quizzen.
Debuggeren
Nu kunne man jo godt ved hjælp af rationel analyse og sund fornuft tænke sig frem til problemets årsag. Men så får vi ikke demonstreret VBA's debugger, og det ville jo være kedeligt. En debugger er som bekendt et hjælpeprogram, der kan anskueliggøre de tilstande, som programmet gennemløber under udførelsen, og det er et uundværligt redskab, når man programmerer.
Den simpleste måde at benytte en debugger på, er at vælge nogle specifikke værdier, som man vil holde øje med undervejs. Derefter indsættes et eller flere såkaldte breakpoints, som får programafviklingen til at stoppe midlertidigt, og på den vis kan man holde øje med, hvad der sker under afviklingen. Her vil vi gerne holde øje med vores to variable Score1 og Score2.
Gå ind i kodevinduet i VBA, vælg (General) fra venstre drop-down liste og opmærk Score1. Vælg menuen Debug > Add Watch. Klik OK. Nu vises Watch-vinduet, hvor vi kan tjekke værdien af Score1 undervejs. Gør det samme med Score2.
Nu skal vi indsætte et breakpoint. Det gør vi på linien umiddelbart før, vi viser dialogboksen. Det gøres ved at højreklikke på linien og vælge menuen Toggle > Breakpoint. Nu bliver linien fremhævet med brunt.
Vend nu tilbage til dokumentet i Word. Skaler vinduet, så du både kan se Word-dokumentet og VBA-editoren samtidigt.
Klik på nogle svar i quizzen, og klik så på "Find min score"-knappen.
Nu stopper afviklingen på den brune linie og nederst i Watch-vinduet, kan vi nu se, hvilke værdier Score1 og Score2 har lige nu. Derefter kan man forsætte programmet ved at vælge menuen Run > Continue.
Ved at køre programmet en gang, hvor vi klikker på radioknapperne, og en gang hvor vi ikke klikker på radioknapperne, kan vi se, hvad der er galt: Score1 og Score2 beholder deres værdier fra forrige gennemløb.
Problemet løses ved at indsætte to linier i Command_Click:
Score1 = 0
Score2 = 0
Så nu ser det hele sådan ud:
Private Sub CommandButton1_Click()
Sum = Score1 + Score2
MsgBox "Du scorede " & Sum & _
" point ud af 2 mulige."
OptionButton1.Value = False
OptionButton2.Value = False
OptionButton3.Value = False
OptionButton4.Value = False
Score1 = 0
Score2 = 0
End Sub
Til sidst fjerner vi vores breakpoint ved at vælge menuen Debug > Clear all breakpoints.
I den næste artikel i vores lille serie om VBA, ser vi på, hvorledes man blander tal og tekst fra Word og Excel.