Как из stringgrid вывести данные в excel
Перейти к содержимому

Как из stringgrid вывести данные в excel

Как из stringgrid вывести данные в excel

Очень многие документы создаются и хранятся в формате электронных таблиц Microsoft Excel. Несмотря на то, что эти таблицы обладают возможностями для автоматической обработки документа, нам, дельфистам, гораздо приятнее работать в привычной среде, что которая и обладает к тому же гораздо более развитыми возможностями. Давайте посмотрим, как получать данные из Excel. Естественно, табличные данные будем размещать в привычную нам таблицу StringGrid.

Для работы с Excel и другими программами из пакета Microsoft Office необходимо добавить в список uses модуль ComObj:

unit Unit1;

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Grids, ComObj;

Далее, описываем глобальную переменную типа Variant:

var
Form1: TForm1;
Excel: Variant;

Далее, нужно создать объект Excel. Excell Application создаётся пустым, без таблиц, поэтому необходимо добавить хотя бы одну книгу. Делать это нужно в каком-либо обработчике, например обработчике нажатия кнопки, хотя можно и сразу в OnCreate Формы:

Если создаётся пустая книга, метод Add применяется без параметра — без имени файла. Естественно, можно предложить пользователю выбрать файл:

with OpenDialog1 do
if Execute then
Excel.Application.WorkBooks.Add(FileName);

Для отладки необходимо, чтобы таблица Excel была видимой, а также лучше запретить задавать вопросы о сохранении данных при закрытии:

Excel.Visible:=True; //После отладки можно закомментировать эту строку
Excel.DisplayAlerts:=False;

Сразу создайте метод закрытия объекта Excel, иначе при отладке, да и при работе пользователя в компьютере наплодится столько невидимых процессов Excel, что мама дорогая. В обработчике OnCloseQuery Формы напишите:

try
Excel.Quit;
except
end;
CanClose:=True;

Естественно, будет произведён выход из Excel, и затем закроется всё приложение. Но если нам нужно после закрытия процесса Excel продолжить работу с программой, то этот код помещается в обработчик нажатия кнопки. Однако, в данном случае его недостаточно. Попробуйте, и вы убедитесь, взглянув в список процессов в Диспетчере Задач, что наш процесс Excel жив и здоров! Это произошло потому, что он остаётся связанным с переменной, его создавшей (Excel же). Для реального уничтожения процесса нужно разорвать эту связь. Дополните вышеприведённый код строкой:

и при нажатии кнопки закрытия наш Excel исчезнет из списка процессов.

Теперь нужно получить данные из Excel. В Excel столбцы именуются буквами, но мы в Delphi обращаемся к ним привычно, по порядковым номерам. Обратите внимание, что, поскольку в Delphi первым в индексе идёт индекс столбца, а в таблице Excel индекс строки, то индексы должны быть расположены на противоположных местах. В обработчике нажатия кнопки:

with StringGrid1 do
for i:=1 to RowCount-1 do
for j:=1 to ColCount-1 do
Cells[j, i]:=Excel.WorkSheets.Item[‘Лист1’].Cells[i, j];

Маленькое предупреждение: если при отладке проверять внесение данных, то перед нажатием нашей кнопки нужно завершить ввод в Excel — нажать Enter. Ведь если ячейка таблицы Excel останется в режиме редактирования, то мы получим отказ от Excel.
И ещё. Данные в Excel адресуются начиная с 1. Попытка получить содержимое фиксированных ячеек не удаётся. Поэтому фиксированные ячейки в таблице StringGrid при необходимости нужно заполнять самому, отдельно.

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

var S1, S2: String;
begin
S1:=Excel.WorkSheets.Item[‘Лист1’].Cells[5, 6];
S2:=Excel.WorkSheets.Item[‘Лист1’].Range[‘F5’];
end;

В переменных S1 и S2 будет одинаковое значение.

Теперь в таблице StringGrid мы имеем данные для обработки, и делаем с ними что хотим. Затем можно перенести обработанные данные назад в таблицу Excel. Делается это совершенно аналогично, в обработчике нажатия другой кнопки:

for i:=1 to Grid.RowCount-1 do
for j:=1 to Grid.ColCount-1 do
Excel.WorkSheets.Item[‘Лист1’].Cells[i, j]:=Grid.Cells[j, i];

Если эти операции производятся с активным листом Excel, то можно сократить написание, и вместо:

Или можно создать переменную и присвоить ей значение того листа Excel, с которым производится работа:

