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

Наверное многие программисты сталкивались с такой проблемой, как создание отчёта. Репортинговых систем сейчас предостаточно, но всё таки, если нужно использовать или включать как дополнительную опцию для вывода отчёта установленный на компьютере заказчика MS Excel. Или наоборот нужно не выводить данные в таблицу, а брать оттуда какие либо данные, автоматизировать обработку данных хранящихся в таблице.