Szukaj…


Najlepsze praktyki

UserForm to moduł klasy z projektantem i instancją domyślną . Dostęp do projektanta można uzyskać, naciskając Shift + F7 podczas przeglądania kodu z tyłu , a dostęp do kodu można uzyskać, naciskając klawisz F7 podczas przeglądania projektanta .


Za każdym razem pracuj z nową instancją.

Forma, będąc modułem klasy , jest więc planem obiektu . Ponieważ formularz może przechowywać stan i dane, lepszą praktyką jest praca z nową instancją klasy niż z domyślną / globalną:

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

Zamiast:

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

Praca z domyślną instancją może prowadzić do subtelnych błędów, kiedy formularz jest zamykany czerwonym przyciskiem „X” i / lub gdy Unload Me jest używany z tyłu kodu.


Zaimplementuj logikę gdzie indziej.

Formularz powinien być zaniepokojony, ale nic z prezentacją: przycisk Click obsługi, który łączy się z bazą danych i uruchamia zapytania parametrycznego na podstawie danych wprowadzonych przez użytkownika, robi zbyt wiele rzeczy.

Zamiast tego zaimplementuj logikę aplikacyjną w kodzie odpowiedzialnym za wyświetlanie formularza, a nawet lepiej, w dedykowanych modułach i procedurach.

Napisz kod w taki sposób, że UserForm jest zawsze odpowiedzialny za to, jak wyświetlać i gromadzić dane: skąd dane pochodzą lub co dzieje się z danymi później, nie ma znaczenia.


Dzwoniącemu nie powinno przeszkadzać sterowanie.

Stwórz dobrze zdefiniowany model formularza do pracy, albo we własnym dedykowanym module klasy, albo zamknięty w samym kodzie formularza - ujawnij model za pomocą procedur Property Get i pozwól, aby kod klienta działał z tymi: tworzą abstrakcję kontroli i ich drobiazgowe szczegóły, ujawniając tylko odpowiednie dane w kodzie klienta.

Oznacza to kod, który wygląda następująco:

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

Zamiast tego:

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

Obsługa zdarzenia QueryClose.

Formularze zazwyczaj mają przycisk Zamknij , a monity / okna dialogowe mają przyciski Ok i Anuluj ; użytkownik może zamknąć formularz za pomocą pola kontrolnego formularza (czerwony przycisk „X”), który domyślnie niszczy instancję formularza (kolejny dobry powód, aby za każdym razem pracować z nową instancją ).

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

Najprostszym sposobem obsługi zdarzenia QueryClose jest ustawienie parametru Cancel na True , a następnie ukrycie formularza zamiast jego zamknięcia :

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

W ten sposób przycisk „X” nigdy nie zniszczy instancji, a osoba dzwoniąca może bezpiecznie uzyskać dostęp do wszystkich członków publicznych.


Ukryj, nie zamykaj.

Kod, który tworzy obiekt, powinien być odpowiedzialny za jego zniszczenie: forma nie jest odpowiedzialna za rozładowanie i zakończenie się.

Unikaj używania opcji Unload Me w formularzu za kodem. Me.Hide tego zadzwoń do Me.Hide , aby kod wywołujący mógł nadal korzystać z obiektu utworzonego po zamknięciu formularza.


Nazwij rzeczy.

Użyj okna narzędzi właściwości ( F4 ), aby ostrożnie nazwać każdą kontrolkę w formularzu. Nazwa kontrolki jest używana w kodzie, więc jeśli nie używasz narzędzia refaktoryzującego, które może to obsłużyć, zmiana nazwy kontrolki spowoduje uszkodzenie kodu - więc o wiele łatwiej jest robić rzeczy właściwie, niż próbować aby dokładnie ustalić, które z 20 TextBox12 oznacza TextBox12 .

Tradycyjnie formanty UserForm są nazywane prefiksami w stylu węgierskim:

  • lblUserName dla kontrolki Label która wskazuje nazwę użytkownika.
  • txtUserName dla kontrolki TextBox której użytkownik może wprowadzić nazwę użytkownika.
  • cboUserName dla kontrolki ComboBox której użytkownik może wprowadzić lub wybrać nazwę użytkownika.
  • lstUserName dla kontrolki ListBox której użytkownik może wybrać nazwę użytkownika.
  • btnOk lub cmdOk dla kontrolki Button oznaczonej „Ok”.

Problem polega na tym, że gdy np. Interfejs użytkownika zostanie przeprojektowany, a ComboBox zmieni się w ListBox , nazwa musi się zmienić, aby odzwierciedlić nowy typ kontrolki: lepiej nazwać formanty dla tego, co reprezentują, niż po ich typie kontrolnym - aby oddzielić kod z interfejsu użytkownika w jak największym stopniu.

  • UserNameLabel dla etykiety tylko do odczytu, która wskazuje nazwę użytkownika.
  • UserNameInput dla kontrolki, w której użytkownik może wprowadzić lub wybrać nazwę użytkownika.
  • OkButton dla jednego przycisku oznaczonego „Ok”.

Niezależnie od tego, który styl zostanie wybrany, wszystko jest lepsze niż pozostawienie wszystkim kontrolkom ich domyślnych nazw. Idealna jest również spójność stylu nazewnictwa.

Obsługa QueryClose

Zdarzenie QueryClose jest wywoływane za każdym razem, gdy formularz ma zostać zamknięty, czy to poprzez działanie użytkownika, czy programowo. Parametr CloseMode zawiera wartość VbQueryClose która wskazuje, w jaki sposób formularz został zamknięty:

Stały Opis Wartość
vbFormControlMenu Formularz zamyka się w odpowiedzi na działanie użytkownika 0
vbFormCode Formularz zamyka się w odpowiedzi na instrukcję Unload 1
vbAppWindows Sesja Windows się kończy 2)
vbAppTaskManager Menedżer zadań systemu Windows zamyka aplikację hosta 3)
vbFormMDIForm Nieobsługiwany w VBA 4

Dla lepszej czytelności najlepiej jest użyć tych stałych zamiast bezpośrednio ich wartości.


Formularz użytkownika, który można anulować

Biorąc pod uwagę formularz z przyciskiem Anuluj

jakiś przykładowy formularz

Kod w formularzu może wyglądać następująco:

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

Kod wywołujący może następnie wyświetlić formularz i wiedzieć, czy został anulowany:

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

Właściwość IsCancelled zwraca wartość True po kliknięciu przycisku Anuluj lub po zamknięciu formularza przez użytkownika za pomocą pola kontrolnego .



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow