Итак, начинаем третий урок по работе с 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,
присылайте примеры, проекты и интересные решения нам,
а также если у вас остались вопросы — спрашивайте.
|