Поиск…


Лучшие практики

UserForm - это модуль класса с дизайнером и экземпляром по умолчанию . Доступ к дизайнеру можно получить, нажав Shift + F7 при просмотре кода , а доступ к коду можно получить, нажав F7 во время просмотра дизайнера .


Работайте с новым экземпляром каждый раз.

Будучи модулем класса , форма является, таким образом, планом для объекта . Поскольку форма может содержать состояние и данные, лучше работать с новым экземпляром класса, а не с по умолчанию / глобальным:

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

Вместо:

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

Работа с экземпляром по умолчанию может привести к тонким ошибкам, когда форма закрыта красной кнопкой «X» и / или когда Unload Me используется в коде.


Реализуйте логику в другом месте.

Форма должна касаться только презентации : кнопка Click handler, которая подключается к базе данных и запускает параметризованный запрос на основе ввода пользователем, делает слишком много вещей .

Вместо этого внедрите прикладную логику в код, который отвечает за отображение формы или даже лучше в выделенных модулях и процедурах.

Напишите код таким образом, чтобы UserForm всегда отвечал за знание того, как отображать и собирать данные: откуда поступают данные или что происходит с данными после этого, не является проблемой.


Абонент не должен беспокоиться о контроле.

Создайте хорошо определенную модель для формы, с которой можно работать, либо в своем собственном выделенном модуле класса, либо инкапсулироваться внутри самого кода кода - выставлять модель с процедурами Property Get и работать с этим кодом клиента: это делает форма абстракции над элементами управления и их подробные детали, подвергая только соответствующие данные клиенту.

Это означает, что код выглядит следующим образом:

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

Вместо этого:

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

Обработать событие QueryClose.

Обычно формы имеют кнопку « Закрыть» , а в подсказках / диалоговом окне есть кнопки « ОК» и « Отмена» ; пользователь может закрыть форму, используя блок управления формы (красная кнопка «X»), которая по умолчанию уничтожает экземпляр формы (еще одна веская причина работать с новым экземпляром каждый раз ).

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

Самый простой способ обработать событие QueryClose - установить для параметра Cancel значение True , а затем скрыть форму, а не закрывать ее:

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

Таким образом, кнопка «X» никогда не уничтожит экземпляр, и вызывающий может безопасно получить доступ ко всем открытым членам.


Скрыть, не закрывать.

Код, который создает объект, должен нести ответственность за его уничтожение: ответственность за разгрузку и завершение работы лежит не на форме.

Избегайте использования Unload Me в коде кода. Вызовите Me.Hide вместо этого, чтобы вызывающий код все еще мог использовать объект, который он создал, когда форма закрывается.


Назовите вещи.

Используйте окно свойств ( F4 ) для тщательного определения каждого элемента управления в форме. Имя элемента управления используется в коде, так что, если вы не используете инструмент рефакторинга, который может справиться с этим, переименование элемента управления приведет к поломке кода - так что гораздо проще делать все правильно, в первую очередь, чем пытаться чтобы точно определить, какой из 20 текстовых TextBox12 означает.

Традиционно элементы управления UserForm называются префиксами венгерского стиля:

  • lblUserName для lblUserName управления Label , указывающего имя пользователя.
  • txtUserName для txtUserName управления TextBox где пользователь может ввести имя пользователя.
  • cboUserName для управления ComboBox где пользователь может ввести или выбрать имя пользователя.
  • lstUserName для lstUserName управления ListBox где пользователь может выбрать имя пользователя.
  • btnOk или cmdOk для управления Button с надписью «Ok».

Проблема заключается в том, что когда, например, пользовательский интерфейс изменен и ComboBox изменяется на ListBox , имя необходимо изменить, чтобы отразить новый тип управления: лучше называть элементы управления для того, что они представляют, а не после их типа управления - отделить кода из пользовательского интерфейса, насколько это возможно.

  • UserNameLabel для метки только для чтения, которая указывает имя пользователя.
  • UserNameInput для UserNameInput управления, в котором пользователь может ввести или выбрать имя пользователя.
  • OkButton для командной кнопки с надписью «Ok».

Какой бы стиль ни выбрали, все лучше, чем оставлять все элементы управления по умолчанию. Согласованность в стиле именования тоже идеальна.

Обработка QueryClose

Событие QueryClose возникает всякий раз, когда форма закрывается, независимо от того, выполняется ли это с помощью действия пользователя или программно. Параметр CloseMode содержит VbQueryClose перечисления VbQueryClose которое указывает, как форма была закрыта:

постоянная Описание Значение
vbFormControlMenu Форма закрывается в ответ на действие пользователя 0
vbFormCode Форма закрывается в ответ на оператор Unload 1
vbAppWindows Сеанс Windows завершается 2
vbAppTaskManager Диспетчер задач Windows закрывает приложение-хост 3
vbFormMDIForm Не поддерживается в VBA 4

Для лучшей читаемости лучше использовать эти константы, а не использовать их значение напрямую.


Отмена пользовательской формы

Учитывая форму с кнопкой « Отмена»

какая-то форма образца

Кодировка кода формы может выглядеть так:

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

Затем вызывающий код может отображать форму и знать, была ли она отменена:

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

Свойство IsCancelled возвращает True при нажатии кнопки « Отмена» или когда пользователь закрывает форму с помощью блока управления .



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow