- •Разработка интегрированных прикладных программ
- •Введение
- •Интерфейсы в Delphi
- •Присоединение интерфейсов к формам
- •Объекты com
- •Контроллер позднего связывания (Delphi)
- •Контроллер на основе библиотеки типов (Delphi)
- •Контоллер на vba
- •Управление офисными приложениями
- •Ms Excel и компоненты библиотеки vcl
- •Работа с ячейками таблицы
- •Серверы ms Office и позднее связывание
- •Работа с серверами из Delphi (позднее связывание)
- •Элементы управления ActiveX
- •Создание ActiveX на основе компонентов vcl
- •Тестирование ActiveX
- •Тестирование с использованием vba
- •Создание активных форм
- •Добавление свойств и методов
- •Динамическое создание элементов управления ActiveX
- •Компонент oleContainer
- •Создание и сохранение нового объекта (внедрение)
- •Создание связанного объекта
- •Работа с сервером
- •Библиографический список
- •Оглавление
Серверы ms Office и позднее связывание
Приложения Microsoft Office созданы с соблюдением всех правил COM и поэтому обладают рядом свойств, обязательных для серверов автоматизации. Подробный перечень свойств можно найти в [3]. В табл. 1 перечислены только обязательные свойства и методы.
Таблица 1. Обязательные свойства и методы объекта втоматизации
Имя |
Чтение, запись |
Тип |
Смысл |
Application |
Только чтение |
IDispatch |
Приложение |
FullName |
Только чтение |
WideString |
Путь и имя приложения |
Name |
Только чтение |
WideString |
Краткое описание приложения |
Parent |
Только чтение |
IDispatch |
То же, что и свойство Application |
Visible |
Чтение и запись |
WordBool |
Видимость окна приложения |
Quit |
|
Метод |
Закрытие приложения |
В общем случае любой контроллер автоматизации (не только для офиса) должен проверить, запущена ли уже копия приложения-сервера, и решить, запускать ли новую копию или подключиться к имеющейся. После окончания работы с сервером закрыть приложение (если сервер был запущен контроллером) или отключиться от него. Рассмотрим программный код, который позволяет это сделать.
Создадим в C++Builder новое приложение с двумя кнопками (Button1-> Caption=Connect и Button2-> Caption=Disconnect). Включим в текст строку #include <ComObj.hpp>
Объявим логическую переменную, которая будет помнить, запустил ли контроллер приложение-сервер (true) или подключился к работающей копии (false): bool RunServer;
Вариантные переменные будут представлять в контроллере объекты сервера (приложение и коллекцию рабочих книг): Variant App, WorkBs;
Код обработчика первой кнопки попытается связаться с запущенной копией сервера, передав в качестве параметра строку, содержащую имя объекта автоматизации (ProgID – программные идентификаторы содержатся в реестре и независимы от версии). При неудаче возникнет системное исключение и тогда контроллер сам создаст объект автоматизации:
void __fastcall TForm1::Button1Click(TObject *Sender) {AnsiString AppProgID; AppProgID="Excel.Application"; RunServer=False; if (VarType(App)!=varDispatch) { try {App=GetActiveOleObject(AppProgID);} catch (EOleSysError&) {App=CreateOleObject(AppProgID);RunServer=true;} } if (VarType(App)==varDispatch) { App.OlePropertySet("Visible",true); WorkBs=App.OlePropertyGet("Workbooks"); WorkBs.OleProcedure("Add"); } }
Вторая кнопка закроет сервер (если контроллер его сам стартовал) и освободит указатели на все полученные интерфейсы:
void __fastcall TForm1::Button2Click(TObject *Sender) { if (RunServer) App.OleProcedure("Quit"); WorkBs=NULL; App=NULL; }
Если окно сервера видимо, то пользователь может непредсказуемо вмешаться в совместную работу приложений. Поэтому при создании контроллеров таких приложений не рекомендуется давать доступ конечному пользователю к интерфейсу сервера. Проще всего этого достичь, установив свойство Visible=false, а чтобы сервер не выводил на экран диагностические сообщения для пользователя, то установить свойство DisplayAlerts=false.
Контроллер на C++ Builder (позднее связывание)
Для организации позднего связывания контроллера с сервером MS Excel, естественно, понадобятся переменные типа Variant: AppE (объект Application), Workbs (коллекция рабочих книг), Workb (рабочая книга), Workshs (коллекция листов рабочей книги), Worksh (рабочий лист), work (ячейка таблицы). После создания приложения (объект Application) AppE=CreateOleObject ("Excel.Application"); с помощью метода OlePropertyGet можно получить доступ к другим объектам MS Excel:
Workbs=AppE.OlePropertyGet("Workbooks"); Workb=Workbs.OlePropertyGet("Item",1); Workshs=Workb.OlePropertyGet("Worksheets") ; Worksh=Workshs.OlePropertyGet("Item",2);
Для добавления нового объекта к коллекции (например, рабочей книги) используется процедура Add, для вызова которой придется использовать метод OleProcedure: Workbs.OleProcedure("Add");
Для изменения свойств используется метод OlePropertySet:
AppE.OlePropertySet("Visible",true); Workshs.OlePropertyGet("Item",1).OlePropertySet ("Name","Исходная таблица");
Доступ к ячейкам таблицы организуется совместной работой методов:
// запись значения в ячейку (числа или формулы) Worksh.OlePropertyGet("Cells").OlePropertyGet ("Item",3,1).OlePropertySet("Value",-34); Worksh.OlePropertyGet("Cells").OlePropertyGet ("Item",11,1).OlePropertySet ("Value","=СУММ(A1:A10)"); // оформление ячейки таблицы work=Worksh.OlePropertyGet("Cells").OlePropertyGet ("Item",3,2); work.OlePropertyGet("Font").OlePropertySet ("Color",clBlue); work.OlePropertyGet("Font").OlePropertySet ("Bold",true);
Для организации позднего связывания c MS Word также понадобятся переменные типа Variant: AppW (объект Application), WordDs (коллекция документов WordDocuments), WordD (документ Document), WordPars (коллекция Paragraphs), Rng (объект Range).
После создания приложения-сервера AppW=CreateOleObject ("Word.Application"); доступ к его свойствам (среди свойств есть и такие, которые представляют коллекции других объектов) можно получить через функцию OlePropertyGet:
WordDs=AppW.OlePropertyGet("Documents"); WordD=AppW.OlePropertyGet("ActiveDocument"); WordPars=WordD.OlePropertyGet("Paragraphs");
Для установки значений свойств используется OlePropertySet:
AppW.OlePropertySet("Visible",true); AppW.OlePropertySet("Width",200);
Для доступа к конкретному объекту коллекции документов или параграфов используется функция OleFunction, а для создания новых объектов необходимо использовать метод OleProcedure, например:
WordD = WordDs.OleFunction ("Item",2); WordDs.OleProcedure("Add"); WordPars.OleProcedure("Add");
Для работы с документом потребуется сочетание перечисленных функций и методов:
//получение количества документов и активизация документа int j=(int) (WordDs.OlePropertyGet("Count")); WordD =WordDs.OleFunction ("Item",2).OleProcedure ("Activate"); // доступ к частям документа Rng=WordD.OleFunction("Range",10,15); Rng= WordPars.OleFunction ("Item",1). OlePropertyGet("Range"); // вставка текста в документ Rng.OleProcedure("InsertBefore","Текст 1"); WordPars.OleFunction("Item",1).OlePropertyGet("Range"). OleProcedure("InsertAfter","Текст 33"); // изменение цвета букв Rng.OlePropertyGet("Font").OlePropertySet("Color",clRed);