Informaticasite van het Sondervick College te Veldhoven                 © L.J.M van Haperen (bron : R.J. van der Beek)
 

Hoofdstuk 7. VBA-programma's in Excel

  7.1 Een macro bekijken

We gaan in dit hoofdstuk verder met het werkblad van de schaatswedstrijd van hoofdstuk 6.

In hoofdstuk 5 hebben we besproken hoe je een macro kunt maken voor het sorteren.
Je kunt ook bekijken hoe Excel de macro vastlegt.
Een macro wordt vastgelegd als een programma, en als je dat programma wilt bekijken en/of veranderen dan moet je het volgende doen:

  • Klik op Extra, dan op Macro, dan op Macro's, kies Eindsortering uit, en klik op Bewerken.
    In Excel 2007 klik je op Beeld → Macro's → Macro's weergeven, kies Eindsortering uit, en klik op Bewerken.
    Dan krijg je het volgende venster in beeld:

Je ziet dat er in de titelbalk Visual Basic staat. Er wordt dus vanuit Excel naar VBA overgeschakeld.
Wil je weer terug naar Excel dan moet je dit venster wegklikken, het venster van Excel staat er nog wel achter.

  7.2. Een knop met VBA maken

We hebben in hoofdstuk 5 gezien dat je een knop voor een macro kunt maken.
Je kunt nog op een andere manier een knop maken, en dan hoeft het niet beslist voor een macro te zijn.
Dat kan met VBA, dat is Visual Basic for Applications.

Wil je er voor zorgen dat je het programma voor het sorteren, dat je in de vorige paragraaf hebt gezien, kunt oproepen door op een knop te klikken dan moet je het volgende doen:
  • Klik op Beeld, dan op Werkbalken, en dan op Visual Basic.
    In Excel 2007 klik je op de Officeknop linksboven en dan op Opties voor Excel → Populair. En dan zet je een vinkje voor Tabblad Ontwikkelaars op het lint weergeven en je klikt op OK
    Daarna klik je in het lint op het tabblad Ontwikkelaars, en dan zie je op het lint bij de groep Besturingselementen de icoontjes die bij Excel 2003 op de werkbalk Visual Basic staan.

  • Klik nog eens op Beeld, dan op Werkbalken, en dan op Werkset Besturingselementen.
    In Excel 2007 klik je in het lint op het tabblad Ontwikkelaars, en dan bij de groep Besturingselementen op Invoegen.

    Dan zie je in Excel 2003 het volgende venster: In Excel 2007 ziet het er wat anders uit, maar het komt op hetzelfde neer)



  • Nu klik je in de Visual Basic-werkbalk op het rechter icoontje : Ontwerpen, en dan kun je een VBA-programma ontwerpen.
    In Excel 2007 klik je in het lint bij de groep Besturingselementen op Ontwerpmodus

  • Vervolgens klik je in de werkset op de knop CommandButton (=opdrachtknop, zie hiernaast), en dan kun je een button op het werkblad zetten.

  • Klik dan in de werkset (of in Excel 2007 klik je er in het lint bij de groep Besturingselementen op) op Eigenschappen (zie hiernaast, rechtsboven), dan kun je de eigenschappen van die knop instellen.
  • In het eigenschappenvenster (zie het venster hieronder) vul je bij Caption Eindsortering in.
  • En bij Name vul je in: bEindsortering in. (de b van button zetten we ervoor).



  • Dan heb je de interface klaar.
  • Maar nu de programmacode nog.
    Daarvoor dubbelklik je op de knop met Eindsortering, dan verschijnt het programmavenster.
  • Er staat al Private Sub bEindsortering_Click() en een eindje verder staat End Sub
    Op de regels daar tussen moet de programma-code worden geplaatst.
    Daar tik je het volgende in (of je plakt het er neer als je van tevoren de tekst uit de macro op het klembord hebt gezet) :

    Private Sub bEindsortering_Click()
        Range("A3:R6").Select
        Selection.Sort Key1:=Range("R3"), Order1:=xlAscending, Header:=xlGuess, _
            OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom
        Range("A1").Select
    End Sub

  • Als dat klaar is dan klik je het programmavenster en het Visual Basicvenster weg, dan klik je in de Visual Basic-werkbalk op het rechter icoontje : Ontwerpmodus afsluiten (of in Excel 2007 klik je er in het lint bij de groep Besturingselementen op) , en dan ben je klaar.

  7.3. Een paar eenvoudige oefeningen met VBA

