Компонент StringGrid Delphi

Совместная работа StringGrid и Excel




Уроки Delphi
  1.  Первая программа
  2.  Использование компонентов
  3.  События Delphi
  4.  Типы данных Delphi
  5.  Создание своих типов данных
  6.  Выражения и операторы
  7.  Работа с файлами в Delphi
  8.  Дополнительные формы
  9.  Подпрограммы в Delphi
  10. Исключительные ситуации
  11. Взаимодействие приложения с пользователем
  12. Указатели в Delphi
  13. Обзор компонентов
  14. Работа со строками
  15. Создание интерфейса
  16. Графика в Delphi
  17. Многопоточность в Delphi
  18. Динамическое создание
        компонентов
Поиск по сайту




 Это важно:
   Метод Application.ProcessMessages;

 Это полезно:
   Параметр Sender в обработчиках событий;










Бояться не надо



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

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

unit Unit1;

interface

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

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

var
  Form1: TForm1;
  Excel: Variant;

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

Excel:=CreateOleObject('Excel.Application');
Excel.Application.WorkBooks.Add('Имя_Файла.xls');

Если создаётся пустая книга, метод 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:=Unassigned;

и при нажатии кнопки закрытия наш 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.WorkSheets.Item['Лист1'].Cells[i, j]

   писать:

Excel.Cells[i, j]

   Или можно создать переменную и присвоить ей значение того листа 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:

Range:=Excel.Range['A1'];

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

Range:=Excel.Range['A1:D4'];

   А вот как выполнить перепись региона 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 слово 'Привет':

  Excel.Range[Excel.Cells[1, 1], Excel.Cells[100, 100]]:='Привет';

Очистка региона выполняется методом Clear:

  Excel.Range[Excel.Cells[1, 1], Excel.Cells[100, 100]].Clear;


Обзор компонентов Delphi           В начало урока          Компонент StringGrid Delphi

Уроки Delphi начинающим



Вопросы и комментарии (47)      Решение задач в Delphi

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

Имя  

Текст комментария