var Sheet: Variant;
S1, S2: String;
begin
Sheet:=Excel.WorkSheets.Item[‘Лист1’];
S1:=Sheet.Cells[5, 6];
S2:=Sheet.Range[‘F5’];
end;

Только имейте в виду, что таблица может содержать не только данные непосредственно в ячейках, но и формулы. При записи данных из нашей таблицы StringGrid всё, кроме непосредственно записываемого текста, будет уничтожено!

Напоследок нужно заставить таблицу Excel сохранить обработанные данные:

Excel.ActiveWorkbook.SaveAs(‘Имя_Файла’);// Или SaveAs(‘OpenDialog1.FileName’);

Можно вывести отчёт на печеть. Вот как задана функция печати:

function PrintOut(
From: Variant; //Необязательно. Номер срааницы с которой начинается печать.
To: Variant; //Необязательно. Номер страницы по какую продолжается печать.
Copies: Variant; //Необязательно. Количество копий.
Preview: Variant; //Необязательно. Предварительный просмотр (True или False).
ActivePrinter: Variant; //Необязательно. Имя активного принтера.
PrintToFile: Variant; //Необязательно. При значении True печать будет идти в файл.
Collate: Variant //Необязательно. При значении True копии страниц объединяются.
): Workbook;

Воспользоваться этой функцией можно как методом переменной, указывающей страницу — Sheet (также Excel.ActiveWorkBook или Excel.WorkSheets):

Sheet.PrintOut(1, 1, 1, False, True);

Будет произведён вывод на печать с первой страницы по первую, одной копии, без предварительного просмотра, без указания принтера — печать идёт в файл. Предварительно будет выдан запрос на указание имени файла. Создаётся файл типа *.xps. Для его просмотра нужны специальные программы.

Естественно, в Delphi можно осуществлять также и форматирование ячеек, и другие операции с таблицей Excel. Эту информацию добавлю чуть позже. А пока на первый раз достаточно.

Работа с регионом ячеек Excel

Продолжить хочу с того факта, что операции чтения и записи данных по одной ячейке занимают довольно много времени — вы уже и сами наверное заметили. Есть способ ускорить этот процесс. Для этого нужно освоить несложные операции работы с регионом ячеек Excel.

Регион ячеек таблицы Excel также имеет тип Variant и задаётся прямоугольником, с указанием левой верхней и правой нижней ячеек:

var Range: Variant;
begin
Range:=Excel.Range[Excel.Cells[1, 1], Excel.Cells[100, 100]];
end;

В частности, регион может состоять и из одной ячейки:

Range:=Excel.Range[Excel.Cells[1, 1], Excel.Cells[1, 1]];

Эту запись проще выполнить с указанием адреса как в таблице Excel:

Также можно задать и прямоугольный регион, если вам известны имена ячеек. Вот регион 4х4:

А вот как выполнить перепись региона 100Х100 ячеек Excel в таблицу StringGrid:

var Range: Variant;
i, j: Integer;
begin
Range:=Excel.Range[Excel.Cells[1, 1], Excel.Cells[100, 100]];
with StringGrid1 do
for i:=1 to 100 do
for j:=1 to 100 do
Cells[i, j]:=Range.Cells[j, i];
end;

Вот и всё! На моём компьютере, эта операция переписи региона 100х100 ячеек Excel в таблицу StringGrid длится около 300 мсек, что на 2 порядка быстрее, чем чтение и запись по одной ячейке.

А, например, операция занесения какого-либо одного значения во все ячейки региона выполняется ещё проще. Занесём в наш вышеопределённый регион 100х100 слово ‘Привет’ :

Как из stringgrid вывести данные в excel

Пример процедуры экспорта из StringGrid в Excel

unit Unit1;

Windows, Messages, SysUtils , Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls , Grids, ComObj ;

TForm1 = class( TForm )

StringGrid1: TStringGrid ;

Button1: TButton ;

procedure Button1Click(Sender: TObject );

Form1: TForm1;

dir_ :string ;

implementation

procedure TForm1.Button1Click(Sender: TObject );

Excel, WorkBook , Sheet :variant ;

i , j: integer;

GetDir ( 0, dir_); // определяем текущий каталог

Excel := CreateOleObject (‘ Excel.Application ‘);

Excel.DisplayAlerts :=False;

Excel.Visible := True;

Workbook := Excel.

Workbooks.Add ;

Workbook.SaveAs ( dir_ + ‘\temp.xls’); //c охраняем файл temp.xls

Sheet := Workbook.ActiveSheet ;

for i := 1 to StringGrid1.RowCount — 1 do

for j:= 1 to StringGrid1.ColCount — 1 do

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *