Гость |
Построение диалогов
Содержание |
См. также Экранные формы (Forms).
Диалоги
Диалоги являются абсолютно необходимым средством для повышения управляемости и гибкости макропрограмм.
Они представлены двумя командами: MsgBox (диалог с кнопками) и InputBox (для ввода значений).
Для начинающих программистов этого вполне достаточно.
Синтаксис команд:
MsgBox(prompt[, buttons] [, title] [, helpfile, context])
InputBox(prompt[, title] [, default] [, xpos] [, ypos] [, helpfile, context])
Доступ к этим материалам предоставляется только зарегистрированным пользователям!
InputBox
Диалог предназначен для ввода единичного символьного (строкового) значения. Как видно из основного синтаксиса:
InputBox(prompt[, title] [, default] [, xpos] [, ypos]),
обязательным является только поясняющий текст (prompt).
Появляется возможность указать значение по умолчанию (default), пренебрегать которым не стоит. Ведь во многих случаях оно может быть предсказано и пользователю не придется заниматься утомительным вводом.
Также можно указать в твипсах (1/20 часть пикселя, а не пункта, как принято в полиграфии) координаты окна (xpos, ypos). Если соответствующие координаты опущены, то диалог центрируется относительно горизонтали и опускается примерно на треть экрана по вертикали.
Использовать команду следует в виде функции, так как введенное значение обязано быть присвоено переменной.
Dim x As Single x = InputBox("Введите значение x для подстановки") |
Результат будет выглядеть так:
Если внимательно посмотреть на текст программы, то закономерным будет вопрос: переменной x (числового типа Single) будет передаваться строковое значение, что является ошибочным?
Однако в VBA это будет обработано правильно, если пользователь введет любое число: преобразование пройдет само собой. Если же он введет буквы или нажмёт кнопку отмены (Cancel), то переменной будет присваиваться строковое значение, что породит ошибку:
Избежать подобной ситуации можно двумя способами, предоставляющими различные возможности.
Решение 1
x = Val(InputBox("Введите значение x для подстановки")) |
Здесь сразу происходит преобразование типа возвращаемого значения функцией Val(). В результате при вводе букв они будут:
- преобразованы в 0,
- если в начале строки введены числа ("125xyz"), то строка преобразуется в число (125).
При нажатии на кнопку Cancel будет возвращена пустая строка (""), преобразуемая в 0.
Если такой ввод допустим в принципе, то нет возможности прекратить выполнение программы без дополнительного запроса пользователю.
Решение 2
Dim x As Single, xVal As String xVal = InputBox("Введите значение x для подстановки") If xVal = "" Then Exit Sub x = Val(xVal) |
В данном случае создаётся дополнительная переменная (xVal), в которой хранится результат ввода. Что мы имеем в результате?
- В строке, выделенной красным, проведен анализ результата ввода и выход из программы при пустой строке. Такой подход вполне приемлем и для случая, когда пользователь забыл задать значение. Здесь ему может быть задан вопрос о необходимости прерывания программы.
- Значение, сохраненное в xVal, можно использовать и в дальнейшем. В том числе для детальной разборки или анализа, в том числе на предмет правильности ввода.
- Появляется возможность ввести несколько значений, например, через запятую, которые потом можно анализировать и использовать в соответствии с замыслом программиста.
- Занята дополнительная память, что является платой за функциональность.
InputBox в Excel VBA
К сожалению, объектная модель Word и Excel не совпадают, в связи с чем приходится говорить, что в Excel можно воспользоваться ещё одним способом:
Dim x As Variant x = Application.InputBox(Prompt:="Введите значение x для подстановки", Type:=1) |
В этой ситуации пользователь сможет ввести данные только указанного типа (числового). Если можно вводить несколько типов, то следует задать тип как сумму соответствующих типов: 1+2 (либо сразу 3) — можно вводить цифры и символы.
- Перечень типов:
- 0 = formulas
- 1 = numbers
- 2 = strings
- 4 = logical values
- 8 = cell references
- 16 = error values
- 64 = arrays
MsgBox
Вспомним синтаксис команды:
MsgBox(prompt[, buttons] [, title] [, helpfile, context])
Атрибут buttons представляет собой сумму трех (реже — более) целых чисел, означающих: набор кнопок, картинку, кнопку по умолчанию. Последняя довольно важна, так как многие пользователи невнимательно относятся к надписям в диалоге, и гораздо разумнее активизировать для него ту кнопку, нажатие на которую требуется чаще. Вместо чисел можно использовать системные переменные памяти. Подробная информация приведена в таблице.
Переменная Word | Значение | Описание |
vbOKOnly | 0 | Вывести только кнопку OK |
vbOKCancel | 1 | Вывести кнопки OK и Cancel |
vbAbortRetryIgnore | 2 | Вывести кнопки Abort, Retry и Ignore |
vbYesNoCancel | 3 | Вывести кнопки Yes, No и Cancel |
vbYesNo | 4 | Вывести кнопки Yes и No |
vbRetryCancel | 5 | Вывести кнопки Retry и Cancel |
vbCritical | 16 | Вывести картинку Critical Message |
vbQuestion | 32 | Вывести картинку Warning Query |
vbExclamation | 48 | Вывести картинку Warning Message |
vbInformation | 64 | Вывести картинку Information Message |
vbDefaultButton1 | 0 | По умолчанию активна 1‑я кнопка |
vbDefaultButton2 | 256 | По умолчанию активна 2‑я кнопка |
vbDefaultButton3 | 512 | По умолчанию активна 3‑я кнопка |
vbDefaultButton4 | 768 | По умолчанию активна 4‑я кнопка |
vbApplicationModal | 0 | Диалог модален для Word: для продолжения работы в приложении и самого макроса нужно нажать на одну из кнопок |
vbSystemModal | 4096 | Диалог модален для Windows: все приложения прекращают работу до тех пор, пока пользователь не нажмет на одну из кнопок |
vbMsgBoxHelpButton | 16384 | Добавляет в диалог кнопку Help (Справка) |
VbMsgBoxSetForeground | 65536 | Переводит окно диалога на передний план (практическое применение неизвестно) |
vbMsgBoxRight | 524288 | Надписи выравниваются вправо |
vbMsgBoxRtlReading | 1048576 | Для языков, читаемых справа налево |
Как видно, если не задавать для кнопок ничего, то получится диалог с кнопкой ОК и без пиктограммы. Кстати, он является одним из наиболее часто используемых вариантов для вывода информации о результатах работы программы как в процессе её отладки, так и при обычном режиме работы.
Пример: MsgBox "Значение х достигло " & x
Диалог будет выглядеть так:
Следует отметить, что кнопка ОК обладает интересным свойством: её можно нажать как мышкой, так и клавишами Enter, Space и Esc.
Так как можно вывести диалог с большим разнообразием кнопок, требуется помочь программе разобраться, какая из них была нажата. В этом случае команда запускается в виде функции, возвращающей значение (целое число) переменной в памяти. Далее можно проанализировать его и принять решение о дальнейших действиях
Ниже приведен список значений, возвращаемых функцией MsgBox() в зависимости от нажатой в диалоге кнопки.
Значение | Константа Word | Надпись на кнопке |
1 | vbOK | OK |
2 | vbCancel | Cancel |
3 | vbAbort | Abort |
4 | vbRetry | Retry |
5 | vbIgnore | Ignore |
6 | vbYes | Yes |
7 | vbNo | No |
Пример:
Dim RunMacro As Byte 'Задать целочисленную переменную минимального размера RunMacro = MsgBox("Заменить дефисы в документе?", 4 + 48, "Замена дефисов") 'Запустить диалог с кнопками Yes+No и картинкой "Внимание!" 'Целое число, соответствующее нажатой кнопке, запомнить в RunMacro If RunMacro = 6 Then 'Нажато Yes (вместо 6 можно записать vbYes) Selection.HomeKey Unit:=wdStory 'Перейти на начало документа и продолжить программу после End If Else 'Нажато не Yes (No для нашего примера) Exit Sub 'Выйти из программы, не делая ничего End If ... Основная программа |
Диалог будет выглядеть так:
Можно сказать, что в нем допущена интерфейсная ошибка, так как нажатие клавиши Esc не позволит закрыть диалог. Для комфортности лучше использовать одновременно кнопки Yes, No и Cancel. Для доработки понадобится только заменить в тексте программы 4 на 3: ведь нажатие на Cancel обработается также, как и No (выход из программы).
Обратите внимание! Вместо 4+48, можно было бы записать сразу результат сложения (52). Программа выполнилась бы чуточку быстрее, но редактирование человеком стало бы сложнее. Также можно заменить эту форму сложением программных констант: vbYesNo+vbExclamation, что легче понять при чтении.
Идеальным(?) решением было бы добавление кнопки Cancel, как показано ниже.
RunMacro = MsgBox("Заменить дефисы в документе?", 3 + 48, "Замена дефисов") |
См. также Экранные формы (Forms).