Основы офисного программирования и язык VBA

       

&Вопросы для системного администратора


"100" Чем нужно зажимать сетевой джек:
"100" Специальным инструментом.
"50" Плоскогубцами.
"0" Зубами.
"0" А зачем его вообще зажимать?

"80" Что вы делали на Новый Год:
"0" Гулял с друзьями.
"100" Переставлял Линукс.

"100" Как у вас проложен сетевой кабель:
"50" В коробе.
"0" По полу.
"100" Мы давно перешли на WaveLAN.

То есть первая строка со значком & обозначает начало темы, потом идут группы строк, первая из которых - вопрос, а остальные - ответы. Строки предваряются весовыми коэффициентами: "важности" - для вопросов, и "степени верности" - для ответов. Согласитесь, что ввести и модифицировать такой файл может любой пользователь. Для представления банка данных создадим три тривиальных класса: ' class BLine Public Weight As Integer Public Value As String Public ff As InlineShape Public loc As Range Public Sub Parse (s As String) p1 = InStr (s, """") p2 = InStr (p1 + 1, s, """") If (p1 > 0) And (p2 > p1) Then Weight = Val (Mid (s, p1 + 1, p2 - 1)) Value = Trim (Mid (s, p2 + 1)) Else Weight = 0 Value = s End If End Sub

' class Question Public Question As New BLine Public Answers As New Collection 'Of BLine (s)

' class Theme Public Title As String Public Questions As New Collection 'Of Question (s) Public Selected As Boolean

Как видите, вопрос - это собственно вопрос и коллекция ответов, а тема - это название темы и коллекция вопросов. Это похоже на представление списков в LISP - голова и хвост. Самый главный кирпич всей иерархии, класс BLline, включает в себя строку и ее вес, а также дополнительные поля, смысл которых прояснится позже. Тривиальный метод Perse принимает строку и преобразует ее в поля объекта - немудреный суржик перегрузки конструктора в C++.

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

Есть четыре возможности запустить макрос: по нажатию горячей клавиши, по нажатию кнопки на панели, по системному событию и явно через меню Макросы. Поскольку этот вопрос нас пока не занимает, то пусть наш процесс запускается по Ctrl+K - кнопки на панелях инструментов имеют свойство теряться, а сами панели - быть закрытыми шаловливыми конечностями пользователей.

С высоты птичьего полета выполняем такие вот действия:

  • инициализируем используемые структуры и получаем ссылки на необходимые системные (в смысле, Word) объекты;
  • строим иерархическое дерево Test - Theme (s) - Question (s) - Bline + Bline (s);
  • выводим список тем и количество вопросов в каждой - для выбора вопросов только по этим темам. Опуская сам процесс выбора и задействованное при этом диалоговое окно, можно только сказать, что после его закрытия поле Selected выбранных тем принимает значение TRUE;
  • после того как темы выбраны, все вопросы по всем темам сбрасываются в одну большую коллекцию и как следует тасуются. Поскольку объекты представляются ссылками, то новая коллекция содержит только ссылки, а не сами объекты;
  • формируется новый документ с отобранными вопросами в нужном количестве. Документ имеет несколько необычных свойств: он защищен на уровне защиты страницы, в нем отключена проверка правописания (для подавления ненужных визуальных эффектов) и в него внедрены ActiveX-элементы типа checkbox. К каждому элементу динамически прикрепляется обработчик. Задача обработчика - воспринимать ввод пользователя. Как только пользователь выбирает один ответ, другие варианты блокируются и сам вопрос подсвечивается определенным цветом - в зависимости от правильности ответа.


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


Этот документ воспринимает ввод пользователя, видоизменяя сам документ, и в конце концов формирует "протокол тестирования".

Обратите внимание на то, как мы динамически создаем OLE controls в слое документа (есть еще слой векторной графики с абсолютными координатами). Существует также два уровня доступа к OLE-элементу - фактически для каждого элемента создается мини-контейнер со своими собственными свойствами. Для доступа к настоящему OLE приходится обращаться на уровень ниже - к полю Object (это похоже на то, как MFC или Delphi инкапсулирует объекты Windows). К каждому элементу управления "приделывается" персональный и в общем случае ни на что не похожий обработчик - с помощью техники, знакомой конструкторам Wizard'ов и прочих RAD'ов.



Текст основной (а фактически - и единственной) функции приведен в листинге 1. Имя ее не имеет значения - главное, чтобы она вызывалась по Ctrl+K или другим известным способом.

Модуль Module1, экспортируемый из первичного документа и импортируемый в "билет" через файл. Небольшая обработка на предмет "а не закончились ли у нас вопросы?"; если да - то заполнение "протокола" (листинг 2).

Обработчики событий для формы выбора тем - приводится для полноты изложения листинг 3. Сама форма выглядит примерно так, как показано на рисунке.



Содержание раздела