Работа с Exсel из приложения, написанного на C++Builder   (часть 3)
Итак, начинаем третий урок по работе с Excel из C++Builder.
Мы рассмотрим работу с шаблонами (.xlt) и использование макросов.

В предыдущих уроках мы сами формировали отчет в Excel, от начала и до конца,
но это не всегда удобно, иногда проще создать нужную форму отчета (шаблон .xlt),
а уже потом выводить в нее данные (например из базы данных).
Особенно это удобно, если форма отчета может незначительно измениться,
тогда нет необходимости вносить изменения в проект на C++Builder,
достаточно будет лишь изменить шаблон.
Кроме того, часть информации рассчитывается по формулам, записанным в шаблон,
и при изменении этих формул, также нет необходимости вносить изменения
в проект на C++Builder,достаточно изменить формулу в шаблоне.

Давайте рассмотрим этот вариант.

У нас есть некая база данных, и в ней таблица поставщиков SaleMan
и связанная с ней таблица товаров Goods, которые они поставляют.
Создадим на их основе отчет "Счет-фактура" и "Накладная" по
выбранному поставщику.

Оба отчета будут использовать один шаблон (.xlt) и выводиться в один файл (.xls)
(на одном листе WorkSheets 1 — Счет-фактура, на другом WorkSheets 2 — Накладная)
Создадим шаблон отчета (рассмотрите прилагаемый файл NaclSf.xlt)
Всем полям, в которые будут выводиться данные, дадим интуитивно понятные
имена.

Например: НомерНАКЛ , ДатаНАКЛ, ПоставщикНАКЛ, ИННПНАКЛ, НомерСФ , ДатаСФ и др.

Формат таблиц SaleMan и Goods следующий:

SaleMan

ID integer ID поставщика
Org string Hазвание организации-поставщика
Addr string Адрес поставщика
InnOrg string ИНН постащика

Goods

ID integer ID товара
IDSale integer поставщик товара
Name string наименование товара
Izmer string единица измерения
Count float количество
Price float цена за ед изм

---

Разумеется это крайне обрезанный и упрощенный вариант, удобный для примера.

Variant App, Sh;
TDate Today = Now();

// устанавливаем путь к файлу шаблона
AnsiString sFile = GetCurrentDir()+"\\NaclSf.xlt";

// инициализируем Excel, открываем этот шаблон
try {
App=Variant::GetActiveObject("Excel.Application");
} catch(...) {
try { App=Variant::CreateObject("Excel.Application"); }
catch (...) {
Application->MessageBox("Невозможно открыть Microsoft Excel!"
" Возможно этого приложения на компьютере не установлено.","Ошибка",MB_OK+MB_ICONERROR);
}}
try {
App.OlePropertyGet("WorkBooks").OleProcedure("Open",sFile.c_str(),0,false,1);
Sh=App.OlePropertyGet("WorkSheets",1);
} catch(...) {
Application->MessageBox("Ошибка открытия книги Microsoft Excel!","Ошибка",MB_OK+MB_ICONERROR);
}

// выводим в шаблон данные
// сначала заголовок
toExcel(App,"НомерНАКЛ",SaleManID->Value);
toExcel(App,"ДатаНАКЛ",Today.DateString());
toExcel(App,"ПоставщикНАКЛ",SaleManOrg->Value.c_str());
toExcel(App,"ИННПНАКЛ",SaleManInn->Value.c_str());

toExcel(App,"НомерСФ",SaleManID->Value);
toExcel(App,"ДатаСФ",Today.DateString());
toExcel(App,"АдресПСФ",SaleManAddr->Value.c_str());
toExcel(App,"ПоставщикСФ",SaleManOrg->Value.c_str());
toExcel(App,"ИННПСФ",SaleManInn->Value.c_str());

// определяем в n количество товара (строк для ввода в шаблон)
Goods->First();
int n = 0; while(!Goods->Eof) { n++; Goods->Next(); }
// или int n = Goods->RecordCount;

// вставляем в шаблон нужное количество строк
Variant C;
App.OlePropertyGet("WorkSheets",1).OleProcedure("Select");
C=App.OlePropertyGet("Range","ТоварСФ");
C=App.OlePropertyGet("Rows",(int) C.OlePropertyGet("Row")+1);
for(int i=1;i<n;i++) C.OleProcedure("Insert");

App.OlePropertyGet("WorkSheets",2).OleProcedure("Select");
C=App.OlePropertyGet("Range","ТоварНАКЛ");
C=App.OlePropertyGet("Rows",(int) C.OlePropertyGet("Row")+1);
for(int i=1;i<n;i++) C.OleProcedure("Insert");

// вывод данных из накладной в эти строки
Goods->First();
int i = 0;
while(!Goods->Eof){
toExcel(App,"ТоварСФ",i,GoodsName->Value.c_str());
toExcel(App,"ТоварНАКЛ",i,GoodsName->Value.c_str());
toExcel(App,"НомерППНАКЛ",i,i+1);
toExcel(App,"СтранаСФ",i,"Россия");
toExcel(App,"ЕдизмСФ",i,GoodsIzmer->Value.c_str());
toExcel(App,"ЕдизмНАКЛ",i,GoodsIzmer->Value.c_str());
toExcel(App,"КолСФ",i,GoodsCount->Value);
toExcel(App,"КолНАКЛ",i,GoodsCount->Value);
toExcel(App,"ЦенаСФ",i,GoodsPrice->Value);
toExcel(App,"ЦенаНАКЛ",i,GoodsPrice->Value);
toExcel(App,"СтоимСФ",i,GoodsPrice->Value*GoodsCount->Value);
toExcel(App,"СтоимостьСНДССФ",i,(GoodsPrice->Value*GoodsCount->Value*5)/100.);
toExcel(App,"ВсегоНАКЛ",i,GoodsPrice->Value*GoodsCount->Value);
toExcel(App,"СуммаНДССФ",i,(GoodsPrice->Value*GoodsCount->Value*5)/100.);
toExcel(App,"СуммаНДСНАКЛ",i,(GoodsPrice->Value*GoodsCount->Value*5)/100.);
i++; Goods->Next();
}

// и наконец, делаем Excel видимым
App.OlePropertySet("Visible",true);

Полный проект примера к C++Builder 6 с шаблоном и таблицами можно скачать здесь (12 Кб)

----

Теперь об использовании макросов.

Практически любые наши действия в Excel могут быть описаны с помощью макросов.
Создадим и запишем в шаблоне новый макрос, дадим ему имя. (например MyMacros1)
Всё !!!
Теперь запустим макрос на выполнение

App.OleProcedure("Run","MyMacros1");

и необходимые действия из макроса будут выполнены.
Разумеется, нужно, чтобы эти макросы были подготовлены заранее
и сохранены в шаблоне, а уже при формировании отчета (.xls) на
основании этого шаблона (.xlt), макросы можно будет применять.

Все замечания и предложения и добавления: support@cbuilder.ru
Если Вы используете Excel или Word в работе с C++Builder,
присылайте примеры, проекты и интересные решения нам,
а также если у вас остались вопросы — спрашивайте.