Je hoeft niet alleen met macro's VBA te gebruiken, je kunt het ook rechtstreeks gebruiken.
Daar gaan we een beetje mee oefenen.

Een knop voor het vermeerderen van het getal in A4 met één
Zet in een nieuw werkblad in Excel in cel A4 het getal 10
Nu gaan we een knop maken, waarbij het zo is dat als je op die knop klikt er één bij het getal in A4 wordt opgeteld.

Klik in de Visual Basic-werkbalk op het rechter icoontje : Ontwerpen (we gaan er van uit dat de VB-werkbalk op het werkblad staat. Is hij er niet dan moet je hem er eerst neerzetten) (of in Excel 2007 klik je er in het lint bij de groep Besturingselementen op)
Vervolgens klik je in de werkset op de knop CommandButton of Opdrachtknop en dan zet je een button op het werkblad neer.
Klik dan in de werkset op Eigenschappen (rechtsboven), (of in Excel 2007 klik je er in het lint bij de groep Besturingselementen op) dan verschijnt het eigenschappenvenster
Bij Caption vul je Tel er 1 bij op in.
En bij Name vul je in: bOptellen in. (de b van button zetten we ervoor).

Dan heb je de interface klaar.
Dubbelklik vervolgens op de knop met Tel er 1 bij op, dan verschijnt het programmavenster.
Daar tik je het volgende in:

Private Sub bOptellen_Click()
	Dim g As Integer
	g = Cells(4,1).value
	g = g+1
	Cells(4,1).value = g
End Sub

Als dat klaar is dan klik je het Visual Basicvenster weg, dan klik je in de Visual Basic-werkbalk op het rechter icoontje : Ontwerpmodus afsluiten, (of in Excel 2007 klik je er in het lint bij de groep Besturingselementen op) en dan ben je klaar.
Probeer het dan een paar keer uit door op de knop te klikken.

Toelichting:
  • Cells(4,1).value geeft de waarde van de cel in de vierde rij en de eerste kolom, dus cel A4
  • Door de opdracht g = Cells(4,1).value krijgt g die waarde.
  • De opdracht g = g + 1 heeft tot gevolg dat bij de waarde van g 1 wordt opgeteld.
  • En door de opdracht Cells(4,1).value =g wordt die waarde in de cel A4 gezet.


Een knop voor het vermeerderen van het getal in A4 met een getal dat je in een venster opvraagt
We willen het nu zo maken dat als je op de knop klikt er een invoervenster verschijnt. En als je daar dan bijvoorbeeld 7 invult dan moet er 7 worden opgeteld bij het getal in A4.
Dat kun je op de volgende manier bereiken:
Klik in de Visual Basic-werkbalk op het rechter icoontje : Ontwerpen (of in Excel 2007 klik je er in het lint bij de groep Besturingselementen op)
Klik dan in de werkset op Eigenschappen (rechtsboven), (of in Excel 2007 klik je er in het lint bij de groep Besturingselementen op) dan verschijnt het eigenschappenvenster
Klik op de knop, die je zonet op het werkblad hebt gezet. Dan verschijnen de eigenschappen van die knop in het eigenschappenvenster
Bij Caption vul je Tel ingevulde waarde op in.
En bij Name vul je in: bOptellen in. (de b van button zetten we ervoor).

Dubbelklik vervolgens op de knop, dan verschijnt het programmavenster.
Daar tik je het volgende in:

Private Sub bOptellen_Click()
	Dim g, w As Integer

	g = Cells(4,1).value
	w = InputBox("VBA-test","Voer getal in")
	g = g + w
	Cells(4,1).value = g
End Sub

Als dat klaar is dan klik je het Visual Basicvenster weg, dan klik je in de Visual Basic-werkbalk op het rechter icoontje : Ontwerpmodus afsluiten, (of in Excel 2007 klik je er in het lint bij de groep Besturingselementen op) en dan ben je klaar.
Probeer het dan een paar keer uit door op de knop te klikken.

