Zeroes and Ones - портал высоких технологий - Программирование MS Excel с помощью стандартных компонентов ExcelApplication ( ЧАСТЬ 3 )
Новости
Главная
Software
Hardware
Mobile
Наши новости
Техника
Электроника
Программирование
Delphi
HTML / CSS
*NIX
Дополнительно
О нас
Контакты
Последние новости

 


Опросы

Я за процессоры:



Популярное


Реклама


Партнеры
Программирование MS Excel с помощью стандартных компонентов ExcelApplication ( ЧАСТЬ 3 )
Автор Albinos_X   
07.05.2007 г.
 
 Наверное многие программисты сталкивались с такой проблемой, как создание отчёта. Репортинговых систем сейчас предостаточно, но всё таки, если нужно использовать или включать как дополнительную опцию для вывода отчёта установленный на компьютере заказчика MS Excel. Или наоборот нужно не выводить данные в таблицу, а брать оттуда какие либо данные, автоматизировать обработку данных хранящихся в таблице.
Данная статья поможет Вам разобраться в принципах работы с MS Excel, сэкономить Ваше драгоценное время и полезна для ознакомления не только начинающим, но и опытным программистам. Статья периодически обновляется, добавляются новые нюансы, способы работы с документом и примеры.

В этой части описывается:
 
  • Закрытие книги
  • Особенности при работе с Excel
  • Счисление
  • Ускорение работы программы с Excel
  • Пример 


Закрытие книги
Для закрытия книг(и) в арсенале есть метод Close, если нам требуется закрыть все книги, то достаточно сделать так:

...
ExcelApplication1.Workbooks.Close(lsid);
...


Если же требуется закрыть конкретную книгу, то так:

...
ExcelApplication1.Workbooks[i].Close(SaveChanges,EmptyParam,EmptyParam,lcid);
...


первый параметр определяет сохранять ли изменения, если True - значит сохранять,
во втором параметре указывается имя файла в который необходимо сохранять изменения, если SaveChanges:=True и второй не указан, то появится диалог сохранения файла. Если вместо SaveChanges поставить EmptyParam, то пользователя спросят, нужно ли сохранить изменения. Хотя я слышал, что бывает, что срабатывает SaveChanges:=EmptyParam и SaveChanges:=false одинаково, и оба спрашивают, нужно ли сохранять изменения. Третий параметр используется, когда книга предназначена для пересылки какому-то адресату.

Особенности при работе с Excel
Как и Word, помощь написании программы Вам может оказать сам Excel. Для этого надо в Word зайти в меню Сервис/Макрос/Начать запись. Потом сделать в Excel то, что надо сделать из Delphi и закончить запись макроса. И наконец Сервис/Макрос/Макросы. Выбираем записанный. Изменить и смотрим, как он устроен. Ну и так же справка VBA, тоже окажет Вам помощь.
Также хотелось бы отметить, что для работы с сервером, книгой и листом целесообразней создавать отдельные переменные (объекты). К примеру:


ExcelApplication1.AutoConnect:=true;
ExcelWorkbook1.ConnectTo(ExcelApplication1.Workbooks.Add(EmptyParam,lcid));
ExcelWorksheet1.ConnectTo(ExcelApplication1.ActiveWorkbook.ActiveSheet as ExcelWorkSheet);


И работать уже конкретно, с соответствующими переменными. Обращение к книге (листу, ячейки) через ExcelApplication может вызвать нежелательные последствия, такие как ошибка доступа к объекту или считывание/запись не в предполагаемое место, т.к. пользователь может во время работы программы открыть другую книгу Excel и соответственно, если мы работаем через ActivWorkbook, то программа “сменит адресат”, тоже самое, если мы будем действовать так: ExcelApplication1. Workbooks[0]… Нужная книга может сменить свой индекс. Привязка же книги и листа к конкретным переменным и работа через них позволит нам избежать подобных проблем.


Счисление
Отмечу несколько моментов:
1. Все отчисления производятся не от 0, а от 1.
2. Количество столбцов не может превышать 255
3. Количество строк не может превышать 65536


Ускорение работы программы с Excel
Ускорение работы программы мы можем обеспечить за счёт сокращения числа обращений к серверу. В решении этого вопроса можно использовать вариантные массивы. К примеру запись:

...
var MyRange,V:OleVariant;
...
MyRange:=ExcelWorksheet1.Range['A2','C4'];
V:=VarArrayCreate([0,2,0,2], varVariant);
V[0,0]:=4;
V[0,1]:=6;
V[0,2]:=1;
V[1,0]:=8;
V[1,1]:=9;
V[1,2]:=0;
V[2,0]:=5;
V[2,1]:=7;
V[2,2]:=3;
MyRange.Value:=V;
...


В этом случае мы будем обращаться к серверу не 9 раз, а только 2 раза. При переносе существенных объемов данных. Ускорение должно быть существенным. Аналогично мы можем читать:


var lcid :integer;
ActivCol, ActivRow, BeginDataRow :integer;
j, k :Integer;
MyRang, OleMas:OleVariant;
...
lcid:=LOCALE_USER_DEFAULT;
...
ActivCol:=ExcelWorksheet1.UsedRange[lcid].Columns.Count;
ActivRow:=ExcelWorksheet1.UsedRange[lcid].Rows.Count;
...
OleMas:=VarArrayCreate([0,(ActivCol),0,(ActivRow)], varVariant);
MyRang:=ExcelWorksheet1.Range['A1', AddresColExcel(ActivCol+1)+inttostr(ActivRow+1)];
OleMas:=MyRang.Value;
for j:=0 to (ActivRow-BeginDataRow) do
for k:=0 to ActivCol do
StringGrid1.Cells[k,j]:=OleMas[j+1+BeginDataRow,k+1];


BeginDataRow - первая строка с которой необходимо считывать...
Только вот обратный процесс (чтение) может вызвать некоторые проблемы, т.к. его поведение немного отличается от способа записи.

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

следующий код считывает из ячейки А1 и записывает в ячейку [1,1] Table: TStringGrid:

...
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExcelXP, OleServer, Grids;
type
TForm1 = class(TForm)
ExcelApplication1: TExcelApplication;
ExcelWorksheet1: TExcelWorksheet;
ExcelWorkbook1: TExcelWorkbook;
OpenDialog1: TOpenDialog;
Button1: TButton;
Table: TStringGrid;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var V:OleVariant;
begin
if OpenDialog1.Execute then
begin
// запускаем Excel
ExcelApplication1.AutoConnect:=true;
// открываем книгу
ExcelWorkbook1.ConnectTo(ExcelApplication1.Workbooks.OpenXML(OpenDialog1.FileName,EmptyParam));
// соединяемся с книгой
ExcelApplication1.ConnectTo(ExcelWorkbook1.Application);
ExcelWorksheet1.ConnectTo(ExcelWorkbook1.ActiveSheet as ExcelWorksheet);
// делаем видимым Excel
ExcelApplication1.Visible[0]:=true;
// считываем ячейку
v:=ExcelWorksheet1.Range['A1',EmptyParam];
// записываем в таблицу
Table.Cells[1,1]:=V;
// выходим из Excel
ExcelApplication1.Quit;
end;
end;
...


теперь если надо записывать в БД :

...
procedure TForm1.Button1Click(Sender: TObject);
var V:OleVariant;
begin
if OpenDialog1.Execute then
begin
// запускаем Excel
ExcelApplication1.AutoConnect:=true;
// открываем книгу
ExcelWorkbook1.ConnectTo(ExcelApplication1.Workbooks.OpenXML(OpenDialog1.FileName, EmptyParam));
// соединяемся с книгой
ExcelApplication1.ConnectTo(ExcelWorkbook1.Application);
ExcelWorksheet1.ConnectTo(ExcelWorkbook1.ActiveSheet as ExcelWorksheet);
// делаем видимым Excel
ExcelApplication1.Visible[0]:=true;
// считываем ячейку
v:=ExcelWorksheet1.Range['A1',EmptyParam];
// записываем в таблицу
Table1.Append; //здесь наши изменения. первая команда добавляет запись в БД
Table1.FieldByName('Pole1').AsString:=v; // вторая записывает данные
Table1.Post; // третьей сохраняем изменения
// выходим из Excel
ExcelApplication1.Quit;
end;
end;
...


если количество сток не известно, то :

...
procedure TForm1.Button1Click(Sender: TObject);
var V:OleVariant;
row, i:integer:
begin
if OpenDialog1.Execute then
begin
// запускаем Excel
ExcelApplication1.AutoConnect:=true;
// открываем книгу
ExcelWorkbook1.ConnectTo(ExcelApplication1.Workbooks.OpenXML(OpenDialog1.FileName, EmptyParam));
// соединяемся с книгой
ExcelApplication1.ConnectTo(ExcelWorkbook1.Application);
ExcelWorksheet1.ConnectTo(ExcelWorkbook1.ActiveSheet as ExcelWorksheet);
// делаем видимым Excel
ExcelApplication1.Visible[0]:=true;
ExcelWorksheet1.Cells.SpecialCells(xlCellTypeLastCell, EmptyParam).Activate;
row:=ExcelApplication1.ActiveCell.Row;
// от 2 т.к. предпологаю, что первая является заголовком
for i:=2 to row do
begin
// считываем ячейку
v:=ExcelWorksheet1.Range['A'+inttostr(i),EmptyParam];
// записываем в таблицу
Table1.Append; // добавляеь запись в БД
Table1.FieldByName('Pole1').AsString:=v; // записываем данные
Table1.Post; // сохраняем изменения
// чтоб приложение не "повисало"
Application.ProgresMessages;
end;
// выходим из Excel
ExcelApplication1.Quit;
end;
end;
...


последний код прочитает и занесёт в БД из первого столбца Excel.
 
Еще один пример можно скачать здесь:
http://www.albinos.nightmail.ru/Excel.zip 
 
Удачи.

СУВ, Albinos_X (С)
Задать вопрос или связаться со мной можно по ICQ или E-mail. Их можно узать в Контактах.

ВНИМАНИЕ: Коммерческая публикация данной статьи запрещена без согласования с автором, т.е. со мной. Не коммерческая публикация статьи должна обязательно быть с указанием источника.

Комментарии

Функция доступна только зарегистрированным пользователям.
Войдите под своей учетной записью или зарегистрируйтесь.

Powered by AkoComment 2.0!

 
2001-2007 Jey_k & Albinos_X
Мой ip проверка
ALLDAY.RU - портал обо всем интересном в дизайне