В начало
Статьи
Библиотека
Разное

Вот здесь - новый сайт, заходите немедленно!

kift - Коллекция Интересных Фактов и Теорий

А тут можно поболтать и побухтеть, милости просим:

kift - неизданное

Введение в программирование на примере VBA

Часть II. Создание макроса-приложения

Аннотация
Предисловие
Часть I. Макрос Word
     1. Проектирование и запись макроса
     2. Разбор макроса
     3. Внесение исправлений
     Итоги
Часть II. Макрос-приложение
     4. Проектирование
     5. Визуальное редактирование
     6. Запуск и остановка
     7. Вывод данных
    8. Выбор ответа
     9. Перемещение по списку
     10. Обратное перемещение
     11. Новая версия
     12. Реализация новой версии
     13. Завершение работы
     Итоги
Часть III. Объект на основе класса
     14. "Основное" приложение
     15. Компонент-таймер
     Итоги
Послесловие

Занятие 8. Выбор ответа

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

Подцикл 4. Обработчик выбора ответа

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

Цель работы нашего приложения вообще – определить, верный ли ответ выбран. Сейчас этим и займемся.

У нас уже есть «инструмент» выбора – элементы управления-переключатели.

Очевидно, что выбранный переключатель соответствует выбранному ответу.

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

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

Здесь, как и во многих других случаях, поможет аналогия из жизни. Когда преподаватель проверяет задание? В момент выполнения? Нет, как правило – после сдачи его студентом.

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

Проектирование

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

Сформулируем предварительное описание обработчика выбора ответов (требования).

При переходе к следующему вопросу в списке обработчик будет сообщать, какой (по счету) ответ выбран. Оценку правильности ответа давать пока не будем.

Контрол-переключатель предназначен для множественного выбора. Этот элемент управления имеет свойство ValueЗначение, которое может принимать значение 1, если переключатель выбран, и 0 – если переключатель не выбран. В группе переключателей выбранным может быть только один.

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

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

Реализация

Создание свойства, определяющего выбранный переключатель

Давайте создадим свойство, отвечающее за выбранный переключатель.

Код свойства проще всего поместить в кодовую часть формы.

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

Помещать свойство в модуль бессмысленно. Модуль не является объектом, модуль – всего лишь сборник процедур. Свойство же может быть только у объекта.

Создать же свойство у формы легко.

Для создания нового свойства следует определить, будет ли оно доступно для чтения, для записи или и для того и для другого.

В нашем случае требуется получать значение – читать из свойства.

Синтаксис свойства для чтения такой:

Property Get <имя_свойства> As <тип>
...
End Property

Как видите, есть некоторое сходство с синтаксисом процедуры. Также могут использоваться квалификаторы Public- Private.

Резонный вопрос – почему бы не использовать публичную переменную для хранения номера выбранного ответа? Нами предполагаются некоторые действия для определения этого номера. Обратное действие, которое мы реализуем в перспективе – выбор переключателя по номеру ответа – потребует еще более сложных манипуляций. Код свойства позволяет разместить требуемые действия, иначе мы будем вынуждены чрезвычайно усложнять и запутывать текст программы, что неизбежно ухудшит качество.

  • Откройте окно кода формы frmTest.
  • Создайте вручную заготовку кода свойства:

Private Property Get AnswSelected() As Integer

  • Нажмите [Enter].

Если строка заголовка набрана верно, VBA дополнит заготовку строкой-окончанием, код приобретет такой вид:

Private Property Get AnswSelected() As Integer

End Property

Если что-то не так – проверьте правильность своих действий.

Разберем эту конструкцию.

Слово Private обозначает то, что свойство будет доступно только из проекта, в котором находится форма. Нам не требуется – и даже нежелательно, – чтобы посторонние программы могли иметь доступ к этому свойству. Поэтому объявим его Частным.

Слово PropertyСвойство – определяет объявление свойства, в отличие от объявления процедуры, где мы используем слово Sub.

Далее – слово GetПолучить. Использование этого слова определяет назначение свойства для чтения. Присвоить значение свойству мы еще не можем, для этого используется слово Let.

Имя свойства произвольно, подчиняется универсальным правилам именования в VBA. В данном случае имя AnswSelectedОтв[ет]Выбранный.

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

IntegerЦелое – один из основных типов VBA. Свойства и переменные этого типа могут манипулировать целочисленными числовыми значениями в диапазоне от –32768 до 32767.

Более подробное описание типа можно найти в справке VBA. Так как мы предположительно будем использовать числа от 1 до 3, данный тип нам подходит с избытком. Еще лучше подошел бы тип Byte, допускающий значения от 0 до 255, но тип Integer более традиционен, а, кроме того, допускает отрицательные значения, что упростит расширение программы в дальнейшем, если это вдруг понадобится. Поэтому выбран тип Integer.

Строка

End Property

является обязательным индикатором конца кода свойства.

Давайте проверим, успешно ли прошло создание свойства. Для этого попробуем найти его в Object Browser.

  • Откройте Object Browser нажатием [F2].
  • В верхнем левом списке выберите строку VBAProject.

Ниже вы увидите перечень объектов, относящихся к текущему проекту.

  • Щелкните один раз на строке, соответствующей форме frmTest.

