Het gebruik van de Controls Collection
Regelmatig ontvang ik stukjes source-code waarbij mijn mening wordt gevraagd. Wat daarbij opvalt is dat het gebruik van de Controls Collection niet veel wordt gebruikt. Zie het volgende voorbeeld:
Sub Form_Load()
txtName.Text = ""
txtAdress.Text = ""
txtZipCode.Text =""
txtPlace.Text =""
End Sub
De bedoeling is duidelijk: de maker wil dat als het form wordt geladen de vier aanwezige textboxen leeg worden getoond. Als deze actie zich echter vaker kan voordoen (bijvoorbeeld onder een Cancel-button) dan moet je dezelfde code al meerdere keren invoeren.
Je kan er voor kiezen om er een aparte procedure van te maken:
Sub LeegTextBox()
txtName.Text = ""
txtAdress.Text = ""
txtZipCode.Text =""
txtPlace.Text =""
End Sub
Dan zet je in elke event die de textboxen leeg moet tonen de code:
Sub Form_Load()
Call LeegTextBox
End Sub
Sub cmdCancel_Click()
Call LeegTextBox
End Sub
Je kunt dit nog verder versimpelen door gebruik te maken van de Controls.Collection:
Sub LeegTextBox()
Dim Control
For Each Control In Me.Controls
If TypeOf Control Is TextBox Then Control.Text = ""
Next Control
End Sub
Om het helemaal ‘goed’ te doen maak je er een (op een module) publieke procedure van en geef je nog aan van welke form de textboxen moeten worden geleegd:
Public Sub LeegTextBox(X as Form)
Dim Cntr
For Each Cntr In X.Controls
If TypeOf Cntr Is TextBox Then X.Cntr.Text = ""
Next Cntr
End Sub
Aanroepen gebeurt dan op de volgende manier:
Sub Form_Load()
Call LeegTextBox(Me)
End Sub
Dit kan dan vanaf elk willekeurig formulier en elke event gebeuren. Je kunt natuurlijk elke andere property op deze manier wijzigen. Je kunt tenslotte ook elke control aanroepen. Dit doe je met het TypeOf commando
Het gebruik van indexed controls
Het gebruik van indexed controls heeft als voordeel dat je niet telkens dezelfde code onder dezelfde events van gelijksoortige controls hoeft te plaatsen. Stel je hebt vijf textboxen waar je de volgende gegevens wil laten invoeren:
voornaam (name = txtVoornaam)
achternaam (name = txtAchternaam)
adres (name = txtAdres)
postcode (name = txtPostcode)
woonplaats (name = txtWoonplaats)
Van de invoer in de eerste drie textboxen wil je automatisch de eerste letter van elk woord omzetten in een hoofdletter; van de laatste twee textboxen wil je de invoer in zijn geheel omzetten naar hoofdletters. Kies je ervoor om elke textbox een aparte naam te geven (voor de duidelijkheid is dat wel een goede zaak) dan ziet je code er ongeveer zo uit :
Sub txtVoornaam_LostFocus()
txtVoornaam.Text = StrConv(txtVoornaam.Text, vbProperCase)
End Sub
Sub txtAchternaam_LostFocus()
txtAchternaam.Text = StrConv(txtAchternaam.Text, vbProperCase)
End Sub
Sub txtAdres_LostFocus()
txtAdres.text = StrConv(txtAdres.Text, vbProperCase)
End Sub
Sub txtPostcode_LostFocus()
txtPostcode.Text = UCase$(txtPostode.Text)
End Sub
Sub txtWoonplaats_LostFocus()
txtWoonplaats.Text = Ucase$(txtWoonplaats.Text)
End Sub
Maak je gebruik van indexed textboxen dan ziet het er zo uit:
voornaam (name = txtInvoer; index = 0)
achternaam (name = txtInvoer; index = 1)
adres (name = txtInvoer; index = 2)
postcode (name = txtInvoer; index = 3)
woonplaats (name = txtInvoer; index = 4)
Sub TxtInvoer_LostFocus(Index As Integer)
Select Case Index
Case 0, 1, 2
TxtInvoer(Index).Text = StrConv(TxtInvoer(Index).Text,vbProperCase)
Case 3,4
TxtInvoer(Index).Text = UCase$(TxtInvoer(Index).Text)
End Select
End Sub
Dat scheelt toch wel een hoop type-werk! Nog steeds kun je de voorgaande manier gebruiken om alle textboxen in een keer te legen (er verandert niets aan het soort control wat je gebruikt). Het gebruik van indexed controls gaat meestal samen met het gebruik van de Select Case commando’s.
Een ander voorbeeld waarbij het gebruik van indexed controls erg makkelijk is.
Iedereen gebruikt weleens commandobuttons. Stel je hebt vijf knoppen:
Nieuw (name = cmdKnop; index = 0)
Wijzigen (name = cmdKnop; index = 1)
Bewaren (name = cmdKnop; index = 2)
Verwijder (name = cmdKnop; index = 3)
Stoppen (name = cmdKnop; index = 4)
De code ziet er dan ongeveer zo uit:
Sub cmdKnop_Click(Index As Integer)
Select Case Index
Case 0 ‘code om een item toe te voegen
Case 1 ‘Code om een item te wijzigen
Case 2 ‘Code om een item te bewaren
Case 3 ‘Code om een item te verwijderen
Case 4
Unload Me
End Select
End Sub
Wat je graag zou willen is dat je gebruikers niet tegelijkertijd kunnen toevoegen en verwijderen met andere woorden je wil de mogelijkheid hebben om commandoknoppen te ‘disablen’.
Als er een item wordt toegevoegd moeten de knoppen ‘Wijzigen’ en ‘Verwijderen’ niet ter beschikking staan. Na het bewaren moeten ze weer toegankelijk zijn.
Het komt er dan ongeveer zo uit te zien:
Sub cmdKnop_Click(Index As Integer)
Select Case Index
Case 0 ‘nieuw
cmdKnop(1).Enabled = False
cmdKnop(3).Enabled = False
‘code om een item toe te voegen
Case 1 ‘wijzigen
‘Code om een item te wijzigen
Case 2 ‘bewaren
‘Code om een item te bewaren
cmdKnop(1).Enabled = True
cmdKnop(3).Enabled = True
Case 3 'verwijderen
‘Code om een item te verwijderen
Case 4 ‘stoppen
Unload Me
End Select
End Sub
Dit kan natuurlijk met minder werk. In plaats van per commandoknop de overige knoppen aan of uit te zetten geef je een regel code in:
Sub cmdKnop_Click(Index As Integer)
Select Case Index
Case 0 ‘nieuw
Call SetCommand("10101")
'code om een item toe te voegen
Case 1 ‘wijzigen
‘Code om een item te wijzigen
Case 2 ‘bewaren
‘Code om een item te bewaren
Call SetCommand("11111")
Case 3 'verwijderen
‘Code om een item te verwijderen
Case 4 ‘stoppen
Unload Me
End Select
End Sub
Sub SetCommand(which As String)
Dim lngX As Long
For lngX = 1 To Len(which)
If Mid(which, lngX, 1) = 0 Then
Me.cmdKnop(lngX - 1).Enabled = False
Else
Me.cmdKnop(lngX - 1).Enabled = True
End If
Next lngX
End Sub
Wat de procedure SetCommand doet is per karakter controleren of het een ‘1' of een ‘0' is. Aan de hand van de waarde en van de plaats in de string (‘which’) wordt de betreffende commandoknop toegankelijk (of niet).
Ook deze procedure kun je aanpassen voor gebruik bij meerdere formulieren:
Sub SetCommand(which As String, X As Form)
Dim lngX As Long
For lngX = 1 To Len(which)
If Mid(which, lngX, 1) = 0 Then
X.cmdKnop(lngX - 1).Enabled = False
Else
X.cmdKnop(lngX - 1).Enabled = True
End If
Next lngX
End Sub
De aanroep wordt dan: Call SetCommand("11111", Me)
http://www.kather.net/VisualBasicSource/
[gepubliceerd in kwartaalblad van de Visual Basic Groep NL: Visual Basic Magazine; juni 1998 jaargang 4, nr. 2]