Основные новшества средств программирования Word 97
Миграция WordBasic в Visual Basic
Возможные проблемы при преобразовании кода

Одно из главных новшеств пакета MS Office 97 заключается в том, что именно в этой версии офисного программного комплекса была в целом завершена интеграция средств программирования для отдельных приложений в единую среду разработки. В основе интеграции лежат два ключевых элемента: объектная модель реализации приложений (Component Object Model, COM - модель объектных компонентов) и система разработки Visual Basic for Applications (VBA) версии 5.0.

С точки зрения программирования все приложения и компоненты Office 97 - в том числе Office Art, Office Command Bar, средства поддержки WWW и даже Office Assistant - могут рассматриваться как огромный (свыше пятисот элементов) набор унифицированных объектов, доступ к которым возможен и из других приложений. Более половины этих объектов - общие для всех программ Office 97. Такая же объектная модель положена в основу ряда других продуктов Microsoft, не входящих в состав Office 97, например Project 95, Schedule+ 95, Team Manager 97.

Все основные приложения Office 97 - Word, Excel, PowerPoint и Access - используют единый языковой механизм и среду разработки VBA 5.0, которые в целом совпадают с системой Visual Basic 5.0. Отдельным компонентом Office 97 является среда разработки под названием Редактор Visual Basic (Visual Basic Editor, VBE). Для создания диалоговых окон и форм в VBE используется еще один программный компонент VBA - библиотека MS Form 2.0 Object Library, логика работы которой та же, что и в обычном VB 5.0. VBE используется в Excel, Word и PowerPoint. СУБД Access имеет собственную среду, что обусловлено особенностями работы с базами данных.

Для внутреннего программирования в Outlook используются язык VBScript и довольно специфическая среда для создания форм. Тем не менее создаваемые объекты полностью соответствуют спецификациям COM и могут применяться при программировании на VBA в других приложениях.

Основные новшества средств программирования Word 97

В Word 6 и 7 макрокоманды пишутся на языке WordBasic в специализированной встроенной среде. Привязка WordBasic к специфике Word достигается за счет включения в язык огромного числа команд (всего их около 900). В VBA же, в отличие от WordBasic, множество команд ограничено базовым списком операторов VB, а специальные функции отдельных приложений (это относится не только к Word 97) реализуются иерархической системой объектов. Для работы с такими объектами служат их собственные наборы методов и свойств, а не непосредственно операторы и функции языка.

С внешней стороны данное новшество проявляется в том, что программный код VBA выглядит более сложным. Однако если приглядеться повнимательнее, то выясняется, что громоздкость текста программы кажущаяся. Например, в WordBasic, чтобы установить полужирное начертание шрифта для выделенного фрагмента текста, достаточно написать:

Bold 1

В VBA такого оператора нет, зато определено свойство Bold для объекта Font. Объект Font, в свою очередь, определяется с помощью свойства Font объекта Selection, а объект Selection - с помощью свойства Selection объекта Application. Таким образом, чтобы изменить начертание символов, нужно обратиться к следующей иерархии объектов:

Application -> Selection -> Font -> Bold

А программный код в VBA выглядит так:

[Application.]Selection.Font.Bold = True

При работе внутри приложения объект Application можно опустить.

Более детально принципы программирования в Office 97, объектная модель и особенности работы с отдельными приложениями описываются в двух руководствах, которые вкладываются в коробку с Microsoft Office 97 Developer Edition, - VBA Programmer's Guide и Object Model Guide. Эти руководства существуют также в виде отдельной книги издательства Microsoft Press и в электронной версии, которая находится на Web-узле Microsoft по адресу http://www.microsoft.com/officedev/. Их русский перевод должен выйти в начале 1998 г.

Миграция WordBasic в Visual Basic

Преобразование программного кода из WordBasic в VB, т. е. из Word 6 (Word 7) в Word 97 происходит автоматически при прямом или косвенном (как в случае присоединенных шаблонов) открытии шаблона. Пользователь при этом порой даже не догадывается о том, что преобразование имело место. Однако все же имеет смысл подробнее рассмотреть этот процесс на примере работы с Word 6.0 и Word 97.

Процесс преобразования

Прежде всего нужно обратить внимание на то, что в WordBasic каждая макрокоманда представляет собой модуль с входной точкой Sub MAIN. В Word 97 макрокомандой является любая общая (Public) подпрограмма, в которую не передаются никакие параметры. Тем не менее Word 97 по-прежнему использует точку входа Sub MAIN для обеспечения обратной совместимости. В предыдущих версиях Word макрокоманды могли быть записаны только в шаблоне, а в Word 97 они могут храниться также в файле самого документа.

Создадим в среде Word 6.0 новый шаблон с названием Templ1.dot. Далее напишем для него две макрокоманды - Test1 и Test2. Для это нужно выбрать в меню "Сервис" пункт "Макрокоманда". В диалоговом окне "Макрокоманда" в списке "Макрокоманды, доступные в..." задайте шаблон Templ1.dot. Каждая макрокоманда пока состоит из пустых процедур с одинаковым названием:

Sub MAIN

End Sub

Используя инструментальную панель "Макро", введите программный код макрокоманд, представленный в листинге 1. Макрокоманда Test1 содержит вспомогательную функцию MyFunction$. Вторая макрокоманда (Test2) также использует эту функцию, но для обращения к ней требуется дополнительно указать имя макрокоманды, в которой она хранится. Сохраните шаблон Templ1.dot и закончите работу в среде Word 6.0.

Теперь загрузите Word 97 и откройте в нем Templ1.dot. Чтобы взглянуть на содержимое его программной части, перейдите в среду VBE (для перехода из среды Word в VBE и наоборот можно пользоваться сочетанием клавиш +). В окне Project хорошо видна программная структура проекта, в котором кроме стандартного элемента ThisDocument появилось еще два модуля - Test1 и Test2. Для просмотра содержимого модуля дважды щелкните по его названию. Преобразованный код обоих модулей представлен в листинге 2.

Обратите внимание на то, что в VBA название макрокоманды определяется не именем модуля, а идентификатором процедуры. В нашем случае были созданы две общие процедуры с одним и тем же именем MAIN. Для предотвращения конфликта в качестве имени макрокоманды используется составное название, в данном случае - Test1.MAIN и Test2.MAIN. Благодаря этому в VBA можно использовать в разных модулях общие процедуры с одинаковыми названиями.

Еще несколько замечаний относительно преобразованного кода.

  • Все операторы WordBasic преобразованы в методы объекта WordBasic, который реализован специально для совместимости макросов WordBasic в Word 97.
  • Все переменные описываются в начале процедуры или в разделе описаний модуля. Обратите внимание на то, что числовые переменные по умолчанию определяются как тип Variant.
  • Имена переменных, которые конфликтуют с ключевыми словами Visual Basic, при преобразовании модифицируются. В нашем примере переменная Debug изменилась на Debug_.
  • Конвертер предполагает, что Sub MAIN является единственной точкой входа макроса WordBasic. О правильной работе модулей с несколькими точками входа разработчик должен позаботиться сам.
  • Sub MAIN объявляется как общая (Public) процедура, а MyFunction$ - как частная (Private).
В макрокоманде Test2 объект WordBasic использует новый метод Call для обращения к внешним процедурам, которые автоматически определяются как Private. Однако здесь следует иметь в виду, что конструкция WordBasic.Call работает существенно медленнее, чем непосредственное обращение к процедуре. Для повышения быстродействия при перекрестных вызовах модулей лучше изменить описание вызываемой процедуры (в нашем примере - MyFunction$) с Private на Public, а в операторе вызова удалить WordBasic.Call:

Public Sub MAIN()
WordBasic.Insert Test1.MyFunction$
End Sub

Если подпрограмма или функция, к которой происходит обращение, хранится в другом шаблоне, то вызывающий шаблон должен содержать ссылку на проект с вызываемым шаблоном. Добавьте нужную ссылку в диалоговом окне "Ссылки" (References) в редакторе Visual Basic.

Перспективы улучшения кода

Автоматическое преобразование кода WordBasic в Visual Basic, осуществляемое Word 97, - решение простое, но временное. Если вы предполагаете пользоваться соответствующими процедурами и в будущем, то для повышения эффективности кода преобразованную программу WordBasic лучше переписать с использованием объектов Visual Basic. Замену кода можно осуществлять постепенно, по мере необходимости.

Возможные проблемы при преобразовании кода

Обнаружение старых синтаксических ошибок

Язык WordBasic чисто интерпретируемый. Это означает, что если оператор никогда не выполняется, то он никогда не проверяется и не анализируется. Вот пример такого оператора:

If 0 <> 0 Then
    1 = SyntaxErrorSpokenHere
End If
MsgBox "Работает"

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

Рекомендуется в начало каждого модуля помещать оператор Option Explicit; он задает режим явного описания переменных, в котором любое появление необъявленной переменной рассматривается как ошибка компиляции. Для этого установите флажок "Явное описание переменных" (Require Variable Declarations) в диалоговом окне "Параметры" (Options; команда "Параметры" в меню "Сервис" - Tools - редактора Visual Basic).

Обновление 16-разрядных вызовов API-функций

16-разрядные объявления API-функций должны быть преобразованы в 32-разрядные.

Открытие документов с длинными именами макросов

Допустимая длина имени макроса (имени модуля) в WordBasic составляет 40 символов, а в Visual Basic - только 31. Поэтому, если шаблон содержит два макроса с именами, в которых совпадают первые 31 символ, Word не сможет правильно модифицировать их имена и в результате при открытии шаблона произойдет ошибка. Для ее исправления откройте шаблон в Word 6 (Word 7) и назначьте макросам более короткие имена.

Преобразование локализованного кода WordBasic в Word 97

Разработка на WordBasic приложений, которые бы работали со всеми разноязычными версиями Word, была сопряжена с определенными трудностями. В Word 97 эти трудности устранены благодаря применению вместо литеральных строк пронумерованных констант. Например, для изменения стиля на Heading 1 следует пользоваться не литеральной строкой "Heading 1" (или "Заголовок 1" для русской версии Word), а константой wdStyleHeading1.

" Следующий оператор работает в англоязычной версии Word

Selection.Style = ActiveDocument.Styles("Heading 1")
" А этот оператор работает во всех версиях Word 97
Selection.Style = ActiveDocument.Styles(wdStyleHeading1)

В большинстве случаев преобразование программного кода из WordBasic в VB не вызывает затруднений у разработчиков. Предварительный анализ макрокоманд, созданных в Word 6 и 7, может свести к минимуму количество возникающих при преобразовании проблем. Другие же проблемы решаются с помощью небольшой модернизации уже преобразованного кода. Кроме того, в Word 97 у вас есть возможность добавить к нему те функции, которые ранее были недоступны в WordBasic. Со временем весь код, выполняемый посредством объекта WordBasic, может быть заменен на VB-код, использующий объектную модель Word.

Листинг 1.  Макрокоманды Test1 и Test2 в среде Word 6.0 (WordBasic)

Макрокоманда Test1:

Sub MAIN
   ' Назначение переменной
   MyVariable$ = "Привет!"
   ' Вывод сообщения с использованием этой переменной
   MsgBox MyVariable$
   '
   ' Иллюстрация применения простейших операторов WordBasic
   '
   ' Создание нового файла
   FileNewDefault
   ' Вызов функции
   MyVariable$ = MyFunction$
   ' Выделение целого документа
   EditSelectAll
   ' Удаление содержимого документа
   EditClear
   ' Вставка нового текста с помощью переменной модуля
   Insert MyVariable$
   '
   ' Демонстрация противоречий, 
   ' которые возникают при использовании
   ' неразрешенных имен. Debug - это ключевое слово в VBA
   If Debug = 0 Then
      FileClose 2
   End If
End Sub

Function MyFunction$
   MyFunction = "Это - тестовый пример"
End Function
Макрокоманда Test2:

Sub MAIN
    ' Вставить значение символьный переменной в текст документа
    Insert Test1.MyFunction$
End Sub
Листинг 2. Макрокоманды Test1 и Test2 в среде Word 6.0 (WordBasic)
Макрокоманда Test1:

Option Explicit

Public Sub MAIN()
Dim MyVariable$
Dim Debug_
MySharedVariable$ = ""
   ' Назначение переменной
   MyVariable$ = "Привет!"
   ' Вывод сообщения с использованием этой переменной
   WordBasic.MsgBox MyVariable$
   '
   ' Иллюстрация применения простейших операторов WordBasic
   '
   ' Создание нового файла
   WordBasic.FileNewDefault
   ' Вызов функции
   MyVariable$ = MyFunction$
   ' Выделение целого документа
   WordBasic.EditSelectAll
   ' Удаление содержимого документа
   WordBasic.WW6_EditClear
   ' Вставка нового текста с помощью переменной модуля
   WordBasic.Insert MyVariable$
   '
   ' Демонстрация противоречий, которые возникают 
   ' при использовании неразрешенных имен. 
   ' Debug - это ключевое слово в VBA
   If Debug_ = 0 Then
      WordBasic.FileClose 2
   End If
End Sub

Private Function MyFunction$()
   MyFunction$ = "Это - тестовый пример"
End Function
Макрокоманда Test2:


Option Explicit

Public Sub MAIN()
    ' Вставить значение символьный переменной в текст документа
    WordBasic.Insert WordBasic.Call("Test1.MyFunction$")
End Sub

С Андреем Александровичем Колесовым и Ольгой Романовной Павловой можно связаться по телефону: (095)369-76-97 или по электронной почте: akolesov@glasnet.ru.