Проектирование интерфейса. Диалоговые окна
Проверка корректности данных
Одна из важных функций диалоговых окон, - прием и передача данных, введенных пользователем, для хранения и дальнейшей обработки в систему. Основной вид элементов управления, предназначенных для ввода, - это окна редактирования (TextBox). Для предотвращения ошибок, связанных с неверным типом введенных данных или нарушением некоторых условий, которым эти данные должны удовлетворять следует проверять их корректность до выхода из диалогового окна. Чуть выше мы приводили пример работы с простой формой ввода, где проверялась ситуация, когда пользователь "забыл" ввести данные в окно ввода. Сейчас мы рассмотрим ситуацию, в которой пользователь пытается ввести некорректные данные в поле ввода. Возникает вопрос, где следует проводить проверку на корректность данных? По-видимому, одним из лучших мест является обработчик события Exit, которым обладает элемент управления TextBox. Обработчик этого события вызывается при попытке выхода из окна редактирования. Здесь и следует проводить проверку введенных данных, чтобы не допустить выхода, если данные заданы некорректно.
Продолжим работу с простой формой ввода и предположим, что в поле ввода следует ввести температуру больного человека, значение, которой, естественно, ограничено сверху и снизу. Вот как выглядит обработчик события Exit:
Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean) Dim Msg As String Const MinTemp = 34 Const MaxTemp = 42 Msg = "Ошибка ввода:" & vbCrLf 'Проверка, являются ли данные числовыми If Not IsNumeric(TextBox1.Text) Then Msg = Msg & "Введите числовые данные в формате: ##.#" MsgBox Msg Cancel = True 'Оставляет фокус в поле ввода ElseIf TextBox1.Text < MinTemp Then Msg = Msg & "Температура слишком низкая" & vbCrLf _ & "Проверьте, что с Вашим больным!" MsgBox Msg Cancel = True 'Оставляет фокус в поле ввода ElseIf TextBox1.Text > MaxTemp Then Msg = Msg & "Температура слишком высокая" & vbCrLf _ & "Проверьте, что с Вашим больным!" MsgBox Msg Cancel = True 'Оставляет фокус в поле ввода Else GlobeVar = TextBox1.Text Debug.Print GlobeVar End If End Sub12.2.
Событие Exit имеет параметр Cancel, значение которого следует установить в обработчике события. Если параметру присвоить значение True, то фокус остается на текущем элементе, в противном случае он переходит к элементу, следующему согласно Tab - порядка. Вот как выглядит форма при попытке задания некорректного значения температуры:
Обмен данными с диалоговым окном
Диалоговые окна служат для обмена информацией между пользователем и документом. При открытии формы с заранее спроектированными свойствами элементов управления и после ее инициализации пользователь попадает в мир ее объектов. В этом мире он может выполнять разные действия, вводя требуемые данные, выбирая нужные ему опции и щелкая те или иные командные кнопки. В ответ на изменения, совершаемые пользователем, могут вызываться обработчики событий, которые в свою очередь производят изменения свойств объектов, как самой формы, так и объектов документа. Во многих случаях, изменения, сделанные в результате взаимодействия должны быть сохранены перед тем, как форма будет закрыта, с тем, чтобы их можно было восстановить при последующих открытиях формы. Для этого можно использовать рабочую память самого приложения (ячейки рабочих листов в Excel, записи БД в Access, текст документа в Word), внешние дисковые файлы или переменные уровня модуля.
Приведем сейчас пример уже знакомой нам формы, дополненной командными кнопками Save и Reset, обработчики события Click которых позволяют сохранить текущее состояние элементов управления и восстановить его в нужный момент. Для хранения информации используется память документа Excel. Вот как выглядит лист Excel, в ячейках которого хранятся данные о состоянии формы:
Пять ячеек листа SavedData рабочей книги BookOne12 хранят нужную информацию. Заметьте, ячейка A1 именована. Ее имя "Данные" будет использовано в обработчиках событий. На этом же листе расположена командная кнопка "Вызов Формы". Ее обработчик события очень прост, ѕ он вызывает форму:
Private Sub CommandButton1_Click() frmInit.Show End Sub
А вот как выглядит сама форма в момент ее открытия:
Эта форма уже использовалась в наших примерах. Ранее она была связана с документом Word, а теперь мы перетащили ее в рабочую книгу Excel, используя операции Export - Import. После чего форма была слегка модифицирована добавлением в нее новых командных кнопок ѕ Save, Reset и Cancel. Прежде, чем рассказать о них подробнее, приведем уже встречавшиеся обработчики событий. Наша форма одинаково реагирует на два события Initialize и Activate. Первое из них возникает, когда форма открывается после того, как она была выгружена. Если же форма удаляется с экрана методом Hide, то при ее повторном открытии событие Initialize не возникает. Поскольку мы хотим, чтобы и в этом случае происходила инициализация свойств формы, то определен и обработчик события Activate, выполняющий те же действия. Поскольку оба обработчика эквивалентны, то приведем текст только одного из них:
Private Sub UserForm_Activate() With frmInit .Caption = "Окно после инициализации" ' заголовок диалогового окна .CurrDate.Caption = "Сегодня " & Format(Date, "dd/mm/yy") 'метка - текущая дата .MyText.Text = "Любимый цвет:" 'начальный текст в редакторе .chkGood.Value = True 'включение флажка .chkGood.Caption = " Хороший день" ' заголовок флажка With.lstColors 'задание элементов списка: .AddItem "белый" .AddItem "черный" .AddItem "синий" .AddItem "красный" .AddItem "зеленый" .AddItem "желтый" .AddItem "голубой" .ListIndex = 4 'выбор 5-го элемента в списке ("зеленый") End With End With End Sub
Этот обработчик задает начальные свойства элементов управления ѕ объектов формы в момент ее открытия. После чего с формой работает пользователь. Форма простая, поэтому возможностей у него не много, тем не менее, он может выбрать из списка понравившийся ему цвет, отключить флажок, щелкнуть по командной кнопке "Change". В ответ на последнее действие будет вызван соответствующий обработчик, который программно изменит состояние объектов формы. Текст этого обработчика уже приводился ранее, напомним его:
Private Sub CommandButton1_Click() ChangeForm End Sub Public Sub ChangeForm() With Me .MyText.Text = "Нелюбимый цвет:" 'новый текст .lstColors.ListIndex = 1 'черный .chkGood.Value = False 'отключение флажка End With End Sub
Нам осталось рассмотреть действие новых командных кнопок. Обработчик события Click кнопки Save позволяет сохранить текущее состояние элементов управления формы. Затем это состояние может быть проанализировано, например, для того, чтобы выдать психологический портрет пользователя. Цель сохранения может быть и другая, ѕ иметь возможность вернуться к текущему состоянию при повторном открытии формы. С чисто программистской точки зрения задача сохранения состояния решается просто, главный вопрос это, где и в какой форме хранить состояние элементов управления. В данном случае мы выбрали ячейки листа Excel. Вот текст этого обработчика:
Private Sub cmdSave_Click() 'Сохранение данных формы в ячейках листа SavedData книги BookOne12 Dim Beg As Range Set Beg = Range("[BookOne12.xls]SavedData!Данные") With frmInit Beg.Offset(1, 0) =.CurrDate.Caption 'дата Beg.Offset(1, 1) =.lstColors.ListIndex 'индекс в списке Beg.Offset(1, 2) =.lstColors.Value 'цвет Beg.Offset(1, 3) =.chkGood.Value 'состояние флажка Beg.Offset(1, 4) =.MyText.Text 'текст в окне ввода 'Форма прячется .Hide End With End Sub
Обратите внимание, при работе с ячейками Excel используется техника, основанная на смещении Offset. Вначале фиксируется начальная ячейка, имеющая имя "Данные", и уже относительно ее выполняются действия над остальными ячейками.
Командная кнопка Reset позволяет восстановить сохраненное состояние элементов управления формы. Обработчик события Click для этой кнопки выполняет действия, обратные тем, что делаются при сохранении состояния. Вот текст этого обработчика:
Private Sub cmdReset_Click() 'Восстановление данных формы из ячеек листа SavedData книги BookOne12 Dim Beg As Range Set Beg = Range("[BookOne12.xls]SavedData!Данные") With frmInit .CurrDate.Caption = Beg.Offset(1, 0) .lstColors.ListIndex = Beg.Offset(1, 1) .lstColors.Value = Beg.Offset(1, 2) .chkGood.Value = Beg.Offset(1, 3) .MyText.Text = Beg.Offset(1, 4) End With End Sub
Обработчик события Click для кнопки Cancel просто закрывает форму без сохранения состояния элементов:
Private Sub cmdCancel_Click() frmInit.Hide End Sub
Закрытие диалогового окна
Диалоговые окна в Office 2000 всегда работают в режиме модального диалога. Это значит, что пользователь должен полностью завершить работу в окне и закрыть его, прежде чем сможет перейти к действиям, не связанным с работой в этом диалоговом окне. Заметим, что немодальный диалог в Office 2000 также можно организовать, но для этого потребуется использовать объект Assistant с его баллончиками ѕ объектами Balloon. Для завершения работы с диалоговым окном применяется оператор UnLoad или метод Hide, вызываемые в обработчиках события, завершающих работу в диалоговом окне. Обычно в диалоговое окно включается одна или несколько кнопок, выбор которых приводит к завершению работы в нем ("Отказ", "Выход", "Сохранить", "Готово", "Конец работы" и т. п.).
Ранее мы уже говорили о разнице между UnLoad и Hide, первый ѕ выгружает форму, второй только прячет ее. Есть и синтаксическая разница, Hide - это метод формы, в то время как UnLoad и Load - это встроенные функции, которым в качестве параметра передается имя формы. Мы обращали также внимание и на то, что при открытии спрятанной формы не возникает событие Initialize. В заключение, скажем, что в Office 97 были проблемы с методом Hide, поэтому я всегда пользовался только методом UnLoad, в Office 2000 метод Hide работает должным образом.