В правом перечне появятся имена свойств и методов формы. Как видите, одним из первых идет вновь созданное свойство.

  • Щелкните один раз на строке AnswSelected.

В нижней панели Object Browser – синтаксис этого свойства:

Все правильно.

  • Можете закрыть окно Object Browser.
  • Сохраните изменения.

Перейдем к созданию «полезного» кода.

Откуда мы можем узнать об изменении выбора переключателя? Об этом уже говорилось выше. Контрол-переключатель при щелчке по нему инициирует событие Click. Используем это событие.

Мы уже говорили, что использование этого события для обработки выбора ответа нежелательно из-за множества излишних действий, выполняемых приложением. В данном случае объем «ненужной» деятельности сведен к минимуму, а совсем избежать ее, к сожалению, нельзя. Мы пришли к компромиссу между сложностью кода и «загруженностью» приложения.

  • Откройте окно кода формы frmTest.

Следует создать дополнительное хранилище-переменную для значения свойства.

  • Перейдите в начало окна кода (в область объявления глобальных переменных).
  • Напишите строку:

Dim intAnswer as Integer

Тем самым мы объявили переменную типа Integer (то есть того же типа, что и создаваемое свойство) по имени intAnswer.

Имя переменной, как видите, создано из сокращенного написания типа и собственно имени AnswerОтвет.

  • В верхнем левом списке выберите объект optAnswer1.

VBA автоматически создаст заготовку кода обработчика события Click для этого контрола. Такое поведение характерно для VBA, он автоматически создает заготовки наиболее часто (по его мнению) используемых событий.

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

Если почему-то вы оказались не в обработчике события Click, то:

  • Выберите строку Click.

В окне кода появится заготовка обработчика события Click для объекта optAnswer1.

  • Добавьте строку:

intAnswer = 1

Иначе говоря, внутренней переменной назначается номер выбранного контрола (не забывайте, мы работаем с элементом управления optAnswer1).

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

Код формы приобретет вид:

Объявление внутренней переменной intAnswer находится в так называемой области глобальных объявлений, доступных всему коду. Здесь следует помещать объявления, которые будут использоваться различными участками программы. Объявление Dim в данном случае соответствует Private, то есть эта переменная будет видна только внутри формы.

  • Теперь можно дописать код свойства.

Код приобретет вид:

Private Property Get AnswSelected() As Integer
    AnswSelected = intAnswer
End Property

Проверить правильность кода пока не получится. Надо добавить еще один обработчик – а именно события нажатия на кнопку cmdNext.

Создание обработчика события

  • В верхнем левом списке окна кода выберите объект cmdNext.

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

Тестирование

Для проверки кода достаточно будет просто вывести на экран число, соответствующее выбранному ответу.

  • Дополните код обработчика события Click таким образом:

Private Sub cmdNext_Click()
MsgBox AnswSelected
End Sub

Слово MsgBox – сокращение от MessageBoxОкноСообщения. Здесь показано простейшее применение этой функции VBA. Как аргумент, MsgBox принимает значение свойства AnswSelected.

Внимательно изучите код, запомните синтаксис MsgBox. Эта функция применяется очень часто, ее основное назначение – кратковременный вывод каких-то надписей (сообщений). Кроме того, эта функция позволяет «задавать вопросы» пользователю и в зависимости от выбора пользователя «указывать» приложению способ дальнейшей работы.

Формально верным было бы написание кода так:

MsgBox frmTest.AnswSelected

то есть с явным указанием объекта, которому принадлежит свойство. Так как код находится внутри этой формы, такое указание необязательно. Делайте как хотите, но явное указание объекта-собственника свойства правильнее.

  • Сохраните код.
  • Запустите приложение.
  • Выберите один из ответов щелчком по переключателю – в «кружочке» переключателя должна появиться точка-отметка.
  • Щелкните по кнопке cmdNext – пока мы еще не изменяли надпись на ней, это – правая кнопка на нашей форме.

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

Щелчком на кнопке OK в этом окошечке – или нажатием [Esc], – вы можете закрыть его.

  • Попробуйте выбирать разные переключатели и щелкать на cmdNext.

Если вы внимательно следовали указаниям, числа в окошечке должны соответствовать переключателям.

  • Если все правильно – остановите приложение.
  • Запустите его снова.

Как видите, ни один переключатель не выбран.

  • Щелкните на кнопке cmdNext.

В окошечке должно появиться число 0. Действительно, выбор переключателей не производился, значение свойства не изменялось.

Все правильно.

  • Остановите приложение и сохраните проект, не забыв перед этим создать комментарии к каждой строке кода.

Занятие закончено. В дальнейшем мы будем усложнять взаимодействия приложения и пользователя.

Итог занятия

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

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

Функция MsgBox – одна из многочисленных функций языка VBA. Она очень проста в использовании, область применения ее достаточно широка. Изучите раздел справки, относящийся к функции MsgBox.

Напишите конспект, на этот раз не очень большой:

  • Свойства, понятие, синтаксис.
  • Свойства для чтения и для записи. Особенности синтаксиса.
  • Функция MsgBox, синтаксис, пример использования.
Hosted by uCoz