Тут иногда бывают вопросы о том, как можно из Delphi работать с документами Excel. Решил написать такую инструкцию, где рассказано об основных действиях.
Для работы с OLE нужно к строке Uses добавить модуль ComObj. Так же нужно объявить переменную типа Variant.
Delphi | ||
|
Что бы начать работу с Экселем, нужно создать OLE объект:
Ap := CreateOleObject(‘Excel.Application’);
После этого нужно либо создать новую книгу:
Ap.Workbooks.Add;
либо открыть файл:
Ap.Workbooks.Open(<имя файла>);
Что бы открыть файл только для чтения, нужно указать:
Ap.Workbooks.Open(<имя файла>,0,True);
где True и указывает, что файл открывается только для чтения.
По умолчанию окно Excel не будет отображаться… что бы оно появилось, нужно выполнить
Ap.Visible := True;
Но это желательно делать в последний момент, т.к. когда окно видимое, то все изменения в нём происходят медленнее. Поэтому, лучше оставить его невидимым, сделать там все необходимые изменения, и только после этого сделать его видимым или закрыть. Если вы его оставите невидимым, то процесс EXCEL.EXE останется висеть в памяти, даже когда будет закрыто ваше приложение.
Что бы закрыть Excel, выполните Ap.Quit или Ap.Application.Quit. Честно говоря, я не знаю, чем они отличаются.
Что бы при закрытии не выдавался запрос на сохранение файла, можно отключить сообщения:
Ap.DisplayAlerts := False;
Что бы записать или прочитать содержимое ячейки можно использовать Ap.Range[<имя ячейки>] или Ap.Cells[<позиция по Y>,<позиция по X>]
Ap.Range[‘D1’] := ‘Ляляля’;
Ap.Cells[1,4] := ‘Ляляля’;
Эти две строки выполняют одно и тоже действие: записывают строку «Ляляля» в ячейку D1
Читать значение из ячейки таким же образом:
S := Ap.Range[‘D1’];
или
S := Ap.Cells[1,4];
Так же можно записывать значение сразу в несколько ячеек… можно перечислить через точку с запятой или указать диапазон через двоеточие:
Delphi | ||
|
Изменение свойств текста
Всё это можно применять как к отдельным ячейкам, так и к группам ячеек, строк, столбцов и т.п. Я буду показывать примеры на Ap.Cells… но Вам никто не мешает использовать Ap.Range[‘D5’], Ap.Range[‘A2:E8’], Ap.Columns[‘B:F’] и т.п.
Delphi | ||
|
Изменение цвета фона ячеек:
Delphi | ||
|
Наверное, вы обращали внимание, что в новом документе появляются 3 листа (их список отображается внизу программы Excel). По умолчанию, мы работаем с активным листом (сразу после создания это первый лист). Но при желании, мы можем использовать и другие листы. Доступ к ним осуществляется с помощью Worksheets[<номер листа>]. Обратите внимание, что нумеруются они начиная с 1 (а не с 0, как привыкли все программисты).
Delphi | ||
|
Свойства страницы
Delphi | ||
|
Ниже приведён более полный список размеров бумаги из модуля ExcelXP:
Delphi | ||
|
Распечатать
Delphi | ||
|
Выделение
Excel.Range[Excel.Cells[1, 1], Excel.Cells[5, 3]].Select;
а также любые другие комбинации выбора ячейки с окончанием .select — выбор 1 или группы ячеек
С выбранными ячейками возможны следующие преобразования:
1) объединение ячеек
Excel.Selection.MergeCells:=True;
2) перенос по словам
Excel.Selection.WrapText:=True;
3) горизонтальное выравнивание
Excel.Selection.HorizontalAlignment:=3;
при присваивании значения 1 используется выравнивание по умолчанию, при 2 — выравнивание слева, 3 — по центру, 4 — справа.
4) вериткальное выравнивание
Excel.Selection.VerticalAlignment:=1;
присваиваемые значения аналогичны горизонтальному выравниванию.
5) граница для ячеек
Excel.Selection.Borders.LineStyle:=1;
При значении 1 границы ячеек рисуются тонкими сплошными линиями.
Кроме этого можно указать значения для свойства Borders, например, равное 3. Тогда установится только верхняя граница для блока выделения:
Excel.Selection.Borders[3].LineStyle:=1;
Значение свойства Borders задает различную комбинацию граней ячеек.
В обоих случаях можно использовать значения в диапазоне от 1 до 10. ]
//9 и 11 — лучшие
\\\\\\\\\\\\\\\\
Установка пароля для активной книги может быть произведена следующим образом:
Delphi | ||
|
где pass — устанавливаемый пароль на книгу.
Снятие пароля с книги аналогично, использовуем команду
Delphi | ||
|
где pass — пароль, установленный для защиты книги.
Установка и снятие пароля для активного листа книги Excel производится командами
Delphi | ||
|
где pass — пароль, установленный для защиты книги.
Вспомогательные операции в EXCEL
Удаление строк со сдвигом вверх:
Delphi | ||
|
при выполнении данных действий будут удалены строки с 5 по 15.
Установка закрепления области на активном листе Excel
Delphi | ||
|
Спасибо VampireKB за дополнения
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Сегодняшняя статья блога будет целиком посвящена работе с Excel Range или, говоря другими словами — работе с диапазонами ячеек Excel.
Про работу с этими объектами я уже вкратце говорил, а сегодня хотел бы поделиться с вами более полной информацией. Итак, начнем с самого простого.
1. Что такое Range и как его получить?
Согласно официальному определению Microsoft, Range :
представляет собой ячейки, строки, столбцы, набор ячеек, содержащих один или более смежных блоков ячеек, или 3-D диапазон.
Однако это определение не исключает того, что объектом Range может выступать и одна ячейка (Cell) листа. Таким образом, чтобы получить в свое распоряжение объект Range, можно выполнить следующие операции c объектом Excel в Delphi:
var MyRange: OLEVariat; begin {объект Range, состоящий из одной ячейки} MyRange:=MyExcel.ActiveWorkBook.ActiveSheet.Range['A1']; {объект Range в виде строки из четырех ячеек} MyRange:=MyExcel.ActiveWorkBook.ActiveSheet.Range['A1:D1']; {объект Range в виде столбца из четырех ячеек} MyRange:=MyExcel.ActiveWorkBook.ActiveSheet.Range['A1:A4']; {объект Range в виде таблицы 4х4 ячейки} MyRange:=MyExcel.ActiveWorkBook.ActiveSheet.Range['A1:D4']; end;
Если Вам неудобно в какой-либо ситуации использовать буквенные обозначение ячеек или Вы привыкли до этого момента иметь дело только с отдельными ячейками (Cells), то объект Range можно получить например вот так:
var MyRange: OLEVariat; Cell_1, Cell2: OLEVariant; begin {получаем ссылку на объект Cells, соответствующей ячейке A1} Cell_1:=MyExcel.ActiveWorkBook.ActiveSheet.Cells[1,1]; {получаем ссылку на объект Cells, соответствующей ячейке C5} Cell_2:=MyExcel.ActiveWorkBook.ActiveSheet.Cells[5,3]; {получаем объект Range размером 3х5} MyRange:=MyExcel.ActiveWorkBook.ActiveSheet.Range[Cell_1, Cell_2] end;
Какой из способов Вы будете использовать в Delphi — не важно, так как результат будет один и тот же. Получив в свое распоряжение диапазон Вы можете использовать его далее, например, для того, чтобы установить вид его границ.
2. Свойства объекта Excel Range.
Рассмотрим основные свойства объекта Range и их применение работе в Excel в Delphi.
Вначале перечислю свойства, которые будут далее рассмотрены в статье.
Свойство | Описание |
Formula | Возвращает или помещает в диапазон формулу |
Value | Возвращает или устанавливает значение для диапазона |
Text | возвращает текст из ячейки |
Column | Возвращает номер первого столбца в первой области, в указанном диапазоне |
Columns | возвращает объект Range, представляющий собой один столбец из всего диапазона |
Comment | Возвращает объект Comment для Range. В данном случае Range должен определять одну ячейку. |
Address | Возвращает реальный адрес диапазона Range |
Formula
Возвращает или помещает в диапазон формулу.
Value
Возвращает или устанавливает значение для диапазона.Свойство Value замечательно тем, что с помощью него можно записать в ячейки абсолютно любые данные, особо не задумываясь о формате данных. Например, запишем в ячейки диапазона строку, число типа integer и число типа single: чтобы каждый раз не повторяться в листингах и не писать одни и те же элементы по 100 раз, будем считать, что в переменной Sheet уже содержится ссылка на активный лист (ActiveWorkSheet) активной книги (ActiveWorkBook) Excel (MyExcel)
var i:integer; s: single; str: string; Sheet: OLEVariant; begin i:=100; s:=2.12; str:='Hello World!'; Sheet.Range['A1'].Value:=i; Sheet.Range['A2'].Value:=s; Sheet.Range['A3'].Value:=str; end;
Как видите, обращение к ячейкам было одно и то же и нигде я не приводил данный к какому-то типу — записал в ячейки всё как есть.
Если Вы хотите записать в весь диапазон Range одно и то же значение, то просто выполните:
Sheet.Range['A1:A10'].Value:=str;
и получите одну и ту же строку «Hello World!» в десяти ячейках Excel, но такие операции очень редко необходимы при работе с Excel в Delphi. Зато очень часто необходимо воспользоваться другой стороной свойства Value — прочитать большой объем данных из книги Excel за один прием и получить весь массив данных в Delphi. Операция чтения данных из Excel в Delphi более проста, чем Вам может показаться на первый взгляд. Проведем обратную операцию — прочитаем данные из Excel:
var val: Variant; Sheet: OLEVariant; i:integer; begin Val:=Sheet.Range['A1:A3'].Value; for i:=1 to 3 do ShowMessage(val[i,1]); end;
Если Вам необходимо читать/писать большое количество данных, то наиболее быстрым способом работы с данными будет использование вариантных массивов. О том, как использовать вариантные массивы при работе с Excel в Delphi рассказывается в статье «Быстрая обработка данных Excel в Delphi.«
Как видите здесь мы за один прием прочитали данные сразу из трех ячеек Excel и отобразили их в сообщении. Этот прием чтения на порядок более скоростной, чем, например чтение содержимого каждой ячейки (Cells) в отдельности.
Text
Ещё одно простенькое свойство объекта Range — возвращает текст из ячейки. Самое главное отличие от свойства Value — Text возвращает string только для чтения и использовать это свойство для чтения большого объема данных, как в предыдущем примере — ни в коем случае нельзя, так как переменная Val вернет значение Null.
Column
Возвращает номер первого столбца в первой области, в указанном диапазоне. Свойство только для чтения.
Чтобы продемонстрировать свойство в действии, давайте создадим такие диапазоны как показано на рисунке:
То есть каждый из диапазонов Range будет содержать по две несвязанные друг с другом области (Area). Причем первая область диапазона Range будет начинаться в столбце А, а первая область второго диапазона (Range 2) — в столбце B.
После того, как диапазоны будут созданы — посмотрим, что вернет нам свойство Column для каждого из диапазонов.
Листинг процедуры создания двух несвязных диапазонов Range следующий:
var Range1,Range2,BigRange: OLEVariant; begin {создаем первый диапазон} Range1:=Sheet.Range['A1:C4']; Range2:=Sheet.Range['E6:H9']; BigRange:=Sheet.Range[Range1,Range2]; ShowMessage(IntToStr(BigRange.Column)); //показываем значение свойства {создаем второй диапазон} Range1:=Sheet.Range['B7:C13']; Range2:=Sheet.Range['E1:H3']; BigRange:=Sheet.Range[Range1,Range2]; ShowMessage(IntToStr(BigRange.Column)); //показываем значение свойства end;
Так, в случае с первым Range Column вернет нам значение 1, а для второго Range — значение 2.
Columns
В отличие от предыдущего свойства, Columns возвращает не простое число, а объект Range, представляющий собой один столбец из всего диапазона.
Посмотрим как, например, используя это свойство можно изменять столбцы во всем диапазоне Range.
Для демонстрации воспользуемся предыдущим примером, изменим только окончание:
... BigRange:=Sheet.Range[Range1,Range2]; for i:=1 to BigRange.Columns.Count do BigRange.Columns[i].Value:='Столбец №'+IntToStr(i);
В итоге в каждый из столбцов диапазона должна записаться строка с номером этого столбца, результат представлен на рисунке. Как видите, в цикле все столбцы обработались «насквозь», хотя Range не содержал в себе столбец D.
Возвращает объект Comment для Range. В данном случае Range должен определять одну ячейку.
Для демонстрации свойства не будем заходить в Excel, поработаем с приложением прямо из Delphi. Для этого воспользуемся методом AddComment. То есть сначала запишем комментарий в ячейку, а потом прочитаем его используя свойство Comment:
Range2:=Sheet.Range['E6']; {записали комментарий} Range2.AddComment('Это комментарий ячейки области'); {прочитали} ShowMessage(Range2.Comment.Text);
Address
Возвращает реальный адрес диапазона Range. Например для диапазона ячеек, заданных вот таким образом:
Range2:=Sheet.Range['A1:E6']; Свойство Address будет содержать строку "$A$1:$E$6"
Это свойство удобно использовать, когда Вы оперируете в программе только числовыми значениями (номерами столбцов и строк) и появляется необходимость показать пользователю адреса ячеек из диапазона.
Помимо перечисленных выше свойств к объекту Range применимы все свойства, описанный в статье об изменении внешнего вида ячеек Excel, т.е. borders, color и пр.
3. Методы объекта Excel Range.
Теперь рассмотрим несколько полезных методов, которые могут Вам пригодиться при работе с Excel в Delphi.
Метод | Описание |
CheckSpelling | Проверяет грамматику в выбранном диапазоне и при нахождении ошибок выводит окно для замены |
PrintPreview | Выводит на экран окно предварительного просмотра перед печатью выбранного диапазона ячеек |
AutoFill | Автозаполнение диапазона ячеек на основе данных из другого диапазона |
AutoFit | Изменяет ширину или высоту ячеек диапазона для наилучшего представления данных. |
Clear | Удаляет все данные из диапазона |
ClearComments | Удаляет все комментарии в диапазоне Range |
ClearContents | Удаляет все формулы из диапазона Range |
ClearFormats | Очищает форматы в диапазоне Range |
ClearNotes | Очищает все заметки в диапазоне Range |
Copy | Копирует содержимое диапазона Range в буфер обмена или в другой диапазон |
PasteSpecial | Специальная вставка диапазона |
Cut | Вырезает данные и при необходимости вставляет их в новый диапазон |
Merge | Объединение ячеек диапазона |
CheckSpelling
Проверяет грамматику в выбранном диапазоне и при нахождении ошибок выводит окно для замены. Замечательной особенностью этого метода является то, что окно замены появляется даже при скрытом окне Excel, то есть, когда свойство Visible у объекта Excel равно false.
Вызывается метод без каких-либо дополнительных параметров:
Range['A1:H6'].CheckSpelling
PrintPreview
Выводит на экран окно предварительного просмотра перед печатью выбранного диапазона ячеек. Также как и предыдущий метод PrintPreview не имеет дополнительных параметров. Однако при попытке вызвать метод при скрытом окне Excel в лучшем случае возникнет исключительная ситуация, в худшем — зависание Вашего приложения. Так что перед вызовом:
не забывайте включить свойство Visible у Excel:
AutoFill
Автоматическое заполнение диапазона ячеек на основе данных из другого диапазона.
Вызов метода:
Range.AutoFill(Destination, Type)
Параметр | Тип | Описание |
Destination | Variant | представляет собой объект Range уже заполненных ячеек. Эти ячейки должны входить в автозаполняемый диапазон |
Type | Integer | тип автозаполнения (возможные значения см. ниже) |
Рассмотрим применение метода на примере.
Sheet.Range['A1'].Value:=1; Sheet.Range['A2'].Value:=2; Source:=Sheet.Range['A1:A6']; Range2:=Sheet.Range['A1:E6']; Source.AutoFill(Range2, xlFillDefault)
В результате лист Excel примет следующий вид:
Как видите все столбцы второго диапазона Range заполнились значениями из диапазоны Source.
При использовании этого метода следует иметь в виду, что диапазон-источник (в нашем случае — это source) по одному из измерений должен совпадать с источником назначения. В приведенном примере совпадает размерность по строкам (в обоих диапазонах их шесть). Если размерности диапазонов не совпадают, то возникает исключительная ситуация.
При использовании метода мы использовали одну из констант в параметре Type — xlFillDefault = 0. Используя её мы скопировали данные один-к-одному. Дополнительно Вы можете использовать следующие константы при автозаполнении:
Имя | Значение | Описание |
xlFillDefault | 0 | скопировать данные один-к-одному |
xlFillDays | 5 | копирование дней недели с расширением, т.е., если Вы запишете в ячейку слово «Понедельник» и попробуете провести автозаполнение ещё на 2 строки, то во второй и третьей строке появятся «Вторник» и «Среда» |
xlFillCopy | 1 | копирует все данные и форматы, повторяя при необходимости |
xlFillFormats | 3 | копирует только форматы источника |
xlFillMonths | 7 | копирует названия месяцев. Работает аналогично xlFillDays |
xlFillSeries | 2 | копирует данные с расширением, например 1,2,3 будут при копировании расширены до 4,5,6 и т.д. Также копирует форматы данных |
xlFillValues | 4 | копирует только значения |
xlFillWeekdays | 6 | копирует дни рабочей недели, работает аналогично xlFillDays, но только до пятницы |
xlFillYears | 8 | копирует года. Работает аналогично xlFillDays |
xlGrowthTrend | 10 | копирует числовые значения из источника, расширяя их в предположении, что каждое последующее число представляет собой предыдущее, но умноженное на некоторую величину. Например 1,2 раскопируются в 4, 8, 16 и т.д. Формат данных также копируется |
xlLinearTrend | 9 | копирует числовые значения из источника, расширяя их в предположении, что каждое последующее число представляет собой предыдущее + некоторая величина. Например 1,2 раскопируются в 3, 4, 5 и т.д. Формат данных также копируется |
AutoFit
Изменяет ширину или высоту ячеек диапазона для наилучшего представления данных.
Пример вызова:
Sheet.Range['A1'].Value:=1234567891012; Sheet.Range['A2'].Value:=23456789; Source:=Sheet.Range['A1:A2']; Source.Columns.AutoFit
Приведет и изменению ширины столбца А таким образом, чтобы число было полностью видно на листе.
Методы очистки данных диапазона Range
Есть несколько различных методов очистки содержимого диапазона Range при работе с Excel в Delphi.
1. Clear
Удаляет все данные из диапазона.
Пример вызова:
2. ClearComments
Удаляет все комментарии в диапазоне Range.
Пример вызова:
3. ClearContents
Удаляет все формулы из диапазона Range
Пример вызова:
4. ClearFormats
Очищает форматы в диапазоне Range
Пример вызова:
5. ClearNotes
Очищает все заметки в диапазоне Range
Пример вызова:
Методы работы с буфером обмена Excel
1. Copy
Копирует содержимое диапазона Range в буфер обмена или в другой диапазон.
Попробуем реализовать работу метода следующим образом: заполним столбец А некоторыми значениями, а затем скопируем его сначала в буфер, а потом в столбец Е:
Sheet.Range['A1'].Value:=1; Sheet.Range['A2'].Value:=2; Sheet.Range['A3'].Value:=3; Sheet.Range['A4'].Value:=4; Sheet.Range['A5'].Value:=5; Sheet.Range['A6'].Value:=6; Source:=Sheet.Range['A1:A6']; Source.Copy; //скопировали в буфер Range2:=Sheet.Range['E1:E6']; Source.Copy(Range2)//скопировали в новый диапазон
А для того, чтобы вставить данные из буфера обмена существует ещё один метод
2. PasteSpecial
Вызов метода:
MyRange.PasteSpecial(Paste, Operation, SkipBlanks, Transpose)
Параметр | Тип | Описание |
Paste | Integer | определяет какая часть данных диапазона будет вставлена (возможные значения см. ниже) |
Operation | Integer | операция, которая будет выполнена при вставке данных (возможные значения см. ниже) |
SkipBlanks | boolean | True, для того чтобы пустые ячейки из буфера обмена не вставлялись в диапазон назначения. Значение по умолчанию False |
Transpose | boolean | транспонирование столбцов и строк после вставки. По умолчанию устанавливается значение False |
При определении параметра Paste следует использовать следующие константы:
Имя | Значение | Описание |
xlPasteAll | -4104 | Вставка всех данных |
xlPasteAllExceptBorders | 7 | Вставка всего содержимого за исключением вида границ диапазона |
xlPasteAllUsingSourceTheme | 13 | Вставка всего содержимого, используя тему оформления источника |
xlPasteColumnWidths | 8 | Копирует ширину столбцов |
xlPasteComments | -4144 | Вставка комментариев |
xlPasteFormats | -4122 | Вставка форматов данных |
xlPasteFormulas | -4123 | Вставка формул |
xlPasteFormulasAndNumberFormats | 11 | Вставка формул и чисел |
xlPasteValidation | 6 | Вставка проверок |
xlPasteValues | -4163 | Вставка значений |
xlPasteValuesAndNumberFormats | 12 | Вставка значений и чисел |
При использовании параметра Operation следует использовать следующие константы:
Имя | Значение | Описание |
xlPasteSpecialOperationAdd | 2 | К скопированным данным будут добавлены значения из целевых ячеек |
xlPasteSpecialOperationDivide | 5 | Скопированные данные будут разделены на значения в целевых ячейках |
xlPasteSpecialOperationMultiply | 4 | Скопированные данные будут умножены на значения в целевых ячейках |
xlPasteSpecialOperationNone | -4142 | При вставке значений никакие операции не будут применяться |
xlPasteSpecialOperationSubtract | 3 | Из скопированных данных будут вычитаться значения целевых ячеек |
Теперь рассмотрим применение метода на примере. В качестве исходных данных возьмем данные из предыдущего примера, но для вставки используем метод PasteSpecial:
... Range2.PasteSpecial(Operation:=xlPasteSpecialOperationAdd);
После выполнения этой операции все данные вставятся в диапазон Range2, т.к. диапазон до вставки был пуст, то данные скопировались один-к-одному.
3. Cut
Вырезает данные и при необходимости вставляет их в новый диапазон. Метод работает аналогично методу Copy, но с последующим удалением данных из источника.
Merge
Объединение ячеек диапазона.
Для новичков, только начинающих постигать азы работы с excel в Delphi этот метод в какой-то момент становится камнем преткновения :). Дело в том, что очень часто возникает необходимость объединить часть ячеек листа для записи в объединенную область большого количества данных или длинной строки. В Excel есть такой метод Union, который и отвечает за объединение — им-то и пробуют пользоваться многие. А метод Union при вызове из Delphi применительно к диапазону Range вызывает исключительную ситуацию. Про Merge люди либо не знают, либо забывают. А использовать его достаточно просто:
Параметр | Тип | Описание |
Across | boolean | True, чтобы объединить ячейки в каждой строке указанного диапазона как отдельные объекты. Значение по умолчанию False |
Например, объединим ячейки в диапазоне Range2 из предыдущего примера:
После выполнения этой операции в диапазоне останется только верхнее значение, т.е. 1.
Дополнительные методы автозаполнения ячеек диапазона Range
В отдельную группу методов можно выделить 4 метода автозаполнения ячеек диапазона:
- FillDown
- FillUp
- FillRight
- FillLeft
Принцип действия этих методов один и тот же за исключением направления автозаполнения.
Например, давайте запишем в ячейку A1 какое-нибудь значение и воспользуемся методами FillDown и FillRight:
Sheet.Range['A1'].Value:=1; Sheet.Range['A1:A6'].FillDown; Sheet.Range['A1:F1'].FillRight;
После этого в строк 1 и столбце A появятся числа 1. Аналогичным образом можно заполнять не только строки или столбцы, но и таблицы целиком — достаточно знать в какую сторону двигаться при автозаполнениии и применять соответствующие методы Excel для Range.
Вот в принципе краткий обзор возможностей работы с объектов Range в Excel. В целом можно отметить, что работа с этим объектом в Delphi один из самых эффективных способов организации пресылки/получения данных между Excel и Delphi, не считая работы через XML формат.
Книжная полка
Название:Разработка приложений Microsoft Office 2007 в Delphi Описание Описаны общие подходы к программированию приложений MS Office. Даны программные методы реализации функций MS Excel, MS Word, MS Access и MS Outlook в среде Delphi. |
0
0
голоса
Рейтинг статьи
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Для работы с Excel в Delphi, первым делом нужно в Uses указать модуль ComObj.
procedure TForm1.Button1Click(Sender: TObject); var XL: Variant; begin XL := CreateOLEObject(‘Excel.Application’); // Создание OLE объекта XL.WorkBooks.add; // Создание новой рабочей книги XL.visible := true; end; |
Как обратиться к отдельным ячейкам листа Excel в Delphi
XL.WorkBooks[1].WorkSheets[1].Cells[1,1].Value:=’30’; //Результатом является присвоение ячейке [1,1] первого листа значения 30. Также к ячейке //текущего листа можно обратиться следующим образом: XL.Cells[1, 1]:=’30’; |
Как добавить формулу в ячейку листа Excel в Delphi
XL.WorkBooks[1].WorkSheets[1].Cells[3,3].Value := ‘=SUM(B1:B2)’; |
Форматирование текста в ячейках Excel, производится с помощью свойств Font и Interior объекта Cell:
// Цвет заливки XL.WorkBooks[1].WorkSheets[1].Cells[1,1].Interior.Color := clYellow; // Цвет шрифта XL.WorkBooks[1].WorkSheets[1].Cells[1,1].Font.Color := clRed; XL.WorkBooks[1].WorkSheets[1].Cells[1,1].Font.Name := ‘Courier’; XL.WorkBooks[1].WorkSheets[1].Cells[1,1].Font.Size := 16; XL.WorkBooks[1].WorkSheets[1].Cells[1,1].Font.Bold := True; |
Работа с прямоугольными областями ячеек, с помощью объекта Range:
XL.WorkBooks[1].WorkSheets[1].Range[‘A1:C5’].Value := ‘Blue text’; XL.WorkBooks[1].WorkSheets[1].Range[‘A1:C5’].Font.Color := clBlue; //В результате в области A1:C5 все ячейки заполняются текстом ‘Blue text’. |
Как выделить группу (область) ячеек Excel в Delphi
XL.Range[‘A1:C10’].Select; |
Как установить объединение ячеек, перенос по словам, и горизонтальное или вертикальное выравнивание Excel в Delphi
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
//Выделяем группу (область) ячеек XL.Range[‘A1:C10’].Select; // объединение ячеек XL.Selection.MergeCells:=True; // перенос по словам XL.Selection.WrapText:=True; // горизонтальное выравнивание XL.Selection.HorizontalAlignment:=3; //вериткальное выравнивание XL.Selection.VerticalAlignment:=1; //Возможны следующие значения: //1 — выравнивание по умолчанию, //2 — выравнивание слева, //3 — выравнивание по центру, //4 — выравнивание справа. |
Как задать границы ячеек Excel в Delphi
XL.Selection.Borders.LineStyle:=1; // значение может быть установлено от 1 до 10 |
Как выровнять столбцы Excel по ширине, в зависимости от содержания
XL.selection.Columns.AutoFit; |
Как удалить столбец Excel в Delphi
Как задать формат ячеек Excel в Delphi
XL.columns[1].NumberFormat := ‘@’; // текстовый формат XL.columns[1].NumberFormat := ‘m/d/yyyy’; // формат дата XL.columns[1].NumberFormat = ‘0.00%’ // формат процентный XL.columns[1].NumberFormat = ‘h:mm;@’// формат время |
Создание документа
Внимание!!! Всегда когда создаете объект интерфейса, заключайте процедуру создания в модуль обработки ошибок:
try
создаем интерфейс;
формируем отчет;
освобождаем интерфейс;
Except
обрабатываем ошибки;
освобождаем интерфейс;
end;
Далее идет краткий справочник по основным функциям работы с EXCEL
try
// создаем обьект EXCEL
excel := CreateOleObject(‘Excel.Application’);
// Чтоб не задавал вопрос о сохранении документа
excel.DisplayAlerts := false;
// создаем новый документ рабочую книгу
excel.WorkBooks.Add;
// или загружаем его из директории с программой
excel.WorkBooks.Open(GetCurrentDir() + ‘отчет.xls’);
{ GetCurrentDir()- возвращает путь к директории с программой}
// Делаем его видимым данную функцию после отладки и тестирования лучше использовать в конце, после сформирования отчета (это ускоряет процесс вывода данных в отчет)
excel.Visible := true;
//задаем тип формул в формате R1C1
excel.Application.ReferenceStyle := xlR1C1;
// задаем тип формул в формате A1
excel.Application.ReferenceStyle := xlA1;
// Задаем название первому и второму листу
excel.WorkBooks[1].WorkSheets[1].Name := ‘Отчет1’;
excel.WorkBooks[1].WorkSheets[2].Name := ‘Отчет2’;
//задаем формат числа для первой и четвертой колонки формат числа
excel.WorkBooks[1].WorkSheets[1].Columns[1].NumberFormat := ‘0,00’;
excel.WorkBooks[1].WorkSheets[1].Columns[4].NumberFormat := ‘0,0’;
// задаем ширину первой и второй колонки
excel.WorkBooks[1].WorkSheets[1].Columns[1].ColumnWidth := 10;
excel.WorkBooks[1].WorkSheets[1].Columns[2].ColumnWidth := 20;
// задаем начертание, цвет, размер и тип шрифта для первого ряда
excel.WorkBooks[1].WorkSheets[1].Rows[1].Font.Bold := True; //жирный
excel.WorkBooks[1].WorkSheets[1].Rows[1].Font.Color := clRed; // цвет красный
excel.WorkBooks[1].WorkSheets[1].Rows[1].Font.Size := 12; //размер 12
excel.WorkBooks[1].WorkSheets[1].Rows[1].Font.Name := ‘Times New Roman’; //шрифт
//присваиваем ячейке 1,4 и 2,4 значения (1 — ряд, 4 — колонка)
excel.WorkBooks[1].WorkSheets[1].Cells[1, 4] := ‘А так можно внести значение в ячейку’;
excel.WorkBooks[1].WorkSheets[1].Cells[2, 4] := ‘А так можно внести значение в ячейку’;
//ввод в ячейку ‘A12’ формулы ‘=b5+c4’
excel.WorkBooks[1].WorkSheets[1].Range[‘A12′].Formula:=’=b5+c4’;
// Выравнивам первый ряд по центру по вертикали
excel.WorkBooks[1].WorkSheets[1].Rows[1].VerticalAlignment := xlCenter;
// Выравнивам первый ряд по центру по горизонтали
excel.WorkBooks[1].WorkSheets[1].Rows[1].HorizontalAlignment := xlCenter;
// Выравнивам в ячейке по левому краю
excel.WorkBooks[1].WorkSheets[1].Cells[3, 2].HorizontalAlignment := xlLeft;
// Выравнивам в ячейке по правому краю
excel.WorkBooks[1].WorkSheets[1].Cells[3, 4].HorizontalAlignment := xlRight;
// Обьединяем ячейки ‘A1:A8’
excel.WorkBooks[1].WorkSheets[1].Range[‘A1:A8’].Merge;
// Поворачиваем слова под углом 90 градусов для второго ряда
excel.WorkBooks[1].WorkSheets[1].Rows[2].Orientation := 90;
// Поворачиваем слова под углом 45 градусов для диапазона ячеек ‘B3:D3’
excel.WorkBooks[1].WorkSheets[1].Range[‘B3:D3’].Orientation := 45;
//рисуем границы выделенного диапазона левая
excel.Selection.Borders[xlEdgeLeft].LineStyle := xlContinuous; // стиль линии сплошная
excel.Selection.Borders[xlEdgeLeft].Weight := xlMedium;// толщина линии
//рисуем границы выделенного диапазона верхняя
excel.Selection.Borders[xlEdgeTop].LineStyle := xlContinuous;
excel.Selection.Borders[xlEdgeTop].Weight := xlMedium;
//рисуем границы выделенного диапазона нижняя
excel.Selection.Borders[xlEdgeBottom].LineStyle := xlContinuous;
excel.Selection.Borders[xlEdgeBottom].Weight := xlMedium;
//рисуем границы выделенного диапазона правая
excel.Selection.Borders[xlEdgeRight].LineStyle := xlContinuous;
excel.Selection.Borders[xlEdgeRight].Weight := xlMedium;
//рисуем границы выделенного диапазона вертикальные внутрениие
excel.Selection.Borders[xlInsideVertical].LineStyle := xlContinuous;
excel.Selection.Borders[xlInsideVertical].Weight := xlMedium;
//рисуем границы выделенного диапазона горизонтальные внутрениие
excel.Selection.Borders[xlInsideHorizontal].LineStyle := xlContinuous;
excel.Selection.Borders[xlInsideHorizontal].Weight := xlMedium;
//автозаполнение выделенного диапазона
//для примера заполним область ячеек ‘A10:C10’ словом ‘привет’
//и размножим его вниз еще на пять ячеек ‘A10:C15’
excel.WorkBooks[1].WorkSheets[1].Range[‘A10:C10′].Value:=’привет’;
//выделяем диапазон ячеек ‘A10:C10’
excel.WorkBooks[1].WorkSheets[1].Range[‘A10:C10’].Select;
//автозаполняем (копируем) выделенным диапазоном область ячеек ‘A10:C15’
excel.selection.autofill(excel.WorkBooks[1].WorkSheets[1].Range[‘A10:C15’],xlFillDefault);
//отключаем предупреждения, чтобы не задавал вопросов о сохранении и других
excel.DisplayAlerts := False;
//сохраняем документ в формате Excel 97-2003
excel.ActiveWorkBook.Saveas(GetCurrentDir() + ‘отчет.xls’,xlExcel8);
//сохраняем документ в текущем формате Excel 2007
excel.ActiveWorkBook.Saveas(GetCurrentDir() + ‘отчет.xlsx’);
//закроем все книги
excel.Workbooks.Close;
//закрываем Excel
excel.Application.quit;
//освобождаем интерфейсы
excel := Unassigned;
Except
//обрабатываем ошибки
showmessage(‘Внимание! Произошла ошибка при создании MS Excel приложения’);
//закроем все книги
excel.Workbooks.Close;
//закрываем Excel
excel.Application.quit;
//освобождаем интерфейсы
excel := Unassigned;
end;
end;
При работе с листом Excel мы можем использовать следующие варианты:
— работать с областью Range[‘B3:D3’];
— работать с ячейкой Cells[2, 4] где 2 — ряд, 4 — колонка;
— работать с рядами Rows[1] или с диапазоном рядов Rows[‘1:5’];
— работать с колонками Columns[1] или диапазоном колонок Columns[‘A:I’];
Range[‘A1’] и Cells[1, 1] обозначают одно и тоже.
После сформирования документа или возникновении ошибки вы должны правильно освободить интерфейсы.
Иначе при закрытии Excel он скрывается с экрана, но если открыть диспетчер задач он продолжает там висеть и если данный процесс не завершить , то при каждом новом запуске их будет накапливаться больше и больше, пока компьютер не начнет виснуть. Поэтому обязательно необходимо освобождать все интерфейсы с вязанные с Excel с его книгами и листами.
Например так:
//закроем все книги
excel.Workbooks.Close;
//закрываем Excel
excel.Application.quit;
//освобождаем интерфейсы
sheet:=Unassigned; //интерфейс листа если он был создан
WorkBook := Unassigned;//интерфейс рабочей книги если он был создан
excel := Unassigned;//интерфейс самого предложения если он был создан
end;
Ниже привожу пример вывода в Excel из Delphi таблицы умножения с подробными комментариями.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, comobj, StdCtrls, Excel_TLB;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
excel: variant; // Переменная в которой создаётся объект EXCEL
MyData: variant; // Переменная в которой формируется таблица умножения
i,j:integer;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
try
// Обьект EXCEL
excel := CreateOleObject(‘Excel.Application’);
// Чтоб не задавал вопрос о сохранении документа
excel.DisplayAlerts := false;
// новый документ
excel.WorkBooks.Add;
//объявляем вариантный массив
MyData := VarArrayCreate([1,9,1,9],varVariant);
for I := 1 to 9 do
for J := 1 to 9 do
MyData[i,j]:=i*j;
// Обьединяем ячейки ‘A1:I1’
excel.WorkBooks[1].WorkSheets[1].Range[‘A1:I1’].Merge;
//Пишем заголовок
excel.WorkBooks[1].WorkSheets[1].Range[‘A1′].Value:=’Таблица умножения’;
// Выравнивам заголовок по центру
excel.WorkBooks[1].WorkSheets[1].Range[‘A1’].HorizontalAlignment := xlCenter;
// задаем ширину колонок с A по I
excel.WorkBooks[1].WorkSheets[1].Columns[‘A:I’].ColumnWidth := 3;
//выделяем область таблицы умножения [‘A2:I10’] и рисуем границы
excel.WorkBooks[1].WorkSheets[1].Range[‘A2:I10’].select;
//рисуем границы выделенного диапазона левая
excel.Selection.Borders[xlEdgeLeft].LineStyle := xlContinuous; // стиль линии сплошная
excel.Selection.Borders[xlEdgeLeft].Weight := xlThin;// толщина линии
//рисуем границы выделенного диапазона верхняя
excel.Selection.Borders[xlEdgeTop].LineStyle := xlContinuous;
excel.Selection.Borders[xlEdgeTop].Weight := xlThin;
//рисуем границы выделенного диапазона нижняя
excel.Selection.Borders[xlEdgeBottom].LineStyle := xlContinuous;
excel.Selection.Borders[xlEdgeBottom].Weight := xlThin;
//рисуем границы выделенного диапазона правая
excel.Selection.Borders[xlEdgeRight].LineStyle := xlContinuous;
excel.Selection.Borders[xlEdgeRight].Weight := xlThin;
//рисуем границы выделенного диапазона вертикальные внутрениие
excel.Selection.Borders[xlInsideVertical].LineStyle := xlContinuous;
excel.Selection.Borders[xlInsideVertical].Weight := xlThin;
//рисуем границы выделенного диапазона горизонтальные внутрениие
excel.Selection.Borders[xlInsideHorizontal].LineStyle := xlContinuous;
excel.Selection.Borders[xlInsideHorizontal].Weight := xlThin;
//присваиваем диапазону [‘A2:I10’] значения вариантного массива MyData это значительно ускоряет работу, нежели вывод по //ячеечно
excel.WorkBooks[1].WorkSheets[1].Range[‘A2:I10’].Value:=MyData;
// Делаем его видимым
excel.Visible := true;
//освобождаем интерфейсы
MyData:= Unassigned;
excel := Unassigned;
Except
showmessage(‘Внимание! Произошла ошибка при создании MS Excel приложения’);
//закрываем Excel
excel.Application.quit;
//освобождаем интерфейсы
MyData:= Unassigned;
excel := Unassigned;
end;
end;
end.
При написании статьи использовался материал с сайта http://vlad2000.h1.ru/Frames/Statyi/page_14.html
Подготовка
Откроем нашу среду разработки Delphi (в моем случае это Delphi 2010). Создадим новый проект. Должен сказать, что работа с Excel происходит через объекты COM. Поэтому нам надо подключить в раздел
USES
нашего проекта модуль
COMObj
. Так же нам понадобится модуль
ActiveX
. Это будет выглядеть примерно вот так:
unit Unit1; interface uses Windows, …, ActiveX, COMObj;
Проверка наличия установленного Microsoft Excel в операционной системе
Теперь собственно нам нужно, как писалось выше, определить наличие Excel в системе. Если он не будет обнаружен, то мы сообщим об этом пользователю и завершим программу. Для этого создадим простенькую функцию и объявим её в секции
private
нашей формы
TForm1
:
… private function CheckExcelInstalled(AValue: String): boolean; … function TForm1.CheckExcelInstalled(AValue: String): boolean; var FCLSID: TCLSID; begin Result := (CLSIDFromProgID(PChar(AValue), FCLSID) = S_OK); end;
Функция
CLSIDFromProgID
определена в модуле
ActiveX
и имеет следующее описание:
function CLSIDFromProgID(pszProgID: POleStr; out clsid: TCLSID): HResult;
Данная функция ищет
CLSID
, по соответствующему
ProgID
в реестре, в нашем случае мы ищем «Excel.Application». Если открыть реестр и перейти к ветке:
HKEY_LOCAL_MACHINESOFTWAREClasses
то там можно будет обнаружить много разделов. Среди них есть как раз нужный нам «Excel.Application» (при условии, что данное ПО установлено в системе). К сведению: у этого раздела имеется еще два подраздела:
HKEY_LOCAL_MACHINESOFTWAREClassesExcel.ApplicationCLSID
HKEY_LOCAL_MACHINESOFTWAREClassesExcel.ApplicationCurVer
Параметры функции:
—
pszProgID
: строка, содержащая ProgID.
—
clsid
: получает CLSID.
Возвращаемые значения:
—
S_OK
— CLSID создан успешно.
—
CO_E_CLASSSTRING
— CLSID зарегистрированный для ProgID неверен.
—
REGDB_E_WRITEREGDB
— ошибка записи в реестр.
—
E_OUTOFMEMORY
— нет памяти.
—
E_INVALIDARG
— указывает что один или более аргументов неверны. Стоит проверить правильность строки pszProgID.
—
E_UNEXPECTED
— неизвестная ошибка.
Теперь на событии
OnCreate
формы
TForm1
напишем следующий код:
procedure TForm1.FormCreate(Sender: TObject); begin if not CheckExcelInstalled('Excel.Application') then begin Application.MessageBox(PChar('Для работы программы необходимо ' + 'иметь установленное программное обеспечение Microsoft Excel.'#13#10 + 'Приложение будет закрыто.'), 'Ошибка', MB_ICONERROR); Halt; end; end;
При загрузке приложения ищем наличие Excel в системе. Если не находим, то выводим сообщение пользователю и закрываем программу с помощью метода
Halt
. Если находим, то просто показываем форму.
Проверить, запущен ли Microsoft Excel
Далее давайте кинем на форму одну кнопку TButton. На событии
OnClick
будем писать код работы с Excel. Первое что мы сделаем, это добавим локальную переменную типа
Variant
для доступа к Excel с именем, например,
FExcel
:
Теперь определимся, что мы хотим. Я всегда создавал новый экземпляр экселя, даже если он был уже запущен в системе. Но я это не вы. Поэтому я покажу вам, как можно использовать уже запущенный Excel. Создадим функцию и объявим ее так же в секции
private
:
… private … function CheckExcelRun(AValue: String; var ADest: Variant): boolean; … function TForm1.CheckExcelRun(AValue: String; var ADest: Variant): boolean; begin try ADest := GetActiveOleObject(AValue); Result := true; except Result := false; end; end;
Функция
GetActiveOleObject
определена в модуле
COMObj
и имеет следующее описание:
function GetActiveOleObject(const ClassName: string): IDispatch;
Функция возвращает ссылку на интерфейс
IDispatch
активного OLE-объекта указанного класса. Она использует информацию из таблицы активных объектов OLE (OLE running object table). Идентификатор класса объекта OLE в таблице активных объектов OLE передается в параметре
ClassName
. При невозможности выполнения функции GetActiveOleObject возникает исключение EOleSysError.
Теперь как пользоваться нашей функцией:
procedure TForm1.Button1Click(Sender: TObject); var FExcel: Variant; begin if not CheckExcelRun('Excel.Application', FExcel) then Exit; end;
Стоить пояснить. Если в системе запущена программа Excel, то функция
GetActiveOleObject
находит его, при этом функция
CheckExcelRun
возвращает
TRUE
. Ссылка на интерфейс передается через параметр «var ADest» нашей созданной переменной
FExcel
. Теперь вы можете работать с этим экземпляром Excel. Если же запущенный эксель не найден, то функция
GetActiveOleObject
вызывает исключение, простыми словами выходит ошибка. Поэтому мы поместили эту функцию в блок
try…except…end
. Вот в секции
except
мы присваиваем результат
FALSE
и т.о. выходим из процедуры
Button1Click
с помощью метода
Exit
. Но это все отступление. Давайте не будем искать уже запущенный ексель, а будем создавать новый и по завершению работы с ним корректно закроем его и высвободим память.
Создание нового экземпляра Microsoft Excel
Создать новый экземпляр можно с помощью функции
CreateOleObject
. Давайте сразу напишем шаблон.
procedure TForm1.Button1Click(Sender: TObject); var FExcel: Variant; begin try // Создаем новый экземпляр Excel FExcel := CreateOleObject('Excel.Application'); FExcel.Visible := true; ... // Тут ваш код finally // Если переменная не пустая, то... if not VarIsEmpty(FExcel) then begin // ...отключаем диалог с вопросом сохранять ли файл при выходе или нет FExcel.DisplayAlerts := false; // Закрываем Excel FExcel.Quit; // Присваиваем неопределенный тип, освобождая при этом // процесс excel.exe, чтобы он мог завершиться. Если этого не // сделать, то процесс останется висеть в памяти. FExcel := Unassigned; end; end; end;
Функция
VarIsEmpty
определена в модуле
Variants
и имеет следующее описание:
function VarIsEmpty(const V: Variant): Boolean;
Функция проверяет, определен ли тип значения
Variant
-переменной. Возвращает
TRUE
, если переменная имеет неопределенный тип (Unassigned). Если типу переменной соответствует значение какой-либо константы
VarType
типа
TVarData
, то функция возвращает
FALSE
.
Операции над программой Microsoft Excel из Delphi
Теперь давайте рассмотрим, что вообще можно делать с Excel из Delphi. Операций достаточно много. И все описать просто невозможно. Но если в моем описании не окажется нужного вам метода, то огорчаться не стоит. Методы можно узнать самому. Открываете Excel. Затем в меню
Сервис – Макрос – Начать запись
. Там жмем ОК и выполняем необходимые нам операции в Excel. Когда закончите, жмем на
Стоп
. Затем нажимаем комбинацию клавиш
Alt+F11
и перед нами открывается
редактор Visual Basic
. Вот в нем слева вверху есть древовидный список. В нем находится папка с названием
Modules
. В свою очередь в ней располагаются модули. Вот эти модули и есть ваши макросы. Кликнем два раза на тот модуль, который мы только что записали (если это первая запись, то модуль будет один). И тут будут отображены все ваши действия в виде исходного кода на языке Visual Basic. Вам остается только перевести это дело на Delphi.
По поводу констант. В Delphi придется объявлять их самим. Посмотреть чему они равны можно в том же редакторе Visual Basic. Делается это так. Вписываем любую нужную нам константу в редакторе. Кликаем правой клавишей мыши, чтобы появилось контекстное меню. И там выбираем пункт
«Quick Info»
. При этом будет показана всплывающая подсказка со значением этой константы. Все просто! Единственное оговорюсь. В Visual Basic будет показано так, например:
&HFFFFEFF4
, но Delphi этого не поймет. Надо объявлять в нем так:
$FFFFEFF4
.
Работа с окном (формой) Excel
FExcel.Visible := true;
Делать Excel видимым (True)/не видимым(False). При установке
Visible
в
FALSE
, программа Excel Так же пропадает из панели задач Windows.
FExcel.Application.EnableEvents := false;
Показывать (True)/не показывать(False) системные сообщения Excel. Рекомендую отключать сообщения при построении отчета. А сам код писать после создания экземпляра Excel. Это увеличит скорость создания отчета. Пример:
FExcel := CreateOleObject('Excel.Application'); FExcel.Visible := false; FExcel.Application.EnableEvents := false;
FExcel.DisplayAlerts := false;
Показывать (True)/не показывать(False) предупреждающие сообщения.
FExcel.WindowState := xlMaximized;
Состояние окна Excel:
const xlMaximized = $FFFFEFD7 (или -4137)
— развернуть Excel на весь экран.
const xlNormal = $FFFFEFD1 (или -4143)
— восстановить Excel.
const xlMinimized = $FFFFEFD4 (или -4140)
— свернуть Excel на панель задач.
FExcel.ScreenUpdating := false;
Включить (True)/отключить (False) перерисовку окон. Используется для ускорения работы макроса, т.к. в это время не обновляется экран. Я в своих проектах не использовал данный метод, но возможно построение отчета будет выполняться быстрее, если отключить обновление окон Excel. После построения отчета перерисовку окон можно будет включить обратно.
Работа над книгой (Workbooks)
FExcel.Workbooks.Open(path);
Открытие существующей книги (где path — путь к фалу). Функция Open описана так:
function Open( const Filename: String; UpdateLinks: Variant; ReadOnly: Variant; Format: Variant; Password: Variant; WriteResPassword: Variant; IgnoreReadOnlyRecommended: Variant; Origin: Variant; Delimiter: Variant; Editable: Variant; Notify: Variant; Converter: Variant; AddToMru: Variant ): Workbook;
FileName
— обязательный элемент. Имя открываемого файла, желательно с полным путем, иначе Excel будет искать этот файл в каталоге по умолчанию;
UpdateLinks
— Необязательный параметр. Определяет способ обновления связи в открываемом файле. Если данный аргумент отсутствует, то пользователю будет выдан запрос на определение способа обновления связей. Данный параметр имеет следующие допустимые значения:
0 – никакие связи не обновляются;
1 – обновляются внешние ссылки, но не обновляются удаленные ссылки;
2 – обновляются удаленные ссылки, но не обновляются внешние ссылки;
3 – обновляются оба типа ссылок
ReadOnly
— необязательный параметр. Если файл имеет атрибут только для чтения, то при открытии его в Excel выдается соответствующее предупреждение*. Чтобы его игнорировать, передайте в качестве данного параметра True.
Format
— необязательный параметр. При открытии текстового файла этот параметр определяет вид символов-разделителей. Ниже представлены допустимые значения данного аргумента:
1 – символы табуляции;
2 – запятые;
3 – пробелы;
4 – точка с запятой;
5 – разделители отсутствуют;
6 – вид разделителя определяется пользователем (с помощью параметра Delimiter).
Password
— необязательный параметр, задающий строку пароля, необходимого для открытия защищенной рабочей книги. Если при открытии защищенной книги данный аргумент отсутствует, то пользователю будет выдан запрос на ввод пароля*.
WriteResPassword
— необязательный параметр. Предназначен для задания пароля, необходимого для записи в рабочую книгу. Если при открытии защищенной книги данный аргумент отсутствует, то пользователю будет выдан запрос на ввод пароля*.
IgnoreReadOnlyRecommended
— необязательный параметр. В случае задания ему значения True этот аргумент позволяет устранить вывод сообщения с рекомендацией открытия книги только для чтения (в том случае, если данная рабочая книга была сохранена с параметром Read-Only Recommended).
Origin
— необязательный параметр. При открытии текстового файла этот параметр указывает, где был создан этот файл, что необходимо для правильного распознавания страницы кодировки. Значениями данного аргумента может быть одна из констант: xlMacintosh, xlWindows или xlMSDOS**. Если данный аргумент отсутствует, то используются текущие параметры операционной системы.
Delimiter
— необязательный параметр. Если открывается текстовый файл и параметр Format имеет значение, равное 6, то этот аргумент определяет символ-разделитель.
Editable
— необязательный параметр. Если файл является файлом MS Excel 4.0, то этот параметр при задании ему значения True позволяет открыть надстройку как видимое окно. По умолчанию ему присвоено значение False.
Notify
— необязательный параметр. Если файл не может быть открыт для записи, то при задании данному аргументу значения True файл будет добавлен в список уведомления. Если данный аргумент равен False или отсутствует, то открыть файл будет невозможно.
Converter
— необязательный параметр. Предназначен для определения индекса фильтра, который будет использован при открытии данного файла. Если фильтр не сможет распознать формат файла, то будут последовательно использованы все доступные фильтры.
AddToMRU
— необязательный параметр типа Variant. Если данный параметр имеет значение True, то рабочая книга будет добавлена в список недавно использованных файлов. По умолчанию ему присвоено значение False.
Примечание:
* Сообщения будут выведены на экран, если вы не отключили их с помощью:
FExcel.Application.EnableEvents := false;
Показывать (True)/не показывать(False) системные сообщения Excel.
** Delphi не знает о существовании констант, поэтому чтобы посмотреть их значения, нужно воспользоваться средствами VBA. Эти константы соответственно равны 1, 2 и 3.
***
FExcel.SheetsInNewWorkbook := X;
Задать количество страниц в книге, где X — это количество страниц. Диапазон значений 1..255. Данный метод применяется только с
FExcel.Workbooks.Add;
и в коде Delphi пишется перед методом Add.
FExcel.Workbooks.Add(path);
// path — путь к фалу
Создание новой книги. Причем создается стандартная книга с тремя листами. В этом методе можно указать стандартный тип шаблона Excel. Если же в нем указать имя (с полным путем) подготовленного файла (шаблоном может быть и «обычный» файл XLS, а не только файл XLT), то можно открыть книгу на диске как шаблон.
FExcel.Workbooks.Add(Template);
Template — Необязательный параметр. Этот параметр определяет, как будет создана рабочая книга. Если этот параметр будет иметь значение строки, определяющей имя файла (включая путь) существующей рабочей книги, то создается рабочая книга с использованием данного файла как шаблона. В случае когда данный параметр является одной из констант:
xlWBATExcel4IntlMacroSheet = 4;
xlWBATExcel4MacroSheet = 3;
xlWBATWorksheet = $FFFFEFB9 (или -4167);
xlWBATChart = $FFFFEFF3 (или -4109);
Создаваемая книга будет содержать один лист соответствующего типа. В том случае, если этот параметр отсутствует, то создается рабочая книга с количеством листов, определяемым значением свойства
SheetslnNewWorkbook
.
***
FExcel.Workbooks[1].SaveAs(path);
// path — путь к фалу
Сохранить книгу как… Чтобы укоротить код можно создать переменную
FWorkbook
типа
Variant
и присвоить ей ссылку либо на первую[1] книгу, либо на вновь созданную:
FWorkbook := FExcel.Workbooks[1];
либо
FWorkbook := FExcel.Workbooks.Add;
Тогда сохранение может выглядеть вот так:
FWorkbook.SaveAs(path);
// path — путь к фалу
Функция SaveAs описана так:
function SaveAs( FileName: Variant; FileFormat: Variant; Password: Variant; WriteResPassword: Variant; ReadOnlyRecommended: Variant; CreateBackup: Variant; AccessMode: Variant; ConflictResolution: Variant; AddToMru: Variant; TextCodePage: Variant; TextVisualLayout: Variant ): Workbook;
FileName
— необязательный параметр. Задает строку, определяющую имя сохраняемого файла. Можно указать полный путь или только имя файла (в этом случае файл будет сохранен в текущей папке).
FileFormat
— необязательный параметр. Данный параметр задает формат файла. Его значением может быть одна из констант, описанных в
таблице 1
. В том случае, если файл уже существует, в качестве его формата по умолчанию будет назначен формат, использовавшийся при его предыдущем сохранении.
Формат Константа Книга MS Excel xlWorkbookNormal Web-страница xlHTML Шаблон xlTemplate Текстовые файлы (с разделителями табуляции) xlTextWindows Текст Юникод xlUnicodeText Книга MS Excel 5.0/95 xlExcel7 Книга MS Excel 95/97/2000 xlExcel9795 CSV (разделители – запятые) xlCSVWindows Файл MS Excel 4.0 xlExcel4 Файл MS Excel 3.0 xlExcel3 Файл MS Excel 2.1 xlExcel2 Книга MS Excel 4.0 xlExcel4Workbook WK4 (1-2-3) xlWK4 WK3, FM3 (1-2-3) xlWK3FM3 WK3 (1-2-3) xlWK3 WK1, FMT (1-2-3) xlWK1FMT WK1, ALL (1-2-3) xlWK1ALL WK1 (1-2-3) xlWK1 WKS (1-2-3) xlWKS WQ1 (Quattro Pro/Dos) xlWQ1 DBF4 (dBase IV) xlDBF2 DBF3 (dBase III) xlDBF3 DBF2 (dBase II) xlDBF4 Форматированный текст (разделители – пробелы) xlTextPrinter Текст (Macintosh) xlTextMac Текст (MS-DOS) xlTextMSDOS CSV (Macintosh) xlCSVMac CSV (MS-DOS) xlCSVMSDOS DIF (Data Interchange Format) xlDIF SYLK (Symbolic Link) xlSYLK Надстройка MS Excel xlAddln
Таблица 1 — Форматы файлов MS Excel 2000 и соответствующие им константы.
Password
— необязательный параметр. Данный параметр определяет защитный пароль для сохраняемого файла. Пароль определяется строкой, содержащей не более 15 символов.
WriteResPassword
— необязательный параметр. Предназначен для задания строки, определяющей пароль для сохранения файла в качестве файла только для чтения. При последующем открытии файла будет выдан запрос на ввод этого пароля, и если он не будет введен, то файл будет открыт в режиме только для чтения.
ReadOnlyRecommended
— необязательный параметр. В случае присвоения ему значения True, последующее открытие файла на экране будет сопровождаться сообщением, говорящим о том, что этот файл рекомендуется открыть в режиме только для чтения.
CreateBackup
— необязательный параметр. Определяет возможность создания резервного файла (значение True).
AccessMode
— необязательный параметр. Этот параметр определяет режим доступа к рабочей книге и может иметь одно из следующих значений:
xINoChange – режим доступа не изменяется (равно 1);
xlShared – общие листы (равно 2);
xlExclusive – монопольный доступ (равно 3).
ConflictResolution
— необязательный параметр. Определяет способ разрешения конфликтов в том случае, если книга имеет общие листы. Значением данного свойства может быть значение одной из констант:
xlUserResolution — отображает окно диалога для разрешения конфликтов (равно 1);
xlLocalSessionChanges — автоматически принимаются изменения локального пользователя (равно 2);
xlOtherSessionChanges — принимаются другие изменения вместо изменений локального пользователя (равно 3).
AddToMru
— необязательный параметр. Позволяет поместить сохраняемый файл в список сохраненных файлов в меню Файл (File). Для реализации этой возможности значение этого аргумента должно равняться True.
TextCodePage
— необязательный параметр. В локализованной версии MS Office не используется.
TextVisualLayout
— необязательный параметр. В локализованной версии MS Office не используется.
***
FWorkbook.Save;
Если книга была открыта, то файл перезапишется. Если была создана новая книга, то будет задан вопрос о сохранении файла. Если вы нажмете «Нет», то будет вызвано исключение.
FWorkbook.Close;
Закрыть книгу. При этом если Excel видимый, то появится диалог с вопросом, хотите ли вы сохранить файл.
Функция Close описана так:
function Close( SaveChanges: Variant; FileName: Variant; RouteWorkbook: Variant ): Workbook;
SaveChanges
— Необязательный элемент. Если данный параметр опущен, то будет выдан запрос на сохранение файла. Если равен
FALSE
, то книга закроется без сохранения и каких-либо оповещений, даже при установленном параметре
FileName
. Если равен
TRUE
, то сразу появится проводник с предложением выбрать место, куда сохранить файл. При установленном параметре FileName, книга будет сохранена без появления каких-либо диалогов.
FileName
— Необязательный элемент. Данный параметр определяет имя файла, в который будут записаны изменения.
RouteWorkbook
— Необязательный элемент. Если он имеет значение True, то рабочая книга будет послана следующему получателю.
Примечание:
если файл уже существует, то тогда будет выведен диалог с вопросом о перезаписи файла.
Пример:
// Отключаем предупреждающие сообщения, // в нашем случае чтобы не было вопроса о том, // перезаписывать ли файл, если таковой существует FExcel.DisplayAlerts := false; // Сохраняем книгу в файл "123.xls" на диск D: FWorkbook.Close(true, 'D:123.xls');
Установка параметров страницы, предварительный просмотр и печать
FExcel.Workbooks[1].WorkSheets[1] .Name := ‘Отчёт’;
Присваиваем первому листу в первой книге имя «Отчет». Если будем работать с самим листом, то чтобы не писать много кода мы можем просто объявить новую переменную, например,
FSheet
типа
Variant
:
procedure TForm1.Button1Click(Sender: TObject); var FExcel, FSheet: Variant; begin try ... // Тут ваш код finally ... // Обязательно! нужно все созданные Variant-переменные // очищать перед выходом FSheet := Unassigned; FExcel := Unassigned; ... end; end;
Примечание
: в принципе Delphi сама следит за корректным удалением переменных, но я считаю будем правильным сделать это вручную. Не стоит полагаться на систему.
И присвоим ей ссылку на наш Лист1 первой книги:
FSheet := FExcel.Workbooks[1].WorkSheets[1]; FSheet.Name := 'Отчёт';
Вот так вот будет проще. Теперь мы будет обращаться уже к переменной
FSheet
, а не к
FExcel
.
FSheet.PageSetup.Orientation := 2;
Ориентация страницы (1 – книжная, 2 – альбомная).
FSheet.PageSetup.LeftMargin := X;
Отступ от левого края страницы
FSheet.PageSetup.RightMargin := X;
Отступ от правого края страницы
FSheet.PageSetup.TopMargin := X;
Отступ от верхнего края страницы.
FSheet.PageSetup.BottomMargin := X;
Отступ от нижнего края страницы.
FSheet.PageSetup.HeaderMargin := X;
Высота верхнего колонтитула страницы.
FSheet.PageSetup.FooterMargin := X;
Высота нижнего колонтитула страницы.
Где X — это отступ в пикселях. Можно в принципе воспользоваться функцией перевода из, например, сантиметров в пиксели. Делается это так:
FSheet.PageSetup.BottomMargin := FExcel.Application.CentimetersToPoints(1.5);
Это будет полтора сантиметра, а как там переводится в пиксели это не наша забота.
FSheet.PageSetup.Zoom := false (или значение в процентах Z);
Масштаб. Принимает следующие значения:
Z
— «Установить Z% от натуральной величины», где X – это количество процентов. Т.е. если вы решите включить масштабирование, то вам необходимо вместо
FALSE
подставить число, например: FSheet.PageSetup.Zoom := 100; (что означает 100%).
FALSE
— «Разместить не более чем на: X стр. в ширину и Y стр. в высоту, где:
FSheet.PageSetup.FitToPagesWide := 1;
Количество страниц в ширину (X).
FSheet.PageSetup.FitToPagesTall := 100;
Количество страниц в высоту (Y).
FSheet.PageSetup.CenterFooter := ‘Стр. &С из &К’
;
Центральный нижний колонтитул. В нем будет информации о номере страницы из всего страниц. Данные переменные (&C, &K и т.п.) описаны в справочнике самого Excel. Аналогично:
FSheet.PageSetup.LeftFooter:=’Левый нижний колонтитул’;
FSheet.PageSetup.RightFooter:=’Правый нижний колонтитул’;
FSheet.PageSetup.LeftHeader:=’Левый верхний колонтитул’;
FSheet.PageSetup.CenterHeader:=’Центральный верхний колонтитул’;
FSheet.PageSetup.RightHeader:=’&7Правый верхний колонтитул’;
*
Примечание:
*для изменения размера шрифта добавьте к колонтитулу управляющий символ «&» и размер шрифта, в нашем случае 7
// const xlAutomatic = $FFFFEFF7 (или -4105)
FSheet.PageSetup.FirstPageNumber := xlAutomatic;
Номер первой страницы. В данном случае «Авто».
FSheet.PageSetup.Order := 1;
Последовательность вывода страниц на печать (1 — вниз, затем вправо; 2 — вправо, затем вниз).
FSheet.PrintPreview;
Предварительный просмотр страницы. Если вы не продолжите печать, а нажмете «Отмена», то будет вызвано исключение.
Примечание
: Excel, перед выполнением этой команды, обязательно должен быть видимым (FExcel.Visible := true;).
FSheet.PrintOut;
Вывод страницы на печать. Функция PrintOut описана так:
function PrintOut( From: Variant; To: Variant; Copies: Variant; Preview: Variant; ActivePrinter: Variant; PrintToFile: Variant; Collate: Variant ): Workbook;
From
— необязательный параметр. Задает страницу, с которой начинается печать. Если этот аргумент отсутствует, то печать начинается с первой страницы.
To
— необязательный параметр. Задает последнюю печатаемую страницу. Если этот аргумент отсутствует, то печать продолжается до последней страницы.
Copies
— необязательный параметр. Задает количество печатаемых копий.
Preview
— необязательный параметр, принимающий одно из двух значений:
TRUE
— приводит к выводу перед печатью окна предварительного просмотра;
FALSE
(значение по умолчанию) — печать производится без предварительного просмотра.
ActivePrinter
— необязательный параметр. Задает имя активного принтера.
PrintToFile
— необязательный параметр. Если данный параметр имеет значение True, то производится печать в файл. При этом пользователю выдается запрос на ввод имени файла.
Collate
— необязательный параметр. Если ему задать значение True, то копии будут объединены.
Пример:
FExcel.Application.EnableEvents := true; FExcel.DisplayAlerts := true; FExcel.Visible := true; FSheet.PrintOut(1, 2, 1, False, PrintToFile := True)
Печатаем с 1 по 2 страницы, одну копию, без предварительного просмотра в файл. Заметьте, что мы пропустили параметр ActivePrinter. Мы просто объявили PrintToFile := True.
***
Статья не окончена. Продолжение следует…
При составлении справочника я использовал собственные наработки и информацию со следующих сайтов:
1)
www.taurion.ru/excel
2)
www.superadm.net/index.php?name=pages&op=cat&id=19
3)
www.afalinasoft.com/rus/tips/
4)
www.codenet.ru/progr/delphi/stat/Excel-Export.php
Так же не обошлось без составления макросов в редакторе Visual Basic и последующим переводом кода из VBA в среду разработки Delphi 2010.
Эта статья первая из цикла статей посвященных экспорту документов в MS Excel. В ней мы рассмотрим подключение к Excel, заполнению ячеек и простейшее оформление документа.
Я не буду углубляться в теорию, рассказывать о том как работает OLE механизм, начнем с самого главного.
Подключение.
Для подключения к Excel и работы с ним нам понадобится переменная типа Variant:
Excel:Variant;
Далее создаем OLE объект:
Excel:=CreateOleObject('Excel.Application');
Добавляем новую книгу:
Excel.Workbooks.Add;
Показываем Excel:
Excel.Visible:=true;
Так же нам понадобятся константы:
const xlContinuous=1; xlThin=2; xlTop = -4160; xlCenter = -4108;
Текст ячеек.
Теперь до любой ячейки мы можем добраться следующим образом:
Excel.ActiveWorkBook.WorkSheets[1].Cells[1, 2]:='Текст ячейки (1,2)';
Объект Range, выделение диапазона, объединение ячеек, выравнивание.
Представьте такую ситуацию: необходимо объединить несколько ячеек и выровнять текст в них по центру.
Выделяем:
Excel.ActiveWorkBook.WorkSheets[1].Range['A1:G1'].Select;
Объединяем:
Excel.ActiveWorkBook.WorkSheets[1].Range['A1:G1'].Merge;
И выравниваем:
Excel.Selection.HorizontalAlignment:=xlCenter;
Границы и перенос по словам.
Для начала выделяем нужный диапазон а затем…
Показываем границы:
Excel.Selection.Borders.LineStyle:=xlContinuous; Excel.Selection.Borders.Weight:=xlThin;
И включаем перенос по словам:
Excel.Selection.WrapText:=true;
Пример.
Пример можно скачать здесь
Параметры страницы.
Начнем с полей страницы. Во первых для того чтобы добраться до параметров страницы у листа Excel имеется свойство объект PageSetup его мы и будем использовать. Для установки размеров полей необходимо изменить соответствующие свойства PageSetup, вот эти свойства:
- LeftMargin — Левое поле
- RightMargin — Правое поле
- TopMargin — Верхнее поле
- BottomMargin — Нижнее поле
Значение размеров полей необходимо указывать в пикселях, к чему мы не очень привыкли, поэтому воспользуемся функцией InchesToPoints объекта Application, которая переводит значение в дюймах в значение в пикселях. Теперь напишем процедуру которая подключит Excel и установит поля равные 0.44 дюйма (приблизительно 1 см):
procedure Connect; var Excel:Variant; begin Excel:=CreateOleObject('Excel.Application'); Excel.Workbooks.Add; Excel.ActiveSheet.PageSetup.LeftMargin:= Excel.Application.InchesToPoints(0.44); Excel.ActiveSheet.PageSetup.RightMargin:= Excel.Application.InchesToPoints(0.44); Excel.ActiveSheet.PageSetup.TopMargin:= Excel.Application.InchesToPoints(0.44); Excel.ActiveSheet.PageSetup.BottomMargin:= Excel.Application.InchesToPoints(0.44); end;
Иногда полезно уметь установить и ориентацию страницы:
Excel.ActiveSheet.PageSetup.Orientation:= 2;
Здесь значение ориентации = 2, означает альбомную, при книжной ориентации присвойте Orientation значение 1.
Вы наверное не раз встречали такой отчет в котором таблица с большим количеством строк размещается на нескольких страницах в таких случаях очень удобны сквозные строки, они печатаются на каждой странице отчета:
Excel.ActiveSheet.PageSetup.PrintTitleRows:='$2:$3';
Здесь мы указываем вторую и третью строки для печати на каждой странице.
Шрифты и цвета.
Для установки шрифта и размера текста выделите нужный диапазон и установите свойство Name объекта-свойства Font объекта Selection или свойство Size для изменения размера:
Excel.ActiveWorkBook.WorkSheets[1].Range['F1'].Select; Excel.Selection.Font.Name:='Courier New'; Excel.Selection.Font.Size:=18;
Если Вы хотите установить жирный или, например, наклонный стиль написания текста установите соответствующие свойства:
Excel.ActiveWorkBook.WorkSheets[1].Range['G1'].Select; Excel.Selection.Font.Bold:=true; // Для жирного текста Excel.Selection.Font.Italic:=true; // Для наклонного текста
Для указания цвета текста измените свойство ColorIndex все того же объекта Font:
Excel.ActiveWorkBook.WorkSheets[1].Range['A1'].Select; Excel.Selection.Font.ColorIndex:=3;
Вот несколько индексов цветов:
- Индекс — Цвет
- 0 — Авто
- 2 — Белый
- 3 — Красный
- 5 — Синий
- 6 — Желтый
- 10 — Зеленый
Для изменения цвета фона ячейки используйте объект Interior свойства Selection:
Excel.ActiveWorkBook.WorkSheets[1].Range['H1'].Select; Excel.Selection.Interior.ColorIndex:=3; // Цвет
Колонтитулы.
Для добавления колонтитула к документу достаточно указать его содержание:
Excel.ActiveSheet.PageSetup.LeftFooter:='Левый нижний колонтитул'; Excel.ActiveSheet.PageSetup.CenterFooter:='Центральный нижний колонтитул'; Excel.ActiveSheet.PageSetup.RightFooter:='Правый нижний колонтитул'; Excel.ActiveSheet.PageSetup.LeftHeader:='Левый верхний колонтитул'; Excel.ActiveSheet.PageSetup.CenterHeader:='Центральный верхний колонтитул'; Excel.ActiveSheet.PageSetup.RightHeader:='Правый верхний колонтитул';
Для изменения размера шрифта добавьте к колонтитулу управляющий символ «&» и размер шрифта:
Excel.ActiveSheet.PageSetup.LeftFooter:='&7Левый нижний колонтитул';
На этом пока все. Пример к статье здесь
Программирование. Теория и практика.
Обмен данными с MS Excel в Delphi при помощи OLE.
Обмен данными с MS Excel в Delphi при помощи OLE.
Здравствуйте уважаемые коллеги!
Все мы рано или поздно сталкиваемся с задачами обмена данных с приложениями пакета MS Office. Одно из них — это MS Excel. И именно о взаимодействии с данным продуктом MS Office пойдет речь в данной статье.
Один из способов взаимодействия Delphi c MS Excel — это подключиться к нему как к OLE объекту.
Итак.
Прежде всего для работы с MS Excel и OLE добавим в секцию Uses модули ComObj и ActiveX.
И первое что нам нужно проверить, а установлен ли MS Excel на компьютере пользователя в принципе.
Для этого воспользуемся функцией CLSIDFromProgID, которая ищет в реестре CLSID для переданного ProgID:
Справка из MSDN: Метод CLSIDFromProgID
Параметры:
pszProgID: POleStr — Строка с именем объекта
clsid: TCLSID — Указатель на структуру TGUID в которую передается найденный объект;
Возвращает:
HRESULT — Результат, который может принимать значения:
S_OK — объект найден;
CO_E_CLASSSTRING — Зарегистрированный CLSID для ProgID является недействительным;
REGDB_E_WRITEREGDB — Ошибка записи CLSID в реестр.
Из перечисленных результатов нам нужен S_OK.
Напишем функию для определения наличия Excel у пользователя:
Если Excel установлен, тогда выполним подключение к нему. Сделать это можно двумя способами: GetActiveOleObject — Получить ссылку на уже запущенный экземпляр Excel или CreateOleObject — Создать новый экземпляр Excel.
Если у нас стоит задача получать данные из запущенного Excel, тогда мы должны использовать только первый вариант, в остальных случаях пробуем подключиться и если не получается, то создаем.
Напишем 2 функции, для подключения XlsConnect и запуска нового XlsStart:
Добавим переменную FXlsApp с типом Variant, которая будет содержать в себе ссылку на объект Excel.
Теперь можно добавить кнопку, на клик которой подключимся к MS Excel используя написанные функции:
По умолчанию окно Excel запускается в фоновом режиме. Строка FXlsApp.Visible := True; делает фоновое окно Excel видимым.
Окно Excel запускается пустое и в него нужно добавить рабочую книгу. Делается это при помощи метода WorkBooks.Add, который добавляет новую книгу или открывает ранее сохраненную, если указать путь к файлу.
Добавим процедуру, которая будет это делать:
Книга добавлена, теперь попробуем записать что-нибудь в неё.
Где Row — индекс строки, и Col — индекс столбца, которые начинаются с единицы.
Где Range — массив ячеек, а А1 — привычные для Excel координаты ячейки.
В качестве координат может быть указан диапазон. Например, код
заполнит цифрой 5 все ячейки с А3 по А10, а код
выделит тот же диапазон светло-зеленым цветом.
В обратную сторону, то есть для получения данных из Excel, работает так же. Строка
Выведет сообщение с содержимым ячейки с координатами: Строка=5, Столбец=1.
После того, как мы произвели необходимые нам манипуляции с Excel, мы можем сохранить полученную книгу в файл следующей командой:
Где ActiveWorkbook — текущая книга.
И закрыть приложение Excel командой:
Как понимаете этим возможности управления Excel из Delphi не ограничиваются. И есть один достаточной простой способ узнать, как выполнить необходимо действие с Excel из Delphi.
Называется оно — Макросы.
Представим, что нам необходимо выполнить объединение нескольких ячеек в одну и мы не знаем как это сделать. Но хотим узнать. Для этого выполняем следующие шаги:
1. Запускаем Excel и создаем пустую книгу.
2. Запускаем команду «Записать макрос», по умолчанию название макроса будет «Макрос1». (В разных версиях Excel данная команда находится в разных пунктах меню).
3. Выделяем некоторый диапазон ячеек и нажимаем кнопку «Объединить и поместить в центре».
4. Останавливаем запись макроса.
5. Вызываем список макросов и выбираем там свой записанный макрос.
6. Нажимаем кнопку «Изменить»
Запускается редактор Microsoft Visual Basic for Application в котором видим код проделанных действий:
Давайте разберем по подробнее, что же такого он нам тут написал:
With Selection — Для выделенного диапазона ячеек настраиваем свойства:
HorizontalAlignment = xlCenter — Горизонтальная ориентация = по центру.
VerticalAlignment = xlBottom — Вертикальная ориентация — по нижнему краю.
WrapText = False — Перенос текста по словам — выключен.
Orientation = 0 — Ориентация 0 градусов.
AddIndent = False — Использование автоматического отступа вкл/выкл.
IndentLevel = 0 — Уровень отступа в 0.
ShrinkToFit = False — Сжимать текст по размерам столбца вкл/выкл.
ReadingOrder = xlContext — Порядок чтения по контексту.
MergeCells = False — Объединенные ячейки вкл/выкл
End With — Конец секции работы с выделенным диапазоном.
Selection.Merge — Объединить выделенный диапазон.
Теперь попробуем объединить ячейки из Delphi:
Выделяем нужный нам диапазон.
Объединяем ячейки задав свойство. Или при помощи метода:
Таким способом можно получать код практически для любых необходимых манипуляций.
А если какое-то свойство или метод вызывает вопросы, то можно воспользоваться справкой на MSDN.
Обратите внимание на особенность работы с массивами в VBA. Индексы в массивах в Delphi оборачиваются в квадратные скобки, в то время как в VBA они будут в круглых. И код в Delphi
в VBA будет выглядеть как
Ниже приведу небольшой FAQ по вопросу взаимодействия с Excel из Delphi
Как определить значения констант в Excel для использования в Delphi?
В редакторе VBA ставим точку остановки напротив интересующей константы. Нажимаем выполнить и когда выполнение остановиться, наводим на интересующую константу:
Как отключить выводы сообщений в Excel?
Как получить список книг из Excel?
Как отключить отображение сетки?
Как вывести текущий лист на предпросмотр печати?
Как выделить жирным часть текста в ячейки?
Как выполнить автоподбор высоты строки для склеенной ячейки?
Как получить используемый диапазон ячеек?
Как получить букву столбца по индексу?
Обращение к Excel из Delphi
В данном обзоре рассмотрены основные конструкции, позволяющие получить доступ к книге Excel из Delphi.
Организация доступа к книге EXCEL
Для взаимодействия с MS excel в программе необходимо использовать модуль ComObj и объявить переменную для доступа к MS Excel вариантного типа.
Инициализацию переменной Excel в простейшем случае можно осуществить так:
Создание новой книги:
Открытие существующей книги (где path — путь к фалу с расширением xls.):
Открытие существующей книги только для чтения:
Блокировка запросов (подтвеждений, уведомлений) Excel, например, запретить запрос на сохранение файла:
Отображаем или скрываем Excel на экране:
Печать содержимого активного листа Excel:
Чтение/запись данных в EXCEL
Доступ к ячейке в текущей книге Excel можно осуществить следующим образом:
Или используя стиль ссылок R1C1:
Вообще, ячейке Excel можно присваивать любое значение (символьное, целое, дробное, дата) при этом Excel установит форматирование в ячейке применяемое по умолчанию.
Формат ячеек в EXCEL
Выделить (выбрать) группу ячеек для последующей работы можно так:
После выполнения выделения можно установить:
1) Объединение ячеек:
4) Вериткальное выравнивание
Использование паролей в EXCEL
Установка пароля для активной книги может быть произведена следующим образом:
Снятие пароля с книги аналогично, использовуем команду
Установка и снятие пароля для активного листа книги Excel производится командами
Вспомогательные операции в EXCEL
Удаление строк со сдвигом вверх (при выполнении данных действий будут удалены строки с 5 по 15):
Установка закрепления области на активном листе Excel:
Работа в excel в delphi
Очень многие документы создаются и хранятся в формате электронных таблиц Microsoft Excel. Несмотря на то, что эти таблицы обладают возможностями для автоматической обработки документа, нам, дельфистам, гораздо приятнее работать в привычной среде, что которая и обладает к тому же гораздо более развитыми возможностями. Давайте посмотрим, как получать данные из Excel. Естественно, табличные данные будем размещать в привычную нам таблицу StringGrid.
Для работы с Excel и другими программами из пакета Microsoft Office необходимо добавить в список uses модуль ComObj:
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 Формы напишите:
Естественно, будет произведён выход из 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 слово ‘Привет’ :
Работа с Excel в Delphi. Основы основ.
Видимо любители экономить килобайты оперативной памяти могут меня закидать помидорами или ещё чем по-хуже, но все-таки я скажу, что интеграция приложений (мегабайты оперативы) — это большой плюс нынешней разработки приложений.
Как ни крути, а время DOS и килобайтов оперативной памяти прошло. Вряд ли кто-то всерьез сейчас задумывается над тем куда это с винчестера пропал мегабайт? Да и использование в своих приложениях функциональности программ, которых ты не писал, но которые выполняют что-то лучше — это всё-таки больший прогресс, нежели корпеть год-два над программой, а потом узнать, что время-то прошло.
План статьи:
Итак, цель сегодняшней статьи — поделиться с Вами опытом работы с Microsoft Excel в приложениях, написанных на Delphi.
Вспомнился сейчас один случай. Когда я только начинал работать по своей специальности, пригласили меня написать программу-расчётник для экологов нашего нефтезавода. В принципе ничего серьёзного — программа считает выброс от нагревательной печи и выдает табличку результатов, которую необходимо распечатать и уложить в толстую папку с отчётами. Естественно, что в области разработки подобных приложения я далеко не пионер, поэтому дали взглянуть на аналог будущей программы, который работал ещё под DOS и печатались отчёты на дико скрипящем матричном принтере с 12-ю иголками. Ну посмотрел, элементарная таблица, расчёт немного запутан, но жить можно — начал по-тихоньку писать. И попалась мне тогда на глаза статейка про работу с Excel в Delphi. Вот я и решил попробовать выдавать отчёт не только на форму приложения, а ещё и скидывать весь ход расчёта с формулами и прочим делом в Excel…Надо сказать более сильно детской радости начальника отдела я не видел до сих пор :). Люди, всю жизнь проработавшие в DOS увидели как тот же самый расчёт может выглядеть в современных условиях. Вот теперь при определении технических заданий на каждую новую программу, обязательно присутствует пункт, гласящий, что программа должна передавать данные либо в MS Word либо в MS Excel.Соответственно и цена на разработку возрастает, иногда значительно.
Отсюда можно сделать простой и однозначный вывод — заказчики готовы пожертвовать лишними деньгами только для того, чтобы всё в программе было красиво. Excel может дать вашему приложению ту самую красоту и удобство.
Ну, а для того, чтобы каждый раз не утруждать себя выполнением однотипных операций, я разработал небольшой модуль для работы с Excel. Этот же модуль я в настоящее время дорабатываю под ещё одну задачу, но об этом после. Сегодня основы основ работы с Excel в Delphi.
1. Как проверить установлен ли Excel на компьютере пользователя?
Создаем новый модуль (unit) и подключаем в uses следующие модули:
Канал в Telegram
Читаем файл Excel (xls) в Delphi
При написании бизнес приложений на Delphi, выполняющих какие либо расчеты, может возникнуть необходимость импорта (экспорта) данных из файлов других приложений. Одно из основных таких приложений – MS Excel. Как прочитать файлы xls в Delphi мы сейчас и рассмотрим!?
Создадим новый проект и разместим на форме три компонента:
StringGrid – находится на палитре компонентов, во вкладке Additional
Кнопку Button и для удобства выбора файлов, диалог открытия файлов (работа с диалогами описана здесь).
Для StringGrid, в свойствах(Properties) укажем следующее:
DefaultRowHeight – 17
FixedCols – 0
FixedRows – 0
В результате форма будет выглядеть примерно так:
На этом украшательства закончим и приступим к написанию кода.
Для работы с Excel файлами нам понадобится библиотека ComObj, входящая в стандартную поставку Delphi. Подключается она в разделе Uses. Добавьте в конце, после запятой «ComObj».
Теперь опишите процедуру Xls_Open после ключевого слова implementation:
procedure Xls_Open(XLSFile:string; Grid:TStringGrid);
const
xlCellTypeLastCell = $0000000B;
var
ExlApp, Sheet: OLEVariant;
i, j, r, c:integer;
begin
//создаем объект Excel
ExlApp := CreateOleObject(‘Excel.Application’);
//делаем окно Excel невидимым
ExlApp.Visible := false;
//открываем файл XLSFile
ExlApp.Workbooks.Open(XLSFile);
//создаем объект Sheet(страница) и указываем номер листа (1)
//в книге, с которого будем осуществлять чтение
Sheet := ExlApp.Workbooks[ExtractFileName(XLSFile)].WorkSheets[1];
//активируем последнюю ячейку на листе
Sheet.Cells.SpecialCells(xlCellTypeLastCell, EmptyParam).Activate;
// Возвращает номер последней строки
r := ExlApp.ActiveCell.Row;
// Возвращает номер последнего столбца
c := ExlApp.ActiveCell.Column;
//устанавливаем кол-во столбцов и строк в StringGrid
Grid.RowCount:=r;
Grid.ColCount:=c;
//считываем значение из каждой ячейки и копируем в нашу таблицу
for j:= 1 to r do
for i:= 1 to c do
Grid.Cells[i-1,j-1]:= sheet.cells[j,i];
//если необходимо прочитать формулы то
//Grid.Cells[i-1,j-1]:= sheet.cells[j,i].formula;
//закрываем приложение Excel
ExlApp.Quit;
//очищаем выделенную память
ExlApp := Unassigned;
Sheet := Unassigned;
end;
Наша процедура Xls_Open имеет два входных параметра:
- XLSFile – путь к файлу Excel (xls)
- Grid – таблица, в которую будем осуществлять вывод данных.
В комментариях к коду я постарался все расписать, объясню немного принцип работы процедуры.
Мы создаем в памяти объект ExlApp с приложением Excel.Application. Затем указываем что этот объект будет невидим для пользователя ExlApp.Visible := false (если false заменить на true, то при открытии файла мы увидим окно Excel с открываемым файлом). Далее открывается файл ExlApp.Workbooks.Open(XLSFile). Потом создаем еще один объект Sheet, который позволяет работать с листом книги Excel: Sheet := ExlApp.Workbooks[ExtractFileName(XLSFile)].WorkSheets[1]. Единица в конце указывает номер листа с которого будем читать данные (к листам можно обращаться по имени, для этого вместо 1 указываем «ИмяЛиста1»). Далее определяем кол-во строк и столбцов которые содержат данные, и используя циклы For считываем данные копируя их в StringGrid. Впринципе и все.
Для использования процедуры Xls_Open пропишем в событие Click кнопки Button1 следующее:
If OpenDialog1.Execute then Xls_Open (OpenDialog1.FileName, StringGrid1);
Основные недостатки этого способа: медленное чтение данных (хотя для небольших файлов вполне сгодится) и необходимость установленной версии Excel на компьютере пользователя.
Полный листинг программы:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, StdCtrls,ComObj;
type
TForm1 = class(TForm)
StringGrid1: TStringGrid;
Button1: TButton;
OpenDialog1: TOpenDialog;
procedure Button1Click(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
procedure Xls_Open(XLSFile:string; Grid:TStringGrid);
const
xlCellTypeLastCell = $0000000B;
var
ExlApp, Sheet: OLEVariant;
i, j, r, c:integer;
begin
//создаем объект Excel
ExlApp := CreateOleObject(‘Excel.Application’);
//делаем окно Excel невидимым
ExlApp.Visible := false;
//открываем файл XLSFile
ExlApp.Workbooks.Open(XLSFile);
//создаем объект Sheet(страница) и указываем номер листа (1)
//в книге, с которого будем осуществлять чтение
Sheet := ExlApp.Workbooks[ExtractFileName(XLSFile)].WorkSheets[1];
//активируем последнюю ячейку на листе
Sheet.Cells.SpecialCells(xlCellTypeLastCell, EmptyParam).Activate;
// Возвращает номер последней строки
r := ExlApp.ActiveCell.Row;
// Возвращает номер последнего столбца
c := ExlApp.ActiveCell.Column;
//устанавливаем кол-во столбцов и строк в StringGrid
Grid.RowCount:=r;
Grid.ColCount:=c;
//считываем значение из каждой ячейки и копируем в нашу таблицу
for j:= 1 to r do
for i:= 1 to c do
Grid.Cells[i-1,j-1]:= sheet.cells[j,i];
//если необходимо прочитать формулы то
//Grid.Cells[i-1,j-1]:= sheet.cells[j,i].formula;
//закрываем приложение Excel
ExlApp.Quit;
//очищаем выделенную память
ExlApp := Unassigned;
Sheet := Unassigned;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
If OpenDialog1.Execute then Xls_Open (OpenDialog1.FileName, StringGrid1);
end;
end.
Обновленный пример. Добавлена функция отбора строк по критерию. Так же добавлен обработчик делающий отображение шрифта «шапки» в StringGrid жирным. Все дополнения постарался по максимуму раскомментить