Zoeken…


Best practices

Een UserForm is een klassemodule met een ontwerper en een standaardinstantie . De ontwerper kan worden benaderd door op Shift + F7 te drukken terwijl de code-behind wordt bekeken , en de code-behind kan worden geopend door op F7 te drukken terwijl u de designer bekijkt.


Werk elke keer met een nieuw exemplaar.

Als een klassemodule is een formulier daarom een blauwdruk voor een object . Omdat een formulier status en gegevens kan bevatten, is het een betere gewoonte om met een nieuw exemplaar van de klasse te werken, in plaats van met het standaard / globale exemplaar:

With New UserForm1
    .Show vbModal
    If Not .IsCancelled Then
        '...
    End If
End With

In plaats van:

UserForm1.Show vbModal
If Not UserForm1.IsCancelled Then
    '...
End If

Werken met de standaardinstantie kan leiden tot subtiele bugs wanneer het formulier wordt gesloten met de rode "X" -knop en / of wanneer Unload Me wordt gebruikt in de code-behind.


Implementeer de logica elders.

Een formulier moet zich alleen bezighouden met presentatie : een Click handler die verbinding maakt met een database en een geparametriseerde query uitvoert op basis van gebruikersinvoer, doet teveel dingen .

Implementeer in plaats daarvan de applicatielogica in de code die verantwoordelijk is voor het weergeven van de vorm, of nog beter, in speciale modules en procedures.

Schrijf de code zodanig dat het UserForm alleen verantwoordelijk is om te weten hoe gegevens moeten worden weergegeven en verzameld: waar de gegevens vandaan komen of wat er daarna met de gegevens gebeurt, is hem niet van belang.


Beller moet zich niet bezig houden met bedieningselementen.

Maak een goed gedefinieerd model voor het formulier om mee te werken, hetzij in zijn eigen speciale klassenmodule, of ingekapseld in de code van het formulier achter zichzelf - leg het model bloot met Property Get procedures en laat de klantcode hiermee werken: dit maakt de vorm een abstractie over bedieningselementen en hun nitty-gritty details, waardoor alleen de relevante gegevens aan de klantcode worden blootgesteld.

Dit betekent code die er zo uitziet:

With New UserForm1
    .Show vbModal
    If Not .IsCancelled Then
        MsgBox .Message, vbInformation
    End If
End With

In plaats van dit:

With New UserForm1
    .Show vbModal
    If Not .IsCancelled Then
        MsgBox .txtMessage.Text, vbInformation
    End If
End With

Behandel de QueryClose-gebeurtenis.

Formulieren hebben meestal een knop Sluiten en aanwijzingen / dialoogvensters hebben de knoppen OK en Annuleren ; kan de gebruiker het formulier sluiten met behulp van het besturingsvak van het formulier (de rode "X" -knop), die standaard de formulierinstantie vernietigt (nog een goede reden om elke keer met een nieuwe instantie te werken ).

With New UserForm1
    .Show vbModal
    If Not .IsCancelled Then 'if QueryClose isn't handled, this can raise a runtime error.
        '...
    End With
End With

De eenvoudigste manier om de QueryClose gebeurtenis af te handelen is om de parameter Cancel te stellen op True en vervolgens het formulier te verbergen in plaats van het te sluiten :

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    Cancel = True
    Me.Hide
End Sub

Op die manier zal de "X" -knop het exemplaar nooit vernietigen en heeft de beller veilig toegang tot alle openbare leden.


Verbergen, niet sluiten.

De code die een object maakt, moet verantwoordelijk zijn voor het vernietigen ervan: het is niet de verantwoordelijkheid van het formulier om zichzelf te ontladen en te beëindigen.

Vermijd het gebruik van Unload Me in de code achter van een formulier. Call Me.Hide plaats daarvan, zodat de roepende code nog steeds het object kan gebruiken dat is gemaakt wanneer het formulier wordt gesloten.


Noem dingen.

