среда, 14 марта 2012 г.

Урок 33. Оборотная ведомость - экспорт в Excel



Когда-то давно, в самом начале тревожных 90-х, когда я писал свою первую бухгалтерскую настоящую большую программу, постановщик задачи, мой коллега и друг, задал такую идею: хорошо было бы, если бы программа могла бы из одних и тех же цифр складывать несколько разных главных книг: одну - для налоговой, одну - для акционеров, одну - самую полную и правильную... и одну - для души...


Не смотря на то, что потом было еще много "хочу" разной сложности от постановщиков задач, с тех давних пор эта идеология живет вместе со мной.

Только решать задачку складывания одних и тех же цифр в различные результаты (=отчеты), сейчас стало на много проще. Для этого существуют универсальные программы, например: Excel.

Итак, в предыдущем уроке я показал как составить и вывести на экран оборотную ведомость. В таком виде можно посмотреть только небольшой отчет, пару каких-то конкретных цифр. Работать, а тем более изменять информацию на экране, добавлять оформление и т.п. невозможно.

Для того, чтобы экспортировать данные из экранного представления прикладной программы "Расходы", добавьте для начала контекстное меню для формы OborotFrm с одним пунктом "Экспорт":

Подготовьте обработчик события нажатия на этот пункт меню.

Тут я хочу сделать небольшое отступление, озадачив всех вопросом: где располагать процедуру экспорта: в данной форме или в модуле главной формы? В принципе - решать Вам, но! Если эта процедура будет универсальной, способной выполнять возложенные на нее функции не только для отчета "Оборотная ведомость", то удобнее ее расположить в модуле главной формы. Более того, если эта процедура окажется на столько универсальна и хороша, что сможет обслуживать не только эту программу, но и многие другие, тогда ей место - в отдельно лежащей библиотеке, например: в файле Dll, но об этом - несколько позже.

А пока - добавьте в форме OborotFRM Вот такой обработчик:



procedure TOborotFrm.N_ExportClick(Sender: TObject);
begin


  // Экспорт в Эксель
  MainFrm.ExportTo('ОВ', DBGridEh1, MainFrm.XLApp, 'Оборотная ведомость', 'Период: '+FormatDateTime('dd/mm/yy',Date_N.Value)+' - '+FormatDateTime('dd/mm/yy',Date_K.Value));


end;

Что здесь "что", перечислю параметры: название книги Excel, ссылка на GridEh, ссылка на неизвестный нам пока компонент, который еще предстоит расположить в главной форме, заголовок документа, подзаголовок.

На этом форму Oborot можно пока закрыть, поскольку все дальнейшие манипуляции будут происходить в форме MainFrm.


Для начала расположите на ней экземпляр компонента TExcelApplication c вкладки Servers, дав ему имя XLApp.


Затем (внимание!) в секции общедоступных объявлений опишите процедуру:



  public
    { Public declarations }
    Procedure ExportTo(p_WorkSheetName: String;  p_PGridEh: TDBGridEh;  p_XLApp: TExcelApplication;
                          p_RepName: String; p_RepSubTitle: String);


А теперь - собственно цель урока - процедура вывода данных:

Procedure TMainFrm.ExportTo(p_WorkSheetName: String; p_PGridEh: TDBGridEh; p_XLApp: TExcelApplication; p_RepName: String; p_RepSubTitle: String);


var WorkBk: _WorkBook; // определяем WorkBook (книгу) WorkSheet: _WorkSheet; // определяем WorkSheet (лист) I, J: Integer; // Вспомогательные переменные SavePlace: TBookmark; // Закладка begin // Вывод данных из источника объекта DBGridEh в Excel try // Установка закладки (чтобы позже вернуть на нее указатель в сетке) SavePlace := p_PGridEh.DataSource.DataSet.GetBookmark; // Соединяемся с сервером TExcelApplication p_XLApp.Connect; // Добавляем WorkBooks в ExcelApplication p_XLApp.WorkBooks.Add(xlWBatWorkSheet, 0); // Выбираем первую WorkBook WorkBk := p_XLApp.WorkBooks.Item[1]; // Определяем первый WorkSheet WorkSheet := WorkBk.WorkSheets.Get_Item(1) as _WorkSheet; // Заполняем свойства WorkSheet WorkSheet.Name := p_WorkSheetName; // Заголовок отчета J := 1; Worksheet.Cells.Item[J,1].Value:= p_RepName; Worksheet.Cells.Item[J,1].Font.Bold := True; Worksheet.Cells.Item[J,1].Font.size := 16; // Указание периода J := 2; Worksheet.Cells.Item[J,1].Value:= p_RepSubTitle; Worksheet.Cells.Item[J,1].Font.Italic := True; // Заголовки колонок J := 3; p_PGridEh.DataSource.DataSet.First; with p_PGridEh.Columns do begin for i := 1 to Count do if Items[I-1].Visible then begin Worksheet.Cells.Item[J,I].Value:= Items[I-1].Title.Caption; Worksheet.Cells.Item[J,I].Font.Bold := True; Worksheet.Cells.Item[J,I].HorizontalAlignment := xlCenter; end; end; // Собственно вывод данных из источника под сеткой в Excel J := 4; with p_PGridEh.DataSource.DataSet do begin First; while not Eof do begin with p_PGridEh.Columns do begin for I := 1 to Count do if Items[I-1].Visible then Worksheet.Cells.Item[J,I].Value:=FieldByName(Items[I-1].FieldName).AsVariant; end; Inc(J, 1); next; end; end; WorkSheet.Columns.ColumnWidth := 25; // Показываем Excel p_XLApp.Visible[0] := True; // Разрываем связь с сервером p_XLApp.Disconnect; // Возврат на закладку p_PGridEh.DataSource.DataSet.GotoBookmark(SavePlace);


// Удаление закладки p_PGridEh.DataSource.DataSet.FreeBookmark(SavePlace); Except MyMessenger.TitleString:='Проблема'; MyMessenger.MessageString:='Возможно, в Вашем компьютере не установлен MS Excel'; MyMessenger.Buttons:=[mbOk]; MyMessenger.ShowMessage; end; end;

Как всегда я достаточно много вписал комментариев в текст процедуры, но,если все же у Вас остались вопросы, и Вы не получили XLS файла, похожего на этот:


то я, как всегда, жду Ваших вопросов:


мои координаты Вы найдете тут.





Комментариев нет:

Отправить комментарий