Построение экранных форм (Forms)

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

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

К сожалению, использование форм достаточно сложно и не входит в основной курс изучения и будет обсуждаться только с профильной группой.

Создание формы

Форма должна быть сохранена в каком-либо проекте (project): шаблоне или документе.

Перейдем в окно VBE нажатием горячей клавиши Alt+F11. Сразу акцентирую ваше внимание на том, что редактор написан на английском языке, хотя используется русская версия Word!

Щелчком правой клавишей мыши в любом месте перечня объектов проекта (выберем текущий документ) в окне Project Explorer (в левом верхнем углу) вызовем контекстное меню, через которое и происходит добавление формы.

Будет создана категория Forms, в которой разместится новая форма, получающая название по умолчанию UserForm1. Появится инструментальная панель Toolbox, содержащая элементы управления для вставки в форму.

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

Щелкнем на ней правой кнопкой мыши и выберем пункт контекстного меню Properties (Свойства), в результате чего откроется окно под списком проектов.

Всего свойств 34, но обсуждаться они пока будут только по необходимости.

Естественно, что имя нужно изменить в соответствии с назначением (осмысленное). В противном случае неизбежной станет путаница, с которой очень тяжело работать. Так как у нас учебный пример, назовем ее Test1 через первую строку (Name) и изменим заголовок (Caption) на «Тестовая форма».

Последоватерьно создадим по две радиокнопки (переключателя) и обычных кнопки, разместим их. По умолчанию, все объекты выравниваются по сетке в соответствии с настройками, но дополнительно можно сдвинуть их на 1 пиксел стрелками управления курсором.

Так как радиокнопки занимают фиксированное и явно избыточное место, сменим для них свойство AutoSize с False на True. Теперь они будут автоматически соответствовать размеру текста подписи по ширине.

Изменение кегля возможно через свойство Font, активация которого приводит к появлению кнопки открытия диалога.

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

Для изменения надписей нужно щелкнуть второй раз (НЕ двойной щелчок) по активному объекту и отредактировать. Либо изменить свойство Caption, как мы это сделали для заголовка формы.

Дополнительно изменим на True свойство Default у кнопки OK и Cancel у кнопки Cancel. Теперь Enter будет нажимать первую, а Esc — вторую.

Форма внешне готова, хотя немного кургуза и неработоспособна. Запустить ее можно клавишей F5, но закрывать придется крестиком.

В глаза бросается отсутствие выбранных вариантов. Если вы хотите предложить пользователю готовый выбор, то для нужной кнопки придется вручную изменить свойство Value на True.

Разберем дальнейшие действия на примере кнопки OK.

Двойной щелчок по ней откроет редактор и, если это не было сделано ранее, создаст пустую подпрограмму:

	Private Sub CommandButton1_Click()

	End Sub

Разберем подробно все элементы, так как именно на них основано все программирование форм.

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

В верхней части окна кода присутствуют два списка. Если раскрыть левый, то мы увидим перечень всех объектов, присутствующих на форме, включая ее саму и пункт General, отвечающий за область определения, общую для всего модуля кода формы.

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

	Private Sub CommandButton2_Click()

	End Sub

Правый список содержит перечень методов для объекта, указанного в левом списке. Выбор из него приводит к переводу курсора на соответствующую программу или ее создание, если таковой еще не было. Все. Именно так и следует начинать программирование любых методов.

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

Способ 1. Все необходимые действия производятся в процедурах нажатия кнопок, после чего форма скрывается (Hide) или уничтожается (Unload). Вариант является очевидным и стандартным, но не всегда приемлемым.

Способ 2. Форма скрывается (Hide), после чего происходит обработка из вызвавшей форму программы. Вариант требует дополнительных усилий.

Разберем их реализацию по порядку.

Выполнения действий из формы

	Private Sub CommandButton1_Click()
	    If OptionButton1.Value = True Then ' Выбран первый переключатель
	        MsgBox "Вариант 1"
	    Else ' Выбран НЕ первый переключатель, то есть второй
	        MsgBox "Вариант 2"
	    End If
	    Unload Test1 ' Форма выгружается из памяти, то есть уничтожается
	End Sub
	Private Sub CommandButton2_Click()
	    Unload Test1 ' Форма выгружается из памяти, то есть уничтожается
	End Sub

Во-первых, обсудим строку OptionButton1.Value = True. Она означает, что у объекта OptionButton1 есть свойство Value (написано через точку), указывающее на содержащееся объектом значение, которое мы сравниваем (=) с истинностью (True). Читающим эти строки уже должен быть понятен синтаксис и без моих объяснений.

Если выражение сравнения истинно, то результатом анализа станет возврат True. Но, позвольте, OptionButton1.Value уже содержит True, то есть можно отказаться от лишнего действия и сократить запись:

	    If OptionButton1.Value Then

Однако, попытка обращения к данному объекту и так возвращает его значение (выбранность), то есть можно записать еще короче:

	    If OptionButton1 Then

Во-вторых, вместо MsgBox нужно ввести код, нужный для данного случая.

В-третьих, If...Else хватило только потому, что выбираем один вариант из двух. Иначе потребуется более сложная конструкция.

Выполнения действий в вызвавшей процедуре

Такой способ будет наиболее эффективен, если форму придется открывать много раз

Первый вопрос, который возникает, касается того, какая же кнопка, была нажата для закрытия формы: подтверждение или отказ.

Простейшим способом решения будет создание в основном модуле уникальной глобальной переменной. Ее объявление производится до начала первой процедуры.

	Public Form_Choice As Byte ' Тип Byte занимает минимальный объем памяти
	Sub Первая_Программа_Модуля()
	    ...
	End Sub

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

	Private Sub CommandButton1_Click()
	    Form_Choice = vbOK
	    Test1.Hide
	End Sub
	Private Sub CommandButton2_Click()
	    Form_Choice = vbCancel
	    Test1.Hide
	End Sub

В данном случае использован объектный метод

ИмяФормы.Hide

Заметьте, команда скрывает форму, а не удаляет ее. В результате можно программно обратиться к отдельным элементам и изучить, что они содержат. То есть проанализировать выбор и/или ввод пользователя.

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

	Test1.Show ' Вызов окна формы. Он потребуется во всех случаях
	If Form_Choice = vbCancel ' Была нажата кнопка отмены
	   Unload Test1 ' Форма выгружается из памяти, то есть уничтожается
	   Exit Sub ' Завершить программу
	End If
	' Последующий код выполнится только если не была нажата отмена
	If Test1.OptionButton1.Value = True Then ' Выбран первый переключатель
            MsgBox "Вариант 1"
	Else ' Выбран НЕ первый переключатель, то есть второй
	    MsgBox "Вариант 2"
	End If
	Unload Test1 ' Форма выгружается из памяти, то есть уничтожается

Все приведенные комментарии для предыдущего способа, действительны и здесь.

Побочный эффект будет заключаться в том, что все изменения, произведенные в форме, сохранятся при ее повторном показе. С этим придется либо бороться, либо, наоборот, удастся воспользоваться.

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

Примеры форм

Диалог обратной связи интеллектуальной системы выделения авторов в списке литературы. Производит анализ текста и расширение/уменьшение выделения справа и слева в зависимости от нажатой кнопки диалога.

Примитивное информирование пользователя о шаблоне, построенное на базе MsgBox, где сообщение принудительно разбито на строки.

Работа со списком научных журналов (3792 штуки). Доступно добавление, удаление, редактирование. Накапливается информация о вариантах написания и правильном сокращенном написании, включая его версии на разные периоды.

Элемент системы проверки списков литературы, позволяющий выявлять некоторые часто встречающиеся проблемы библиографических списков с безошибочной эффективностью на 5–10 порядков выше, чем у профессионального редактора.

Объекты управления и методы

Ниже приведены основные объекты, связанные с формами и перечислены их методы (не свойства!). Найти даже эту информацию достаточно сложно. Так что, не обессудьте, обсуждаться они пока не будут.

Восклицательным знаком обозначены методы, создаваемые автоматически при двойном щелчке на элементе управления.

Проверка введенных данных

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

Это действие разумнее всего производить в самой форме, не загромождая программу.

Прежде чем погружаться в реализацию, надо разобраться, какие варианты проверки и/или ограничений можно использовать.

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

Обращение к форме из программы

Это уже обсуждено в примерах, но, все же, уточним еще раз.

Если форма запущена или скрыта командой ИмяФормы.Hide, то к любому ее методу или элементу можно обратиться и считать его свойства. Кстати, сама команда скрытия в предыдущем предложении и есть обращение к методу формы, равно как и ее запуск или удаление в примерах.

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

Test1.OptionButton1.Value

В пределах модуля программного кода самой формы, такой префикс не требуется.

Удаление формы из памяти

Производится командой (инструкцией):

Unload Test1

После выгрузки объекта, он полностью удаляется из памяти, освобождая ее. Но обращение к нему также становится невозможным.

См. также Диалоги.


Copyright © 1993–2020 Мацкявичюс Д.А. Все права защищены.
Никакая часть сайта не может быть воспроизведена никаким способом без письменного разрешения правообладателя и явной ссылки на данный ресурс.