Gebruik het eigenschappenvenster ( F4 ) om elk besturingselement op een formulier zorgvuldig een naam te geven. De naam van een besturingselement wordt gebruikt in de code achter, dus tenzij u een refactoring-tool gebruikt die dit aankan, zal het hernoemen van een besturingselement de code verbreken - dus het is veel gemakkelijker om dingen meteen te doen, dan proberen om precies uit te puzzelen voor welke van de 20 tekstvakken waar TextBox12 staat.

Traditioneel worden UserForm-besturingselementen benoemd met voorvoegsels in Hongaarse stijl:

  • lblUserName een Label controle die een gebruikersnaam aangeeft.
  • txtUserName voor een TextBox besturingselement waar de gebruiker een gebruikersnaam kan invoeren.
  • cboUserName voor een ComboBox besturingselement waar de gebruiker een gebruikersnaam kan invoeren of kiezen.
  • lstUserName voor een ListBox besturingselement waarbij de gebruiker een gebruikersnaam kan kiezen.
  • btnOk of cmdOk voor een Button het label "Ok".

Het probleem is dat wanneer bijvoorbeeld de UI wordt vernieuwd en een ComboBox verandert in een ListBox , de naam moet veranderen om na te denken van de nieuwe controle-type: het is beter om de naam van de controles voor wat ze vertegenwoordigen, in plaats van na hun controle-type - de ontkoppelen code uit de UI zoveel mogelijk.

  • UserNameLabel voor een alleen-lezen label dat een gebruikersnaam aangeeft.
  • UserNameInput Voer een besturingselement in waarmee de gebruiker een gebruikersnaam kan invoeren of kiezen.
  • OkButton voor een opdrachtknop met het label "Ok".

Welke stijl ook wordt gekozen, alles is beter dan alle besturingselementen hun standaardnamen te laten. Consistentie in naamgevingsstijl is ook ideaal.

Query verwerkenSluiten

De QueryClose gebeurtenis wordt QueryClose wanneer een formulier wordt gesloten, of het nu via gebruikersactie of programmatisch is. De parameter CloseMode bevat een VbQueryClose enum-waarde die aangeeft hoe het formulier is gesloten:

Constante Beschrijving Waarde
vbFormControlMenu Formulier wordt gesloten als reactie op gebruikersactie 0
vbFormCode Formulier wordt gesloten als reactie op een Unload instructie 1
vbAppWindows Windows-sessie is afgelopen 2
vbAppTaskManager Windows Taakbeheer sluit de hosttoepassing 3
vbFormMDIForm Niet ondersteund in VBA 4

Voor een betere leesbaarheid is het het beste om deze constanten te gebruiken in plaats van hun waarde direct te gebruiken.


Een annuleerbaar gebruikersformulier

Een formulier gegeven met een knop Annuleren

een voorbeeldvorm

De code-achter van het formulier kan er zo uitzien:

Option Explicit
Private Type TView
    IsCancelled As Boolean
    SomeOtherSetting As Boolean
    'other properties skipped for brievety
End Type
Private this As TView

Public Property Get IsCancelled() As Boolean
    IsCancelled = this.IsCancelled
End Property

Public Property Get SomeOtherSetting() As Boolean
    SomeOtherSetting = this.SomeOtherSetting
End Property

'...more properties...

Private Sub SomeOtherSettingInput_Change()
    this.SomeOtherSetting = CBool(SomeOtherSettingInput.Value)
End Sub

Private Sub OkButton_Click()
    Me.Hide
End Sub

Private Sub CancelButton_Click()
    this.IsCancelled = True
    Me.Hide
End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    If CloseMode = VbQueryClose.vbFormControlMenu Then
        Cancel = True
        this.IsCancelled = True
        Me.Hide
    End If
End Sub

De belcode kan dan het formulier weergeven en weten of het is geannuleerd:

Public Sub DoSomething()
    With New UserForm1
        .Show vbModal
        If .IsCancelled Then Exit Sub
        If .SomeOtherSetting Then
            'setting is enabled
        Else
            'setting is disabled
        End If
    End With
End Sub

De eigenschap IsCancelled retourneert True wanneer op de knop Annuleren wordt geklikt of wanneer de gebruiker het formulier sluit met behulp van het besturingselement .



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow