Logo CitForum CITForum на CD Форумы Газета Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

23.05.2012

Google
WWW CITForum.ru
2004 г.

Подвижный VBA'стик в кислотной ActiveX-среде

Арсений Чеботарев, "Комиздат"

Обычно книги и статьи по VBA посвящены тому, что можно сделать на VBA, но для чего он совсем не предназначен. Так, например, у меня есть книга (на 800 страниц), посвященная, в основном, таким вещам, как системные вызовы и конструирование древовидных структур вручную. Это как раз то, чего нужно бы избегать,- если вы не пишете трояны, конечно.

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

Use Case с точки зрения программиста

Проиллюстрированная далее программа показывает, как VBA получает доступ, создает и управляет ActiveX-элементами за пределами иерархии классов Office. Создавать элементы управления не имеет особого смысла, если не обрабатывать специфические для них события. Поскольку ActiveX-элементы у нас будут создаваться динамически и их количество не будет даже предварительно известно, то и обработчики будут генерироваться динамически. Да и поведение наших "кнопок", хотя и будет выбираться из нескольких вариантов, но все-таки должно определяться в последний момент… Короче, если вы пробовали генерировать программы, начиная от LISP и prolog и заканчивая визардами в VS, то вы представляете, о чем речь.

Use Case с точки зрения пользователя и заказчика

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

Прежде чем начать работу, включите выполнение макросов: в Сервис> Макросы> Безопасность поставьте переключатель в положение Низкая.

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

Ко всему прочему, макровирусы не отличаются жестокостью, так что вы можете установить антивирус, но не включать его в режиме постоянного сканирования, а всего лишь раз в день запускать на сканирование. Дополнительно можно рекомендовать антивирусную защиту почты - пользуйтесь почтовым сервером, который применяет антивирусные сканеры, поскольку этот путь инфицирования сейчас наиболее распространен. (Из личного опыта: за 15 лет работы за клавиатурой я не потерял ни единого бита из-за вирусов - а всё только по причине собственной рассеянности и пьянства. Так что для меня вирусы - скорее легенда, чем реальная угроза.)

И последнее: никто не отменял резервного копирования и других методов backup'а, таких как хранение эталонной системы в формате Norton Ghost. Благо, CD-RW и прочие носители сейчас дешевле грибов.

Постановка задачи

Есть сборник вопросов в некоторой предметной области (в терминах экзаменаторов - банк данных). Вопросы разделены на несколько тем или групп - уровень деления 1, то есть у тем нет подтем. Все вопросы имеют свой "вес" от 50 до 100, вес определяет важность вопроса: 100 соответствует наиболее важным, а 50 - самым "проходным" вопросам. Каждому вопросу соответствует несколько (обычно 3-5) ответов. Каждый ответ тоже имеет свой "вес" от 100 до 0: 100 соответствует абсолютно правильным и полным ответам, 80 - частично правильным, 50 - не лишенным элементов истины и 0 - полностью неверным. Предполагается, что для каждого вопроса существует один и только один абсолютно правильный ответ. Для проведения экзамена из всего банка случайным образом выбирается определенное количество вопросов, их порядок меняется произвольным образом. При этом можно выбрать одну, несколько или все темы. Ответы также меняются местами. Предварительно выбранные вопросы кладутся в "конверт", который экзаменуемый вскрывает во время экзамена.

После ответов подсчитывается общий балл. Происходит это следующим образом: складываются все веса всех вопросов как максимальное число баллов, которое возможно набрать. Реально набранное число баллов определяется суммой Sum (Vx*Mx) - то есть веса вопросов на вес полученного ответа. Успеваемость экзамена вычисляется как процент набранных баллов от максимально возможных.

Дополнительные условия

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

  • программа должна работать на любых компьютерах, на которых запускается Windows, в том числе без CD и сети;
  • программа должна работать без инсталляции какого-либо ПО, системы управления базами данных, сети, интернета и так далее. Единственная предпосылка - наличие на компьютере Windows и Word. Это довольно строгое ограничение - но, тем не менее, жизненное: инсталляция (или проверка наличия) того же BDE или MS Access на 100-200 компьютерах может значительно откорректировать бюджет любого начинания;
  • вопросы должны изменяться самым простым и непосредственным образом, для этой операции не нужно проходить никакого инструктажа или обучения;
  • подготовленные "конверты" с вопросами должны иметь минимальную степень защиты от модификации, так чтобы экзаменуемый в присутствии экзаменатора не мог нечаянно или с минимальными усилиями изменить результаты в свою пользу. Безусловно, это не касается "людей от компьютера", которые в комфортных условиях и при наличии времени могут сломать и видоизменить все что угодно - подразумевается, что экзаменуемый находится в системе тестирования и не занимается хаком нашей программы.

Итак, отталкиваясь от всего перечисленного, начнем строить нашу тестовую систему. Первое, что приходится сделать, это выбрать Word как в качестве источника данных, так и в качестве среды выполнения. Такое решение - самое естественное, поскольку ни на какой другой рантайм мы не можем рассчитывать. Первой идеей было использовать текстовый режим и gcc+couses. Но редактирование текстовых файлов в dos-кодировке - это задача, с которой справится не каждый современный пользователь, и, как говорят, "текстовый режим выглядит не современно".

Первое последствие из выбора Word в качестве инструмента: наша база данных будет представлена обычным Word-документом определенного формата. В силу некоторых исторических причин формат текста был следующим:

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

"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. Сама форма выглядит примерно так, как показано на рисунке.

Подписка на новости CITForum.ru

Новые публикации:

7 июля

  • Управление параллелизмом с низкими накладными расходами для разделенных баз данных в основной памяти

  • Рекурсивные запросы в Oracle

  • Жесткий диск WD10EARS с сектором 4 КБ. Подготовка к эксплуатации в Linux.

    Обзоры журнала Computer:

    Газета:

  • Московские пробки - исследование IBM

  • От Osborne до iPad: эволюция портативных компьютеров

    19 мая

  • Прозрачный механизм удаленного обслуживания системных вызовов

  • Система моделирования Grid: реализация и возможности применения

    Газета:

    Майкл Стоунбрейкер:

  • Ошибки в системах баз данных, согласованность "в конечном счете" и теорема CAP

  • Дискуссия по поводу "NoSQL" не имеет никакого отношения к SQL

    29 апреля

  • Материалы конференции "Корпоративные Базы Данных-2010"

  • Разные облики технологии баз данных (отчет о конференции)

    14 апреля

  • MapReduce: внутри, снаружи или сбоку от параллельных СУБД?

  • Научные вызовы технологиям СУБД

    Обзоры журнала Computer:

    31 марта

  • Рационализация согласованности в "облаках": не платите за то, что вам не требуется

  • Взаимные блокировки в Oracle

  • Архитектура среды тестирования на основе моделей, построенная на базе компонентных технологий

  • Объектное представление XML-документов

    Газета:

  • Microsoft для российских разработчиков: практика с элементами фундаментальности

    10 марта

  • HadoopDB: архитектурный гибрид технологий MapReduce и СУБД для аналитических рабочих нагрузок

  • Классификация OLAP-систем вида xOLAP

  • BGP. Три внешних канала. Балансировка исходящего и входящего трафиков

    Газета:

  • Что мы знаем об iPhone 4G?

    17 февраля

  • MapReduce и параллельные СУБД: друзья или враги?

  • Объектно-ориентированное программирование в ограничениях: новый подход на основе декларативных языков моделирования данных

  • Системологический подход к декомпозиции в объектно-ориентированном анализе и проектировании программного обеспечения

    Газета:

  • Эволюция Wine

    3 февраля

  • Дом на песке

  • Реальное переосмысление "формальных методов"

  • Интервью с Найджелом Пендзом

    Газета:

  • iPad. Первый взгляд на долгожданный планшет от Apple

  • Я не верю в iPad

    20 января

  • SQL/MapReduce: практический подход к поддержке самоописываемых, полиморфных и параллелизуемых функций, определяемых пользователями

  • Данные на лету: как технология потокового SQL помогает преодолеть кризис

    Обзоры журнала Computer:

    2 декабря

  • Сергей Кузнецов. Год эпохи перемен в технологии баз данных

    18 ноября

  • Генерация тестовых программ для подсистемы управления памятью микропроцессора

  • Сравнительный анализ современных технологий разработки тестов для моделей аппаратного обеспечения

    Все публикации >>>


  • IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

    Информация для рекламодателей PR-акции, размещение рекламы — тел. +7 495 6608306, ICQ 232284597 Пресс-релизы — pr@citforum.ru
    Послать комментарий
    Информация для авторов

    Редакция раздаёт котят!

    Rambler's Top100 TopList liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня This Web server launched on February 24, 1997
    Copyright © 1997-2000 CIT, © 2001-2009 CIT Forum
    Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...