Toelichting:
  • g = Cells(4,1).value zorgt er voor dat de variabele g de waarde krijgt van de inhoud van cel A4
  • w = InputBox("VBA-test", "Voer getal in") heeft tot gevolg dat er een invoervenster verschijnt.
    In de titelbalk van dat venster staat VBA-test, en in het venster zelf staat Voer getal in
    En als je dan een getal, bijv. 7, intikt en op OK klikt, dan krijgt w die waarde 7
  • De opdracht g = g + w heeft tot gevolg dat bij de waarde van g de waarde van w wordt opgeteld.
  • En door de opdracht Cells(4,1).value = g wordt de nieuwe waarde van g in de cel A4 gezet.


Een knop voor het tellen van het aantal cellen in de eerste kolom waar iets is ingevuld
We willen het nu zo maken dat als je op de knop klikt er in een venster verschijnt in hoeveel cellen in de eerste kolom iets is ingevuld.
Dat kun je op de volgende manier doen:
Klik in de Visual Basic-werkbalk op het rechter icoontje : Ontwerpen (of in Excel 2007 klik je er in het lint bij de groep Besturingselementen op)
Klik dan in de werkset op Eigenschappen (rechtsboven), (of in Excel 2007 klik je er in het lint bij de groep Besturingselementen op) dan verschijnt het eigenschappenvenster
Klik op de knop, die je zonet op het werkblad hebt gezet. Dan verschijnen de eigenschappen van die knop in het eigenschappenvenster
Bij Caption vul je Tel het aantal ingevulde cellen in.
En bij Name vul je in: bTellen in. (de b van button zetten we ervoor).

Dubbelklik vervolgens op de knop, dan verschijnt het programmavenster.
Daar tik je het volgende in:

Private Sub bTellen_Click()
	Dim i, aantal As Integer
	dim g as string

	aantal = 0
	for i=1 to 100
    		g = Cells(i,1).value
    		if g <> "" then aantal = aantal+1
	next i
	msgbox("Het aantal ingevulde cellen is " + str(aantal))
End Sub

Als dat klaar is dan klik je het Visual Basicvenster weg, dan klik je in de Visual Basic-werkbalk op het rechter icoontje : Ontwerpmodus afsluiten, en dan ben je klaar.
Vul iets in in een paar cellen van de eerste kolom en probeer het dan een paar keer uit door op de knop te klikken.

Toelichting:
  • Het aantal cellen waar iets in staat wordt vastgelegd m.b.v. de variabele aantal
    Daar moet in het begin, voor je begint te tellen, natuurlijk het getal 0 in staan.
    Daar dient de opdracht aantal = 0 voor, dat noem je de initialisatie.
  • Als we er van uit gaan dat er in ieder geval vanaf de 101-ste rij niets meer ingevuld is, dan moet er in de 1-ste, de 2-de, de 3-de, tot en met de 100-ste cel worden gekeken of er iets staat.
    Daarom wordt de for-lus gebruikt: alles tussen de opdrachten for i=1 to 100 en next i wordt 100 keer herhaald, en daarbij krijgt i achtereenvolgens de waarden 1 t/m 100
  • De eerste opdracht die wordt uitgevoerd is g = Cells(i,1).value
    De eerste keer heeft i de waarde 1, dus eigenlijk staat er dan g = Cells(1,1).value
    Dat betekent dat g de waarde krijgt die in de eerste cel staat.
  • In de volgende opdracht staat if g <> "" then aantal = aantal+1
    Dat betekent dat als g niet niets is (twee aanhalingstekens vlak na elkaar betekent: niets en <> betekent: niet gelijk aan) wordt het aantal met één vermeerderd.
    De tweede keer heeft i de waarde 2, dus eigenlijk staat er dan g = Cells(2,1).value
    Dat betekent dat g de waarde krijgt die in de tweede cel staat.
    En if g <> "" then aantal = aantal+1 heeft dan weer tot gevolg dat als g niet niets is (dus als er wel iets is ingevuld) het aantal met één wordt vermeerderd.
    En zo gaat dat door tot en met de honderdste cel. (eventueel kun je ook tot de 1000-ste cel doortellen)
  • En daarna moet dat aantal nog getoond worden, anders heb je er niets aan.
    Dat gebeurt met de opdracht msgbox("Het aantal ingevulde cellen is " + str(aantal))
    Msgbox("----") heeft tot gevolg dat er een venstertje verschijnt waarin ---- staat.
    Als er in 15 cellen iets staat dan verschijnt er in de Messagebox uit het programma: Het aantal ingevulde cellen is 15
    + str(aantal) betekent dat het aantal (het aantal waar m.b.v. str(--) eerst een string van gemaakt is) achter de tekst Het aantal ingevulde cellen is geplakt wordt.


Een knop voor het invoeren van woorden in een bepaalde kolom
Stel dat je in een bepaalde kolom een aantal dingen in wilt vullen. Dan kun je dat natuurlijk rechtstreeks in die cellen invullen, maar soms is het handig om dat m.b.v. een knop te doen.
We maken een knop waarmee je dat kunt doen
En dan wel zo, dat er eerst gevraagd wordt in welke kolom je de woorden in wilt vullen .
En dat daarna telkens een invulvenster verschijnt waarin je het volgende woord in kunt voeren, net zo lang tot je niets meer invult. Dus zodat je op OK drukt bij het invulvenster zonder dat je iets hebt ingevuld, wordt er gestopt.
Dat kun je op de volgende manier doen:
Klik in de Visual Basic-werkbalk op het rechter icoontje : Ontwerpen (of in Excel 2007 klik je er in het lint bij de groep Besturingselementen op)
Zet een nieuwe knop op het werkblad.
Klik dan in de werkset op Eigenschappen (rechtsboven), (of in Excel 2007 klik je er in het lint bij de groep Besturingselementen op) dan verschijnt het eigenschappenvenster met de eigenschappen van die knop.
Bij Caption vul je Voer woorden in kolom in in.
En bij Name vul je in: bVoerin in. (de b van button zetten we ervoor).

Dubbelklik vervolgens op de knop, dan verschijnt het programmavenster.
Daar tik je het volgende in:

Private Sub bVoerin_Click()
Dim v As String
Dim kolom, rij As Integer

kolom=InputBox("Geef het nummer van de kolom die je in wilt vullen","VBA")
If (kolom < 1) Or (kolom > 10) Then Exit Sub

rij = 1
v = "iets"

while v <> ""
    v=InputBox("Welk woord in rij "+str(rij)+" en kolom  "+str(kolom))
    Cells(rij, kolom + 1 - 1).value = v
    rij = rij + 1
wend

End Sub

Toelichting:
  • De opdracht kolom=InputBox("Geef het nummer van de kolom die je in wilt vullen","VBA")
    heeft tot gevolg dat er een invulvenster verschijnt, waarin om het kolomnummer wordt gevraagd.
    Het nummer van die kolom wordt opgeslagen in de variabele kolom.
  • En dan moet er steeds gevraagd worden welk woord er in de volgende cel moet verschijnen.
    Maar je weet van tevoren niet hoe vaak dat herhaald moet worden.
    Daarom kan het niet met de opdracht FOR i=1 TO ....
    Je weet wel dat er net zo lang doorgegaan moet worden tot er niets wordt ingevuld.
    Als je het ingevulde woord in de variabele v opslaat dan moet er dus net zo lang doorgegaan worden tot v leeg is.
    Je kunt ook zeggen dat er steeeds doorgegaan moet worden zolang v niet leeg is, dus zolang v <> "" is.
    De opdrachten tussen while v <> "" en wend worden dan ook net zolang herhaald tot v leeg is.
  • Maar dan moet v in het begin niet leeg zijn, anders wordt er direkt gestopt.
    Daarom staat de opdracht v = "iets" er tussen, zodat v in het begin niet leeg is.
  • Verder moet het volgende woord steeds in de volgende rij worden ingevuld, dus de rij die aan de beurt is moet worden vastgelegd. Dat gebeurt met de variabele rij.
    En elke keer als er iets is ingevuld wordt het rij-nummer opgehoogd m.b.v. de opdracht rij = rij + 1
  • De opdracht Cells(rij, kolom + 1 - 1).value = v heeft tot gevolg dat het ingetypte woord in de juiste cel wordt geplaatst.
    Als je de opdracht invoert als Cells(rij, kolom).value = v dan zou het eigenlijk ook goed moeten gaan. Maar Excel geeft dan een foutmelding omdat er voor de sluithaakjes een getal wordt verwacht. Daarom heb ik er maar +1-1 tussen gezet, dan werkt het.

  7.4. Een knop voor het invoeren van extra namen

We gaan nu weer terug naar het werkblad van de schaatsers.
De namen van vier schaatsers zijn ingevoerd. Bij een echte wedstrijd zijn er meestal veel meer. We gaan er van uit dat er 16 deelnemers zijn.
Nu kun je die namen gemakkelijk rechtstreeks invoeren. Maar het kan ook anders. Dat gaan we nu laten zien.

Klik in de Visual Basic-werkbalk op het rechter icoontje : Ontwerpen (we gaan er van uit dat de VB-werkbalk nog op het werkblad staat. Is hij er niet dan moet je hem er eerst neerzetten) (of in Excel 2007 klik je er in het lint bij de groep Besturingselementen op).
Vervolgens klik je in de werkset op de knop CommandButton of Opdrachtknop en dan zet je een button op het werkblad neer.
Klik dan in de werkset op Eigenschappen (rechtsboven), (of in Excel 2007 klik je er in het lint bij de groep Besturingselementen op) dan verschijnt het eigenschappenvenster
Bij Caption vul je Namen invoeren in.
En bij Name vul je in: bNamenInvoeren in. (de b van button zetten we ervoor).

Dan heb je de interface klaar.
Dubbelklik vervolgens op de knop met Namen invoeren, dan verschijnt het programmavenster.
Daar tik je het volgende in (of je plakt het er neer als je de tekst hieronder eerst geselecteerd hebt en op het klembord hebt gezet) :

Private Sub bNamenInvoeren_Click()
Dim naam, oudenaam As String
Dim aantal As Integer
aantal = 0
naam = "x"
For r = 1 To 16
    If Cells(r + 2, 2) <> "" Then aantal = aantal + 1
Next r

If aantal = 16 Then
    MsgBox ("Meer namen invullen kan niet")
Else
    For r = 1 To 16
        oudenaam = Cells(r + 2, 2).Value
        If naam <> "" And naam <> "Onwaar" Then
          naam=InputBox("Deelnemer " & r &"","Voer namen in",oudenaam)
          If naam <> "" And naam <> "Onwaar" Then
                Cells(r + 2, 2).Value = naam
                Cells(r + 2, 1).Value = r
          End If
        End If
    Next r
End If

End Sub

Als dat klaar is dan klik je het Visual Basicvenster weg, dan klik je in de Visual Basic-werkbalk op het rechter icoontje : Ontwerpmodus afsluiten, (of in Excel 2007 klik je er in het lint bij de groep Besturingselementen op) en dan ben je klaar.

Toelichting:

De eerste opdrachten:
aantal = 0
For r = 1 To 16
    If Cells(r + 2, 2) <> "" Then aantal = aantal + 1
Next r
In die opdrachten wordt geteld hoeveel namen er al zijn ingevoerd.
Als r gelijk is aan 1 dan bevat Cells(r + 2, 2) de inhoud van de cel in de derde rij en de tweede kolom. (De eerste naam staat in de derde regel, daarom r+2 )
Als daar al iets is ingevuld, dus als dat niet leeg is ( dus <> "" ) dan wordt er één bij het aantal opgeteld d.m.v. de opdracht aantal = aantal + 1
Van tevoren is het aantal op nul gezet d.m.v. de opdracht aantal = 0, en de variabele aantal is gedeclareerd d.m.v. de opdracht Dim aantal As Integer

If aantal = 16 Then MsgBox ("Meer namen invullen kan niet")
Deze opdracht heeft tot gevolg dat als er al 16 namen zijn ingevoerd er een venstertje komt met de tekst "Meer namen invullen kan niet"
Als er nog geen 16 namen zijn ingevoerd dan gaat de computer verder met de opdrachten achter else

De opdracht
oudenaam = Cells(r + 2, 2).Value
heeft tot gevolg dat in de geheugenplaats oudenaam (dat is een geheugenplaats voor een woord, dat zie je aan de declaratie Dim oudenaam as String) de naam wordt gezet die eventueel al is ingevuld in de cel op regel r+2 en in kolom 2.

