Разработка интегрированных прикладных программ (Меньшикова К. Г.) (Разработка интегрированных прикладных программ (Меньшикова К. Г.))

Посмотреть архив целиком

С++Builder и Delphi поддерживают работу со многими распространенными приложениями, предлагая программистам соответствующие компоненты. Офисные компоненты чаще всего располагаются на странице Servers (хотя возможно, что в названии используется номер офисной версии). В любом случае при разработке сложных приложений надо решить вопрос совместимости версий Windows, Microsoft Office и инструментариев разработки, иначе переносимость таких приложений может быть очень ограничена.

Компонент ExcelApplication задает приложение Excel, его свойства, методы и события характеризуют приложение в целом. Его свойство Workbooks определяет коллекцию рабочих книг (все открытые в приложении рабочие книги).

Компонент ExcelWorkbook задает рабочую книгу и, в свою очередь, имеет свойство Worksheets – все рабочие листы книги. Компонент Worksheet – это конкретный лист рабочей книги.

Установить связь с физическим объектом можно так:

ExcelApplication1->Connect();
ExcelWorkbook1-> ConnectTo (ExcelApplication1 ->
ActiveWorkbook);
ExcelWorksheet1 -> ConnectTo (ExcelWorkbook1->
ActiveSheet);
ExcelWorksheet2 -> ConnectTo (ExcelWorksheet1 ->
get_Next());

Для вызова некоторых методов и свойств используется специальная константа - LOCALE_SYSTEM_DEFAULT (lcid); ее значение равно 0. Например, можно сделать окно Excel видимым (или невидимым, если параметр равен false):

#define lcid LOCALE_SYSTEM_DEFAULT
ExcelApplication1->set_Visible(lcid,true);

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

int n= ExcelApplication1-> Workbooks-> Count;

и методам, например, открыть и добавить новую книгу

WideString filename="d:/work.xls";
ExcelApplication1->Workbooks->Open(filename);
ExcelApplication1->Workbooks -> Add();

Сохранить рабочую книгу или сделать рабочий лист активным можно с помощью соответствующих компонент:

ExcelWorkbook1->Save(lcid);
ExcelWorksheet2 ->Activate (lcid);

При работе с офисными компонентами используется раннее связывание. Компилятор, конечно, четко отслеживает типы передаваемых параметров. Однако иногда необходимо или удобно его “обмануть”, упаковав данные в формат TVariant. Например, зададим имена листов:

WideString str; str="MyList 1";
ExcelWorksheet1->set_Name(str);
ExcelWorksheet2->set_Name((TVariant)"MyList 2");

Работа с ячейками таблицы

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

ExcelApplication1->ActiveCell->set_Value((TVariant)"a");

В Excel ячейки таблицы рассматриваются как двумерный массив Cells(<номер строки>,<номер столбца>). Для получения доступа к этому массиву в Builder C++ используется метод get_Cells().

С помощью методов set_Item(<номер строки>, <номер столбца>, <значение>) и get_Item(<номер строки>, <номер столбца>) можно записывать и извлекать значения элементов с указанными индексами. Например:

// число 222 записывается в ячейку с номерами (1,1):
ExcelWorksheet2 -> get_Cells()->
set_Item((TVariant)1,(TVariant)1,(TVariant)"222");
// для записи формулы используется функция:
ExcelWorksheet2 -> get_Cells()->
set_Item((TVariant)5,(TVariant)1,(TVariant)
"=СУММА(A1:A3");
// из ячейки (1,4) извлекается значение:
k = (TVariant)ExcelWorksheet2 -> get_Cells()->
get_Item((TVariant)1,(TVariant)4);

Объект Range рабочего листа ExcelWorksheet предоставляет удобный доступ к таблице и позволяет работать с ячейкой таблицы, диапазоном ячеек, прямоугольной областью. Приведем примеры его использования:

// в ячейку B1 занести число 4:
ExcelWorksheet1->get_Range((TVariant)"B1",
(TVariant)"B1")->set_Value((TVariant)4);
// в ячейки с3-с6 записать формулы:
ExcelWorksheet2->get_Range((TVariant)"с3",(TVariant)"с6") -> set_Value((TVariant)"=a3+b3");

Когда формула присваивается диапазону ячеек, то переменные в формуле имеют относительные имена, поэтому в предыдущем примере в ячейку c4 будет вписана формула “=a4 +b4” и т.д.

// Получение значения из ячейки b5:
TVariant y; y=ExcelWorksheet2->get_Range((TVariant)"b5",
(TVariant)"b5") -> get_Value();
// Удаление содержимого диапазона ячеек:
ExcelWorksheet2 -> get_Range
((TVariant)"D1",(TVariant)"D3") -> Clear();
// Копирование через буфер обмена:
ExcelWorksheet2 -> get_Range
((TVariant)"A1",(TVariant)"B3") -> Copy();
ExcelWorksheet2 -> get_Range
((TVariant)"A7",(TVariant)"B9") -> Select();
ExcelWorksheet2 -> Paste();

При переходе от одного объекта Range к другому, например от одной ячейки к другой, отстоящей от первой на определенное расстояние, можно использовать смещение. Достигается это благодаря методу Offset объекта Range. Метод имеет два параметра: смещение по строкам и столбцам, и возвращает новый объект Range, отстоящий от прежнего на заданное расстояние.

Например, следующий оператор задает запись в ячейку, отстоящую от “b5” на (–1, 3), то есть в ячейку “e4”:

ExcelWorksheet2-> get_Range ((TVariant)"b5",
(TVariant)"b5") -> get_Offset ((TVariant)-1,(TVariant)3)
->set_Value((TVariant)"=b5+d4");

Оформление ячеек таблицы можно выполнить так:

// выделение курсивом
ExcelWorksheet2 -> get_Range ((TVariant)"A1", (TVariant)"E5")->get_Font()->set_Italic((TVariant)true);
//
выравнивание
ExcelWorksheet2->get_Range ((TVariant)"D1", (TVariant) "E3")-> set_HorizontalAlignment((TVariant)xlCenter);
//
изменение цвета букв:
ExcelWorksheet2 -> get_Range((TVariant)"D1", (TVariant) "E3")-> get_Font()-> set_Color((TVariant)0x00FF0000);
//
заливка цветом:
ExcelWorksheet2 -> get_Range((TVariant)"A1",(TVariant) "B7")-> Interior-> set_Color((TVariant)RGB(0,128,200));

Работа с сервером Word организуется аналогичным образом. Среди основных компонент - WordApplication, WordDocument, WordFont и WordParagraphFormat. Примеры работы с ними можно найти в [1].

    1. Серверы 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

Объявим логическую переменную, которая будет помнить, запустил ли контроллер приложение-сервер (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.

    1. Контроллер на C++ Builder (позднее связывание)

Для организации позднего связывания контроллера с сервером MS Excel, естественно, понадобятся переменные типа Variant: AppE (объект Application), Workbs (коллекция рабочих книг), Workb (рабочая книга), Workshs (коллекция листов рабочей книги), Worksh (рабочий лист), work (ячейка таблицы). После создания приложения (объект Application) AppE=CreateOleObject ("Excel.Application"); с помощью метода OlePropertyGet можно получить доступ к другим объектам MS Excel:


Случайные файлы

Файл
ref-16069.doc
175400.rtf
EGIPET.doc
90606.rtf
133251.rtf




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