title | keywords | f1_keywords | ms.prod | api_name | ms.assetid | ms.date | ms.localizationpriority |
---|---|---|---|---|---|---|---|
QueryClose event (Visual Basic for Applications) |
vblr6.chm1107501 |
vblr6.chm1107501 |
office |
Office.QueryClose |
8a12c265-bbb8-ed72-8bde-7b9c3bdf86bd |
12/11/2018 |
medium |
Occurs before a UserForm closes.
Syntax
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
The QueryClose event syntax has these parts:
Part | Description |
---|---|
Cancel | An integer. Setting this argument to any value other than 0 stops the QueryClose event in all loaded user forms and prevents the UserForm and application from closing. |
CloseMode | A value or constant indicating the cause of the QueryClose event. |
Return values
The CloseMode argument returns the following values:
Constant | Value | Description |
---|---|---|
vbFormControlMenu | 0 | The user has chosen the Close command from the Control menu on the UserForm. |
vbFormCode | 1 | The Unload statement is invoked from code. |
vbAppWindows | 2 | The current Windows operating environment session is ending. |
vbAppTaskManager | 3 | The Windows Task Manager is closing the application. |
These constants are listed in the Visual Basic for Applications object library in the Object Browser. Note that vbFormMDIForm is also specified in the Object Browser, but is not yet supported.
Remarks
This event is typically used to make sure there are no unfinished tasks in the user forms included in an application before that application closes. For example, if a user hasn’t saved new data in any UserForm, the application can prompt the user to save the data.
When an application closes, you can use the QueryClose event procedure to set the Cancel property to True, stopping the closing process.
Example
The following code forces the user to click the UserForm client area to close it. If the user tries to use the Close box in the title bar, the Cancel parameter is set to a nonzero value, preventing termination. However, if the user has clicked the client area, CloseMode has the value 1 and Unload Me
is executed.
Private Sub UserForm_Activate() Me.Caption = "You must Click me to kill me!" End Sub Private Sub UserForm_Click() Unload Me End Sub Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer) 'Prevent user from closing with the Close box in the title bar. If CloseMode <> 1 Then Cancel = 1 Me.Caption = "The Close box won't work! Click me!" End Sub
See also
- Events (Visual Basic Add-In Model)
- Events (Visual Basic for Applications)
[!includeSupport and feedback]
Лучшие практики
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
при нажатии кнопки « Отмена» или когда пользователь закрывает форму с помощью блока управления .
Сообщение от Maxsss
то при загрузке этого файла загружается и переменная типа Boolean с значением False , отвечающая за запрет/разрешение закрытия всех открытых форМ.
Аналогично грузиться и переменная (с пустым значением) CloseMode.
Не совсем так.
Excel, конечно, имеет свои внутренние системные переменные, как и любая программа, которые хранятся в оперативной памяти, но напрямую доступа к ним Вы не имеете, да и не должны иметь.
Когда
Сообщение от Maxsss
подключена библиотека Microsoft Forms 2.0 Object Lidrary
в коде Вашей программы с переменными Cancel и CloseMode ничего не происходит до момента, пока Вы не объявите событие и не назначите ему обработчик.
Кроме того, область видимости этих переменных (относительно Вашей программы) находится только в пределах обработчика.
Это значит, что после выхода из него (End Sub), переменные очищаются.
Стоит отметить, что в других процедурах переменные могут иметь точно такие же имена, но будучи объявленными внутри процедур (т.н. локальные), они не имеют никакого влияния на переменные обработчика события.
Касательно происхождения и работы с переменными внутри обработчика:
Они имеют задекларированный тип данных, расположение, кол-во, определенное
для каждого из событий его прототипом.
Как передаются и возращаются данные из обработчика события можно наглядно увидеть в коде, который выкладывал аналитика:
Добавление событий в класс
(создание пользовательских событий)
Уверен, для Вас это разобрать будет сложно.
Итак, в обработчике можно манипулировать:
1) именем переменной;
2) присваивать переменной новое значение;
3) опускать объявление переменной, если это предусмотрено.
События работают совершенно по-другому, чем обычные функции и подпрограммы.
Поясню на примере, загрузки и выгрузки формы.
В основном, события формы по ее инициализации и деинициализации разворачиваются в таком порядке:
- Initialize
- Load
- Activate
- Deactivate
- QueryUnload
- Unload
- Terminate
http://www.firststeps.ru/vba/excel/r.php?51
http://www.firststeps.ru/vba/excel/r.php?54
События происходят всегда, несмотря на то назначен ли им обработчик или нет.
Каждая переменная может быть передана, как значением (byval — тогда в обработчике создается ее копия), так и указателем (byref — тогда область видимости этой переменной распространяется на обработчик (грубо говоря).
По, умолчанию (если byref опущен), используется передача по указателю.
Этот модификатор Вы не увидите, т.к. он задан прототипом события, заданном в «системном» коде Excel-я. Поэтому нужно смотреть его описание в MSDN.
Так, к примеру в обработчик события «QueryUnload» переменная Cancel передана как byref, а CloseMode могла быть передана, и по ссылке и по значению.
Это значит, что все действия, которые выполняются с переменной Cancel внутри обработчика события, «передаются» в системную функцию, откуда инициировано это событие.
Сообщение от Maxsss
зачем аргумент Cancel в процедуре объявляют как число, а не как булево?
Вероятно, разработчикам было удобнее далее по тексту программы использовать именно тип Integer. В любом случае, если Вам удобно, можете задавать True или False. False — это 0, а True — это -1. Все, что не 0 — это True. А поэтому 1 — это тоже True (только обычно возвращаемое API-функциями).
Форма в VBA это каркас приложения. Как добавлять форму в Ваш проект смотрите «Шаг 15 — Пользовательские формы». В основном события формы по ее инициализации и деинициализации разворачиваются в таком порядке:
Initialize Load Activate Deactivate QueryUnload Unload Terminate
Но форма в VBA и VB различаются. Давайте сравним:
VBA | VB |
---|---|
UserForm_Initialize() | Form_Initialize() |
Нет | Form_Load() |
UserForm_Activate() | Form_Activate() |
UserForm_Deactivate() | Form_Deactivate() |
UserForm_QueryClose(Cancel As Integer,CloseMode As Integer) | Form_QueryUnload(Cancel As Integer, UnloadMode As Integer) |
нет | Form_Unload(Cancel As Integer) |
UserForm_Terminate() | Form_Terminate() |
Получается, что событие Load и Unload в VBA не обрабатываются.
Событие Initialize
Событие Initialize (Инициализация) обычно используется для подготовки к работе приложения или формы UserForm. Переменным присваиваются исходные значения, а положение или размеры элементов управления могут быть изменены для согласования с данными, заданными при инициализации. Это событие появляется до загрузки формы и ее отображения. Это событие появляется во время загрузки формы. Давайте в него напишем код:
Private Sub UserForm_Initialize() MsgBox "UserForm_Initialize" End Sub
А теперь две функции, которые вызывают Load:
Sub Test() Load UserForm1 Call Test2 End Sub Sub Test2() Unload UserForm1 Load UserForm1 End Sub
В результате окно с информацией о инициализации будет на экране два раза. Так же это событие сгенерирует событие Show, так как первый раз для работы с формой ее нужно загрузить. Еще это событие может быть вызвано, если в форме определена функция общего назначения. Вызов этой функции опять приводит к загрузке формы.
Private Sub UserForm_Terminate() End Sub Public Sub MyMessage() MsgBox "MyMessage" End Sub
А вот так можно вызвать:
Sub Test() UserForm1.MyMessage End Sub
Итак, событие Intialize вызывается только один раз для формы перед ее загрузкой.
Событие Load
Нет ее в VBA, а вообще в VB здесь можно что-то сделать перед выводом формы на экран.
Событие Activate и Deactivate
Событие Activate происходит, когда объект становится активным окном. А становится активным окном он может в двух случаях. Это в результате Show, когда форма становится видимой на экране и в результате получения фокуса. Событие Deactivate (Деактивизация) происходит, когда объект более не является активным окном. Эти события генерируются только при переключении между окнами одного приложения. Если вы перейдете в другую программу и вернетесь в Excel, то эти события не будут сгенерированы.
Событие QueryClose
Это событие генерируется для того, чтобы получить у пользователя разрешение на закрытие формы. В зависимости от кода возврата форма закрывается или нет.
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer) If CloseMode <> 1 Then Cancel = 1 UserForm1.Caption = "Close не будет работать. Выберите меня!" End IF End Sub
Событие Unload
Нет его, точно так же как и Load, а вообще используется, если надо что-либо делать при выгрузке формы, например сохранить настройки пользователя.
Событие Terminate
Данное событие происходит, когда все ссылки на экземпляр объекта удаляются из памяти с помощью присвоения всем переменным, которые ссылаются на данный объект, состояния Nothing или когда последняя ссылка на объект выходит за пределы области определения. Это событие идет вслед за Unload.
Содержание
- QueryClose event
- Syntax
- Return values
- Remarks
- Example
- See also
- Support and feedback
- Событие QueryClose
- Синтаксис
- Возвращаемые значения
- Замечания
- Пример
- См. также
- Поддержка и обратная связь
- VBA Пользовательские формы
- Лучшие практики
- Работайте с новым экземпляром каждый раз.
- Реализуйте логику в другом месте.
- Абонент не должен беспокоиться о контроле.
- Обработать событие QueryClose.
- Скрыть, не закрывать.
- Назовите вещи.
- Обработка QueryClose
- Отмена пользовательской формы
- How to close VBA UserForm: Hide vs Unload
- Basic VBA code
- Display a UserForm
- Hide a UserForm
- Unload a UserForm
- Close button
- Assigning the Esc key
- Hide vs Unload
- Unload
- Preloading the UserForm
- How to close using the X button
- How did the user close the form?
QueryClose event
Occurs before a UserForm closes.
Syntax
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
The QueryClose event syntax has these parts:
Part | Description |
---|---|
Cancel | An integer. Setting this argument to any value other than 0 stops the QueryClose event in all loaded user forms and prevents the UserForm and application from closing. |
CloseMode | A value or constant indicating the cause of the QueryClose event. |
Return values
The CloseMode argument returns the following values:
Constant | Value | Description |
---|---|---|
vbFormControlMenu | 0 | The user has chosen the Close command from the Control menu on the UserForm. |
vbFormCode | 1 | The Unload statement is invoked from code. |
vbAppWindows | 2 | The current Windows operating environment session is ending. |
vbAppTaskManager | 3 | The Windows Task Manager is closing the application. |
These constants are listed in the Visual Basic for Applications object library in the Object Browser. Note that vbFormMDIForm is also specified in the Object Browser, but is not yet supported.
This event is typically used to make sure there are no unfinished tasks in the user forms included in an application before that application closes. For example, if a user hasn’t saved new data in any UserForm, the application can prompt the user to save the data.
When an application closes, you can use the QueryClose event procedure to set the Cancel property to True, stopping the closing process.
Example
The following code forces the user to click the UserForm client area to close it. If the user tries to use the Close box in the title bar, the Cancel parameter is set to a nonzero value, preventing termination. However, if the user has clicked the client area, CloseMode has the value 1 and Unload Me is executed.
See also
Support and feedback
Have questions or feedback about Office VBA or this documentation? Please see Office VBA support and feedback for guidance about the ways you can receive support and provide feedback.
Источник
Событие QueryClose
Происходит до закрытия UserForm .
Синтаксис
Частный вложенный UserForm_QueryClose(Cancelas Integer, CloseModeas Integer)
Синтаксис события QueryClose содержит следующие элементы:
Part | Описание |
---|---|
Отмена | Параметр SyncSchedule указывает . Допустимые значения этого параметра: Установка для этого аргумента любого значения, отличного от 0, останавливает событие QueryClose во всех загруженных пользовательских формах и предотвращает закрытие UserForm и приложения. |
CloseMode | Значение или константы , указывающие причину события QueryClose . |
Возвращаемые значения
Аргумент CloseMode возвращает следующие значения:
Константа | Значение | Описание |
---|---|---|
vbFormControlMenu | 0 | Пользователь выбрал команду Close (Закрыть) в меню элементов управления Control для UserForm. |
vbFormCode | 1 | Оператор Unload (Загрузить) вызывается из кода. |
vbAppWindows | 2 | Текущий сеанс операционной среды Windows подходит к концу. |
vbAppTaskManager | 3 | Окно Диспетчер задач закрывается в приложении. |
Эти константы перечислены в библиотеке объектов Visual Basic для приложений в браузере объектов Object Browser. Обратите внимание, что vbFormMDIForm также указывается в Object Browser, но еще не поддерживается.
Замечания
Это событие обычно используется, чтобы убедиться, что в пользовательских формах нет незавершенных задач, добавленных в приложение перед его закрытием. Например, если пользователь не сохранил новые данные ни в одной из форм UserForm, приложение предложит пользователю сохранить данные.
При закрытии приложения можно использовать процедуру события QueryClose для задания свойству Cancel (Отмена) значения истины True, прекращая процесс закрытия.
Пример
Следующий код заставляет пользователя щелкнуть область клиента UserForm , чтобы закрыть ее. Если пользователь пытается использовать поле Close (Закрыть) в строке заголовка, параметр Cancel, имеющий ненулевое значение, предотвращает закрытие. Однако если пользователь щелкнул клиентную область, CloseMode имеет значение 1 и Unload Me выполняется.
См. также
Поддержка и обратная связь
Есть вопросы или отзывы, касающиеся Office VBA или этой статьи? Руководство по другим способам получения поддержки и отправки отзывов см. в статье Поддержка Office VBA и обратная связь.
Источник
VBA
Пользовательские формы
Лучшие практики
UserForm — это модуль класса с дизайнером и экземпляром по умолчанию . Доступ к дизайнеру можно получить, нажав Shift + F7 при просмотре кода , а доступ к коду можно получить, нажав F7 во время просмотра дизайнера .
Работайте с новым экземпляром каждый раз.
Будучи модулем класса , форма является, таким образом, планом для объекта . Поскольку форма может содержать состояние и данные, лучше работать с новым экземпляром класса, а не с по умолчанию / глобальным:
Работа с экземпляром по умолчанию может привести к тонким ошибкам, когда форма закрыта красной кнопкой «X» и / или когда Unload Me используется в коде.
Реализуйте логику в другом месте.
Форма должна касаться только презентации : кнопка Click handler, которая подключается к базе данных и запускает параметризованный запрос на основе ввода пользователем, делает слишком много вещей .
Вместо этого внедрите прикладную логику в код, который отвечает за отображение формы или даже лучше в выделенных модулях и процедурах.
Напишите код таким образом, чтобы UserForm всегда отвечал за знание того, как отображать и собирать данные: откуда поступают данные или что происходит с данными после этого, не является проблемой.
Абонент не должен беспокоиться о контроле.
Создайте хорошо определенную модель для формы, с которой можно работать, либо в своем собственном выделенном модуле класса, либо инкапсулироваться внутри самого кода кода — выставлять модель с процедурами Property Get и работать с этим кодом клиента: это делает форма абстракции над элементами управления и их подробные детали, подвергая только соответствующие данные клиенту.
Это означает, что код выглядит следующим образом:
Обработать событие QueryClose.
Обычно формы имеют кнопку « Закрыть» , а в подсказках / диалоговом окне есть кнопки « ОК» и « Отмена» ; пользователь может закрыть форму, используя блок управления формы (красная кнопка «X»), которая по умолчанию уничтожает экземпляр формы (еще одна веская причина работать с новым экземпляром каждый раз ).
Самый простой способ обработать событие QueryClose — установить для параметра Cancel значение True , а затем скрыть форму, а не закрывать ее:
Таким образом, кнопка «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 |
Для лучшей читаемости лучше использовать эти константы, а не использовать их значение напрямую.
Отмена пользовательской формы
Учитывая форму с кнопкой « Отмена»
Кодировка кода формы может выглядеть так:
Затем вызывающий код может отображать форму и знать, была ли она отменена:
Свойство IsCancelled возвращает True при нажатии кнопки « Отмена» или когда пользователь закрывает форму с помощью блока управления .
Источник
How to close VBA UserForm: Hide vs Unload
VBA UserForms are a key tool for managing user interactions. When UserForms are well designed, they guide users through the options and settings without any help file or guidance. However, from my own UserForm development, I know one of the most overlooked aspects is how to close VBA UserForms. Is it best to hide or unload the form? Does it matter either way?
This post covers key considerations to ensure the closure process achieves the desired outcome.
Download the example file: Click the link below to download the example file used for this post:
Basic VBA code
To start, let’s look at the basic VBA code for opening and closing UserForms. In this post, the UserForm is called myUserForm, which looks like this.
The UserForm has three elements:
- Text box: named txtTextBox
- Hide button: named cmdHide
- Unload button: named cmdUnload
Display a UserForm
The code to display a UserForm is usually stored outside of the UserForm in a standard module. The following code displays a UserForm.
Hide a UserForm
To hide a UserForm using a button, the code may be contained within the UserForm itself, or in a separate module.
Code contained within the UserForm
The code below shows an example where the code is contained within the UserForm. Me. refers to the UserForm object.
Code contained within a standard code module
Where the code is contained within another module, we must refer to the name of the UserForm, as shown by the code below.
When using the hide code outside of the UserForm, we need to call the code from the button.
Unload a UserForm
Another way to close a UserForm is to unload it. Like the examples above, the code can be referenced from within or outside the UserForm code module.
Code contained within the UserForm
The code is an example where the code is contained within the UserForm.
Code contained within a standard code module
The example below is where the code is contained within a standard code module
When using the unhide code outside of the UserForm, we need to call the code from the UserForm.
Close button
The simplest option to close a UserForm is the standard [X] close button. It is convenient because it is always at the top of the window where the user expects it. By default, it doesn’t require any code to work as it’s part of the Windows framework.
The close button is equivalent to the unload method to close the VBA UserFrom.
Assigning the Esc key
The Esc key is commonly used within interface design to close a window. We can use this on our UserForm too, though the option to apply the setting is in a strange place.
Select a button on the UserForm and set the Cancel property to True.
When the UserForm is displayed, pressing the Esc key triggers the button with the Cancel property. Therefore, the Esc key can be assigned to a button with hide or unload.
Hide vs Unload
As there is an option to hide or unload, which should we choose? Does it matter? YES, it definitely does matter.
The two options differ in their approach; they achieve slightly different things.
Unload
Unload closes the form completely; it no longer exists in memory. It will be as if the initialize event had never triggered, so if we refer to any of the objects on the UserForm, they will have no value.
Hide makes a UserForm invisible. It is still there; we just can’t see it. As it still exists, we can still reference objects on the form to retrieve their values.
For example, if there is text in a text box, we can obtain that value after the form has closed. The code below displays a message box with the text from the UserForm.
Note: As the form remains open, it continues to hold the memory.
Preloading the UserForm
What if we want to reference an object on a UserForm before we display it? The initialize event has not been executed, and the form does not exist in memory. To get around this issue, we use the load command to create the UserForm, but not display it.
By using this method, the initialize event triggers, but not the activate event. The activate event only triggers only when the UserForm is displayed.
To guarantee the UserForm is always in memory, load the form during the workbook open event.
How to close using the X button
By default, the [X] close button unloads the UserForm. Which is a problem if we want to hide it. But we can hijack the [X] button control to achieve the same as the hide command.
The UserForm has an event called QueryClose. Using this event, we can cancel the unload action, then hide the UserForm.
Enter the following code in the UserFrom code module
Once we’ve canceled the unload action, we can now refer to the elements on the UserForm, just like the normal hide.
How did the user close the form?
As there are multiple ways to close a UserForm, it may be helpful to know which option the user selected. For example, did they click “OK” or “Cancel”?
In this situation, an easy option is to use a public variable. We can assign the value to the variable as part of the close procedure.
The public variable can then be accessed by any module.
Related Posts:
About the author
Hey, I’m Mark, and I run Excel Off The Grid.
My parents tell me that at the age of 7 I declared I was going to become a qualified accountant. I was either psychic or had no imagination, as that is exactly what happened. However, it wasn’t until I was 35 that my journey really began.
In 2015, I started a new job, for which I was regularly working after 10pm. As a result, I rarely saw my children during the week. So, I started searching for the secrets to automating Excel. I discovered that by building a small number of simple tools, I could combine them together in different ways to automate nearly all my regular tasks. This meant I could work less hours (and I got pay raises!). Today, I teach these techniques to other professionals in our training program so they too can spend less time at work (and more time with their children and doing the things they love).
Do you need help adapting this post to your needs?
I’m guessing the examples in this post don’t exactly match your situation. We all use Excel differently, so it’s impossible to write a post that will meet everybody’s needs. By taking the time to understand the techniques and principles in this post (and elsewhere on this site), you should be able to adapt it to your needs.
But, if you’re still struggling you should:
- Read other blogs, or watch YouTube videos on the same topic. You will benefit much more by discovering your own solutions.
- Ask the ‘Excel Ninja’ in your office. It’s amazing what things other people know.
- Ask a question in a forum like Mr Excel, or the Microsoft Answers Community. Remember, the people on these forums are generally giving their time for free. So take care to craft your question, make sure it’s clear and concise. List all the things you’ve tried, and provide screenshots, code segments and example workbooks.
- Use Excel Rescue, who are my consultancy partner. They help by providing solutions to smaller Excel problems.
What next?
Don’t go yet, there is plenty more to learn on Excel Off The Grid. Check out the latest posts:
Источник