De opdracht
naam = InputBox("Deelnemer " & r & ":", "Voer namen in", oudenaam)
heeft tot gevolg dat er een venstertje verschijnt waarin iets kan worden ingevuld.
Achter Inputbox staan drie dingen, gescheiden tussen komma's.
  • De middelste tekst komt in de titelbalk, dus in de titelbalk van dat venster staat : Voer namen in
  • De eerste tekst verschijnt in het venster, daar staat de eerste keer: Deelnemer 1:, en als r 2 is dan staat er: Deelnemer 2:, enz.
    "Deelnemer " & r & ":" betekent dus dat het woord deelnemer wordt afgedrukt, dan de waarde van r, en dan de dubbele punt.
  • De laatste tekst verschijnt alvast als invoer, zodat als er al een naam in de cel stond die naam ook in het invulvak staat, en dan hoeft er alleen maar op enter te worden gedrukt om die naam (weer) vast te leggen.
Cells(r + 2, 2).Value = naam
heeft tot gevolg dat de ingevoerde naam in de cel op regel r+2 en in kolom 2 wordt geplaatst.

Cells(r + 2, 1).Value = r
heeft tot gevolg dat het nummer in de cel op regel r+2 en in kolom 1 wordt geplaatst.

Dit moet natuurlijk alleen gebeuren als er echt een naam is ingevuld, dus als de geheugenplaats naam niet leeg is (dus naam <> "") en als er op Annuleren is geklikt dan moet er ook niets gebeuren. Als er op Annuleren is geklikt dan wordt de geheugenplaats naam automatisch gevuld met het woord Onwaar, vandaar dat er ook bij staat: naam <> "Onwaar"

De rest is hopelijk wel duidelijk.

  7.5. Een programma om de tijden in te voeren.

De tijden moeten ook worden ingevoerd.
Die kun je rechtstreeks invoeren, maar we laten ook hier zien hoe dat met een programma kan.

Maak eerst een knop met daarop Tijden invoeren.
En voer de volgende programmacode daarbij in:

Private Sub bTijdenInvoeren_Click()

Dim keuze, invoer, namen As String
Dim a, v As Integer

keuze = "1 = 500 m" + Chr(13) + "2 = 1500 m" + 
         Chr(13) + "3 = 5000 m" + Chr(13) + "4 = 10000 m"

a=InputBox(keuze,"Geef het nummer van de afstand die je in wilt vullen")
If a < 1 Or a > 5 Then Exit Sub

namen = ""
For r = 3 To 18
    If (Cells(r, 2) <> "") And 
       (Cells(r, 3 + (a - 1) * 4) = "") Then
        namen = namen + " " & (r - 2) & " " + Cells(r, 2) + Chr(13)
    End If
Next r

v = InputBox(namen,"Volgnummer voor invullen op de " + 
      Cells(1, 3 + (a - 1) * 4))

If a > 1 Then
    invoer=InputBox(Cells(v+2,2),Cells(1,3+(a-1)*4)+"tijd in minuten:")
    Cells(v + 2, 2 + (a - 1) * 4) = invoer
End If

invoer=InputBox(Cells(v+2,2),Cells(1,3+(a-1)*4)+"tijd in seconden:")
Cells(v+2,3+(a-1)*4)=invoer
invoer=InputBox(Cells(v+2,2),Cells(1,3+(a-1)*4)+"tijd in 1/100 sec:")
Cells(v+2,4+(a-1)*4)=invoer

End Sub

Toelichting:
De opdracht a = InputBox(keuze, "Geef het nummer van de afstand die je in wilt vullen")
heeft tot gevolg dat het volgende venster verschijnt:

Wat er in de string keuze zit is vastgelegd door de opdracht
keuze = "1 = 500 m" + Chr(13) + "2 = 1500 m" + Chr(13) + "3 = 5000 m" + Chr(13) + "4 = 10000 m"
Chr(13) is de code van de entertoets, je kunt ook zeggen dat het de code is om op een nieuwe regel over te gaan.
Dus bevat de string keuze ten eerste "1 = 500 m", dan "2 = 1500 m" en dat wordt op de volgende regel gezet doordat Chr(13) er tussen staat, enz.

De opdracht
If a < 1 Or a > 5 Then Exit Sub heeft tot gevolg dat als er niet 1, 2, 3 of 4 wordt ingetikt er gestopt wordt met de procedure.

De opdracht
v = InputBox(namen, "Volgnummer voor invullen op de " + Cells(1, 3 + (a - 1) * 4))
heeft tot gevolg dat het volgende venster verschijnt:

Wat er in de string namen zit is vastgelegd door de opdrachten
namen = ""
For r = 3 To 18
If (Cells(r, 2) <> "") And (Cells(r, 3 + (a - 1) * 4) = "") Then
namen = namen + " " & (r - 2) & " " + Cells(r, 2) + Chr(13)
End If
Next r

Eerst de initialisatie-opdracht: (namen = "" ) namen wordt gevuld met de lege string

Daarna wordt er steeds een naam en een nummer aan de string namen toegevoegd: het nummer is (r-2) en de naam zit in de cel op regel r en in kolom 2 (Cells(r, 2) ) , en elke naam komt op een nieuwe regel doordat er Chr(13) aan toegevoegd is.

Maar een naam wordt er alleen aan toegevoegd als er echt een naam in cel (r,2) staat, want het gebeurt alleen als
Cells(r, 2) <> ""
en verder wordt de naam er ook alleen aan toegevoegd als er nog geen tijd is ingevuld voor de afstand waarom het gaat (als a = 1 dan is dat de 500 meter en dan staan de seconden in cel (r,3), enz.), want het gebeurt alleen als
Cells(r, 3 + (a - 1) * 4) = ""

Als het volgnummer van degene waarvan de tijd moet worden ingevuld is ingevoerd verschijnt er een nieuw venster zoals hieronder:

Alleen voor die persoon wordt gevraagd wat de tijd in minuten is (alleen als a>1).
Daarna wat de tijd in seconden is. En dan nog wat de tijd in honderdsten van seconden is.
En die tijden worden vastgelegd in de cellen die daarvoor bestemd zijn.

  7.6. Het eindklassement in een venster.

Als laatste laten we nog even zien hoe je er voor kunt zorgen dat het eindklassement in een apart venstertje getoond wordt.

Maak eerst een knop met daarop Klassement.
En voer de volgende programmacode daarbij in:

Private Sub bKlassement_Click()

Dim lijst As String
Dim r, l, q As Integer

Range("A3:R18").Select
    Selection.Sort Key1:=Range("R1"), Order1:=xlAscending, Header:=xlGuess, _
        OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom
        
lijst = ""
l = 0
For r = 3 To 18
  If Cells(r,5).Value>0 And Cells(r,9).Value>0 And 
                               Cells(r,13).Value>0 And Cells(r,17).Value>0 Then
    l = l + 1
    lijst=lijst+"" & l & ":"+Cells(r,2)+":"+Str(Int(Cells(r,18)*100)/100)+Chr(13)
  End If
Next r

Range("A3:R18").Select
    Selection.Sort Key1:=Range("A1"), Order1:=xlAscending, Header:=xlGuess, _
        OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom
Range("A1").Select
q = MsgBox(lijst, vbDefaultButton1, "Eindklassement")
     
End Sub

Toelichting:
Eerst wordt er gesorteerd op kolom R, dus op het puntentotaal.

Dan wordt er een lijst gemaakt van die uitslag.
Er wordt begonnen met een lege lijst (opdracht: lijst = "" )
Dan wordt er steeds een naam met het puntenaantal aan de lijst toegevoegd.
Maar alleen als de schaatser alle afstanden heeft gereden, want er moet gelden:
Cells(r, 5).Value > 0

In cel (r,5) staat de tijd op de 500 meter, die moet dus zijn ingevuld.
Verder moet ook in cel (r,9) een tijd staan (dat is de tijd op de 1500 meter) en verder in cel (r,13) (dat is de 5000 m) en in cel (r,17) (dat is de 10000 m)

lijst = lijst + "" & l & ":" + Cells(r, 2) + ":" betekent dat het klassementsnummer aan de lijst wordt toegevoegd en de naam (want l is het klassementsnummer en in cel (r,2) staat de naam )

Str(Int(Cells(r, 18) * 100) / 100) + Chr(13) is het puntentotaal, afgerond op twee decimalen (eerst wordt het keer 100 gedaan, daarvan de gehele waarde, en dan wordt er weer gedeeld door 100)

Str zorgt er voor dat het een string wordt, anders kan het niet aan de lijst worden toegevoegd, want lijst is ook een string.

chr(13) zorgt er voor dat elke volgende naam op een nieuwe regel begint.

vbDefaultButton1 betekent dat er alleen maar OK in het venster staat, waarop geklikt moet worden om verder te kunnen.
(je kunt ook vbYesNo gebruiken of vbYesNoCancel, en nog veel meer)

Daarna wordt er nog eens op kolom A gesorteerd, zodat de schaatsers in het werkblad weer in de oorspronkelijke volgorde staan.
Maar in de lijst blijven ze gesorteerd op eindklassement

En tenslotte verschijnt er een venster (een messagebox) waarin de lijst staat, en waarvan de titel is : Eindklassement.
Hier rechts zie je hoe dat er uit ziet.

  7.7. Overzicht VBA-opdrachten

waarde = Cells(r , k).Value De variabele waarde krijgt als inhoud de waarde die staat in de cel in rij r en kolom k
Cells(r , k).Value = waarde
of: Cells(r , k) = waarde
In de cel in rij r en kolom k verschijnt de inhoud van de variabele waarde
Blad2.Cells(r , k).Value = waarde
In de cel op Blad2 in rij r en kolom k verschijnt de inhoud van de variabele waarde
Blad2.Activate
De inhoud van blad2 verschijnt in beeld
MsgBox ("Dit is een test") Er verschijnt een venstertje met de boodschap: "Dit is een test"
aantal = 0
While Cells(r,1) <> ""
      aantal = aantal + 1
      r = r + 1
wend
Er wordt geteld in hoeveel cellen in de eerste kolom iets is ingevuld
De variabele aantal bevat na afloop dat getal
naam = InputBox("nr. 10", "Voer naam in", "Piet") Er verschijnt een invoervenster met als tekst: nr. 10, en in de titelbalk staat: Voer naam in
Als naam staat al ingevuld: Piet, maar die kan worden gewijzigd
De variabele naam krijgt als inhoud de naam die in het invoervenster is ingetypt
do until (a>=1 and a<=4)
a = InputBox(keuze, "Geef nummer tussen 1 en 4")
loop
Er verschijnt een invoervenster met de tekst: "Geef nummer tussen 1 en 4" en dat wordt net zo lang herhaald tot er een getal tussen 1 en 4 wordt ingetypt.
De variabele a krijgt de ingevoerde waarde
g = ActiveCell.Value De variabele g krijgt de waarde van de actieve cel
ActiveCell.Value = g In de actieve cel verschijnt de waarde van g
c = ActiveCell.Column De variabele c krijgt de kolom-waarde van de actieve cel
r = ActiveCell.Row De variabele r krijgt de rij-waarde van de actieve cel
Range(r+1,c).Select De cel onder de huidige wordt actief (geselecteerd)
Sheets("Blad2").Range("A1:B12").Select De cellen A1 t/m B12 van blad2 worden geselecteerd
Selection.Copy De geselecteerde cellen worden op het klembord gezet
Ze staan klaar om gekopieerd te worden
Workbooks.Add Er wordt een nieuw excel-werkblad geopend
ActiveSheet.Paste De cellen, die op het klembord staan, worden in het actieve werkblad geplakt
ActiveWorkbook.SaveAs Bestandsnaam Het werkblad wordt opgeslagen onder de naam die de variabele Bestandsnaam bevat
ActiveWorkbook.Save Het werkblad wordt opgeslagen
ActiveWorkbook.Close Het actieve werkblad wordt gesloten
ListBox1.ListFillRange = "A1:A10" Listbox1 wordt gevuld met de gegevens uit de cellen A1 t/m A10
Private Sub Worksheet_Activate()
.....................................
End Sub
De opdrachten die op de stippeltjes staan worden uitgevoerd als het werkblad wordt geactiveerd