Bereik en zichtbaarheid

Inleiding

Bereik en zichtbaarheid wordt 'de scope' genoemd. Het verwijst naar de beschikbaarheid van een variabele, constante of procedure voor het gebruik door een andere procedure. Er zijn drie scope niveaus: procedure niveau, klassenmodule niveau en standaardmodule niveau.

De scope van een variabele, een constante en een procedure wordt bepaald door waar en hoe deze zijn gedeclareerd. Het is belangrijk dat je dit goed begrijpt en het meteen correct doet waardoor naamconflicten worden voorkomen.

Scope op procedure niveau

Een variabele of constante die binnen een procedure is gedeclareerd is niet zichtbaar buiten die procedure. D.w.z. dat de variabele of constante daarbuiten niet gezien kan worden zonder dat deze wordt doorgegeven. Want de variabele of constante kan wel aan een andere procedure worden doorgeven zodat die er wat mee kan doen (omdat dan de levensduur van de variabele nog niet teneinde is). Deze twee dingen moeten we goed van elkaar onderscheiden. Door te stellen dat alleen de procedure de variabele kan gebruiken waarin deze is gedeclareerd, is dus niet helemaal correct.

De variabele strMsg in procedure ProcName1 kan niet worden gezien door ProcName2. Als ProcName2 wordt uitgevoerd, doet zich een compileerfout voor omdat daar geen variabele strMsg is gedeclareerd. Zouden we in ProcName2 wel een variabele strMsg declareren en er een waarde aan toe kennen, dan is dat niet de waarde van strMsg uit ProcName1 omdat de scope is beperkt tot de procedure.

Sub ProcName1()

    Dim strMsg As String

    strMsg = "De scope van deze variabele beperkt zich tot deze procedure."

    MsgBox strMsg

End Sub

Sub ProcName2()

    MsgBox strMsg

End Sub

Het volgende voorbeeld laat zien dat de variabele die in een procedure is gedeclareerd weldegelijk door een andere procedure kan worden gebruikt. Als procedure ProcName1 wordt uitgevoerd zal ProcName2 een berichtvenster tonen met de waarde van strMsg die binnen ProcName1 is gedeclareerd. strMsg kan zelfs in ProcName2 worden gemanipuleerd.

Als ProcName2 is beëindigd, betekent dit het einde van de levensduur van de variabele strMsg. Het is correct te stellen dat daarna de variabele niet meer kan worden gebruikt.

Sub ProcName1()

    Dim strMsg As String

    strMsg = "De scope van deze variabele wordt weldegelijk verruimd als de variabele wordt doorgegeven. De ontvangende procedure kan er ook nog wat mee doen."

    ProcName2 strMsg

End Sub

Sub ProcName2(strMsg)

    MsgBox strMsg

    strMsg = "Als deze procedure is beëindigd, betekent dit het einde van de levensduur van de variabele."

    MsgBox strMsg

End Sub

Opmerking

Public procedures in een standaardmodule of klassenmodule zijn beschikbaar voor elk project dat ernaar verwijst. Om de scope van alle procedures in een module te beperken tot het huidige project, voeg dan een Option Private Module statement aan de declaratie sectie van de module toe. Public gedeclareerde variabelen en procedures zijn dan nog steeds beschikbaar voor andere procedures in het huidige project, maar niet voor projecten die hier naar verwijzen.

Scope op klassenmodule niveau

Variabelen en constanten kunnen worden gedeclareerd in de declaratie sectie van de module. Ze kunnen zowel Public als Private zijn. Public gedeclaraarde variabelen en constanten zijn beschikbaar voor het gehele project (mits de klassenmodule is geladen en er correct naar wordt verwezen). Private gedeclareerde variabelen en constanten zijn alleen beschikbaar voor procedures in die module. De scope van variabelen en constanten die zijn gedeclareerd met het Dim statement in de declaratie sectie zijn Private. Echter, door het Dim statement te vervangen door het sleutelwoord Private, maak je de scope duidelijker in je code.

De volgende voorbeelden illustreren de scope van de gedeclareerde variabele strMsg. Je kan ook de waarde met een constante instellen zodat die waarde door elke procedure in de module kan worden gebruikt.

' Voeg het volgende toe aan de declaratie sectie van de module.

Dim strMsg As String

Const conMsg As String = "Voor een constante geldt hetzelfde."

Sub ProcName1()

    strMsg = "De scope van deze variabele beperkt zich tot deze module."

    MsgBox strMsg

    MsgBox conMsg

End Sub

Sub ProcName2()

    strMsg = "Dezelfde variabele kan worden gebruikt door een andere procedure in de module."

    MsgBox strMsg

    MsgBox conMsg

End Sub

Het volgende voorbeeld illustreert dat strMsg weldegelijk zichtbaar is buiten de klassenmodule. In dit voorbeeld is de code geplaatst in de klassenmodule van een Access formulier. Voorwaarde is dat de variabele Public is gedeclareerd, het formulier is geladen en een correcte verwijzing is ingesteld.

' Voeg het volgende toe aan de declaratie sectie van de module.

Public strMsg As String

Zorg ervoor dat aan de variabele een waarde is toegekend. In dit geval hebben we dat gedaan in de gebeurtenis Load. In welke gebeurtenis je de waarde bepaald is afhankelijk van welke techniek(en) je wilt gebruiken.

Private Sub Form_Load()

    strMsg = "Ik ben zichtbaar als ik Public ben gedeclareerd, het formulier is geladen en een correcte verwijzing is ingesteld."

End Sub

Zolang het formulier is geladen is de variabele zichtbaar omdat we deze Public hebben gedeclareerd. Zo is deze ook buiten het formulier of klassenmodule zichtbaar. Bij het sluiten van het formulier wordt de levensduur van de variabele beëindigd. Onderstaande code kan zowel in een ander formulier zijn of in een standaardmodule. Voor constanten gaat dit verhaal echter niet op, want het Public declareren van constanten in een klassenmodule is niet toegestaan.

Sub ProcName1()

    Dim frm As Form

    Set frm = Screen.ActiveForm

    MsgBox frm.strMsg

End Sub

Scope op standaardmodule niveau

In het volgende voorbeeld is strMsg in een standaardmodule zichtbaar voor het gehele project omdat deze Public is gedeclareerd. In een standaardmodule is dit doorgaans het gebruik. Is strMsg gedeclareerd met Dim of Private, dan is de variabele alleen zichtbaar binnen de module.

' Voeg het volgende toe aan de declaratie sectie van de module.

Public strMsg As String

Procedures in een standaardmodule zijn standaard allemaal Public. De volgende procedure Sub en procedure Function zijn dus Public. Het Public declareren in een standaardmodule is een optie.

Ook opsommingen in een standaardmodule gedeclareerd met het statement Enum (zie Werken met opsommingen) zijn standaard Public.

Sub ProcName()

    Dim strMsg As String

    MsgBox "Ik ben Public"

End Sub

Public Sub ProcName()

    Dim strMsg As String

    MsgBox "Ik ben ook Public"

End Sub

Function ProcName() As String

    ProcName = "Ik ben Public"

End Function

Public Function ProcName() As String

    ProcName = "Ik ben ook Public"

End Function

Als je wilt dat een procedure alleen zichtbaar is in de module, plaats dan het sleutelwoord Private ervoor. Precies zoals Visual Basic dat ook doet bij het maken van een gebeurtenis procedure in een klassenmodule zoals we hebben gezien bij Sub Private Form_Load in de vorige rubriek. Een met Private gedeclareerde procedure in een standaardmodule is overigens onlogisch, maar het kan. Ook een variabele met Dim declareren in een standaardmodule, is mogelijk. Een logische werkwijze is dat de scope voor code in een standaardmodule altijd Public is.

Cursussen