Ранее я рассмотрел методы создания пользовательских форм и основы работы с ними (если вы никогда не работали с пользовательскими формами, рекомендую для начала прочитать указанную заметку). Далее привел целый ряд практически полезных примеров пользовательских диалоговых окон. Большинство диалоговых окон, о которых речь шла в этих заметках, модальные, т.е. их необходимо удалять с экрана, прежде чем приступать к работе с окном приложения, находящимся под этим окном. Некоторые же диалоговые окна являются немодальными. Это означает, что пользователь может продолжать работу в приложении, даже когда диалоговое окно отображено на экране.[1]
Рис. 1. Немодальное диалоговое окно остается видимым, даже если пользователь продолжает работать с электронной таблицей (см. также файл modeless userform1.xlsm)
Скачать заметку в формате Word или pdf, примеры в архиве
Для отображения немодального окна UserForm воспользуйтесь следующим оператором:
UserForml.Show vbModeless
Слово vbModeless является встроенной константой, которая имеет значение 0. Таким образом, представленный ниже оператор будет идентичен предыдущему.
UserForml.Show 0
На рис. 1 показано немодальное диалоговое окно, которое отображает информацию об активной ячейке. Если диалоговое окно представлено на экране, пользователь может продолжать работу с ячейками, перемещаться на другие листы, а также выполнять другие действия, поддерживаемые в Excel.
Важным моментом в использовании немодального диалогового окна является определение времени, когда необходимо обновить его содержимое. С этой целью в нашем примере используются два события рабочей книги: SheetSelectionChange и SheetActivate. Процедуры обработки этих событий находятся в модуле кода объекта ThisWorkbook.
1 2 3 4 5 6 7 8 |
Private Sub Workbook_SheetSelectionChange _ (ByVal Sh As Object, ByVal Target As Range) Call UpdateBox End Sub Private Sub Workbook_SheetActivate(ByVal Sh As Object) Call UpdateBox End Sub |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
Sub UpdateBox() With UserForm1 ' Проверка активности рабочего листа If TypeName(ActiveSheet) <> "Worksheet" Then .lblFormula.Caption = "Н/Д" .lblNumFormat.Caption = "Н/Д" .lblLocked.Caption = "Н/Д" Exit Sub End If .Caption = "Ячейка: " & ActiveCell.Address(False, False) ' Формула If ActiveCell.HasFormula Then .lblFormula.Caption = ActiveCell.Formula Else .lblFormula.Caption = "(none)" End If ' Числовой формат .lblNumFormat.Caption = ActiveCell.NumberFormat ' Locked .lblLocked.Caption = ActiveCell.Locked End With End Sub |
Чтобы посмотреть, как работает процедура покликайте на разных листах и ячейках.
Более сложный пример
На рис. 2 показан более сложный пример. Данная версия отображает достаточно много дополнительной информации о выделенной ячейке. Пользователи, которые давно работают с Excel, могут заметить, что это диалоговое окно напоминает диалоговое окно Инфо (оно было удалено из Excel несколько лет назад).
Рис. 2. В этом немодальном окне UserForm отображаются сведения об активной ячейке; чтобы увеличить изображение кликните на нем правой кнопкой мыши и выберите Открыть картинку в новой вкладке
Код VBA этого примера можно найти в файле modeless userform2.xlsm. Обратите внимание на следующее:
- Диалоговое окно UserForm содержит флажок Автоматическое обновление. Если этот флажок установлен, диалоговое окно обновляется автоматически. Если же он не установлен, для обновления информации нужно щелкнуть мышью на кнопке Обновить.
- Рабочая книга использует модуль класса с целью обнаружения двух событий для всех открытых рабочих книг: SheetSelectionChange и SheetActivate. В результате код, отображающий информацию о текущей ячейке, выполняется автоматически независимо от того, в какой рабочей книге происходят события (предполагается, что установлен флажок Автоматическое обновление). Некоторые действия (например, изменение числового формата ячейки) не приводят к вызову какого-либо из описанных событий. Поэтому диалоговое окно UserForm также содержит кнопку Обновить.
- Счетчики зависящих ячеек и ячеек, от которых зависит текущая, отображают данные только для активного листа. Это ограничение свойств Precedents и Dependents.
- Так как длина отображаемой информации может изменяться, код VBA изменяет размер и расстояние между элементами управления Label, а также размер самого диалогового окна UserForm в соответствии с длиной отображаемой информации.
[1] По материалам книги Джон Уокенбах. Excel 2010. Профессиональное программирование на VBA. – М: Диалектика, 2013. – С. 474–477.