Для работы с 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;@’// формат время |
0 / 0 / 0 Регистрация: 01.10.2009 Сообщений: 3 |
|
1 |
|
01.10.2009, 15:14. Показов 2163. Ответов 1
Кто-нибудь знает программу или как ее написать, которая бы собирала несколько excel файлов в один итоговый excel-ий файл, размещая данные каждого файла на отдельной страничке итогового файла. Было бы хорошо чтобы можно было бы эту прогу поставить скажем в определенное время выполнять эту операцию на сервере.
0 |
Mawrat 13094 / 5875 / 1706 Регистрация: 19.09.2009 Сообщений: 8,808 |
||||
01.10.2009, 23:04 |
2 |
|||
Сообщение было отмечено polcta как решение РешениеСхема решения примерно такая:
0 |
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
В прошлые раз мы с Вами остановились на сохранении рабочей книги. В принципе, ничего сложного в запуске Excel, создании и сохранении рабочей книги нет. Сегодня заглянем немного глубже в работу с Microsoft Excel в Delphi — рассмотрим как можно работать с листами рабочей книги, изменять внешний вид ячеек и попробуем скопировать таблицу из своего приложения в открытую рабочую книгу.
План статьи:
- Объекты Microsoft Excel
- Как активировать лист рабочей книги Excel?
- Методы листа книги Excel
Однако прежде, чем забираться в дебри Excel я хотел продемонстрировать Вам насколько глубоко мы сегодня заглянем.
1. Объекты Microsoft Excel
На рисунке я попробовал изобразить объектную модель Excel в миниатюре. Т.е. из этой модели исключены не требующиеся пока нам элементы, например такие, как свойства рабочей книги или выделенные объекты Selection — об этом речь пойдет позже.
Как Вы можете судить по представленной модели, а также и по собственному опыту работы, приложение Excel в общем случае может содержать коллекцию рабочих книг (WorkBooks Collection). Для доступа к конкретной рабочей книге мы с Вами использовали свойства Item коллекции:
WorkBook:=WorkBooks.Item[index]
где index — порядковый номер рабочей книги в коллекции WorkBooks.
И на этом наше первое знакомство с Excel закончилось. Между тем, каждая отдельная рабочая книга может содержать N листов, каждый из которых состоит из N ячеек, которые могут быть объединены в объекты Range.
На каждой из ступеней этой модели можно останавливаться и изучать её месяцами. Если будет особая необходимость в изучении каких-либо дополнительных свойств и методов — мы обязательно вернемся и изучим. А теперь, приступим к работе в Delphi с листами рабочей книги.
2. Как активировать лист рабочей книги Excel?
Как Вы знаете при создании пустой рабочей книги Excel автоматически добавляет в эту книгу 3 пустых листа. Чтобы работать с конкретным листом (WorkSheet или просто Sheet) этот лист необходимо активировать. Один из способов активации листа рабочей книги Excel в Delphi выглядит следующим образом:
resourcestring rsEInvalidSheetIndex = 'Задан неверный индекс для WorkBooks. Активация листа прервана'; rsEInvalidSheetActivate = 'Активация листа завершена с ошибкой'; function ActivateSheet(WBIndex: integer; SheetName: string): boolean; var i: integer; begin Result := false; if WBIndex > MyExcel.WorkBooks.Count then raise Exception.Create(rsEInvalidSheetIndex); try for i := 1 to MyExcel.WorkBooks[WBIndex].Sheets.Count do if AnsiLowerCase(MyExcel.WorkBooks[WBIndex].Sheets.Item[i].Name) = AnsiLowerCase(SheetName) then begin MyExcel.WorkBooks[WBIndex].Sheets.Item[i].Activate; Result := true; break; end; except raise Exception.Create(rsEInvalidSheetActivate); end; end;
Здесь в качестве параметров функции задается индекс рабочей книги (WBIndex) в коллекции WorkBooks и название листа.
Если хотите, то можете активировать тот же лист по индексу в коллекции WorkSheets — при этом сама функция немного упрощается (не требуется условие проверки названия листа).
Также, если вы уверены, что в данный момент времени активна необходимая Вам рабочая книга, то можно избежать использования лишней переменной (индекса рабочей книги WBIndex) и активировать лист вот так:
MyExcel.ActiveWorkBook.Sheets.Item[i].Activate;
Теперь рассмотрим более подробно методы, используемые объектом WorkSheet.
3. Методы листа книги Excel
Теперь рассмотрим более подробно объект WorkSheet.
На рисунке представлены те методы, которые я когда-либо использовал в своей работе.
Всего объект WorkSheet насчитывает 30 различных методов, которые Вы можете использовать.
Метод | Описание |
Activate | Делает текущий лист активным. Работу метода мы уже с Вами рассмотрели |
Calculate | рассчитывает все открытые книги, конкретный лист в книге, или указанный диапазон ячеек на листе |
CheckSpelling | проверка орфографии на выбранном листе |
SaveAs | сохраняет все изменения в файле |
Delete | удаляет текущий лист WorkSheet |
Select | выделение листа |
Copy | копирует лист в другое место в рабочей книге |
Paste | вставляет содержимое буфера обмена на лист |
ChartObjects | возвращает объект, который представляет собой либо одну диаграмму (объект ChartObject) или совокупность всех диаграмм (объект ChartObjects) на листе |
Move | перемещение листа. Этот метод аналогичен методу Copy. Различие лишь в том, что после вcтавки копируемый лист удаляется из книги |
Рассмотрим теперь каждый из представленных выше методов.
Ниже, в качестве expression должен выступать лист (WorkSheet), если не сказано иное.
Метод Calculate
Расчёт рабочей книги, листа или диапазона ячеек.
Стоит отметить, что вызов метода Calculate возможен не только для конкретного рабочего листа книги Excel. Рассмотрим варианты вызова метода Calculate.
Как рассчитать все открытые в данный момент книги Excel в Delphi?
var MyExcel: OleVariant; MyExcel.Calculate
Как рассчитать отдельный лист книги Excel в Delphi?
в приведенном ниже фрагменте кода рассчитывается активный лист
MyExcel.ActiveWorkBook.ActiveWorkSheet.Calculate
Как рассчитать диапазон ячеек листа Excel в Delphi?
Рассчитаем все формулы в столбцах A, B и C:
MyExcel.ActiveWorkBook.ActiveWorkSheet.UsedRange.Columns("A:C").Calculate
Метод CheckSpelling
Вызов метода выглядит следующим образом:
expression.CheckSpelling(CustomDictionary, IgnoreUppercase, AlwaysSuggest, SpellLang)
При этом в качестве expression должен выступать лист (WorkSheet).
Параметр | Тип | Описание |
CustomDictionary | Variant | строка, указывающая имя файла пользовательского словаря, который будет рассмотрен, если слово не найдено в основном словаре. Если этот аргумент опущен, то будет использоваться словарь по-умолчанию |
IgnoreUppercase | Variant | True, если необходимо, чтобы Microsoft Excel пропускал слова, которые написаны прописными буквами. False для того, чтобы Microsoft Excel проверить все слова. Если этот аргумент опущен, то используются текущие настройки Excel. |
AlwaysSuggest | Variant | True, для того, чтобы Microsoft Excel отображал список предложений других вариантов написания при обнаружении неправильного написанного слова. False, чтобы Microsoft Excel ожидал ввода правильного написание. Если этот аргумент опущен, то используются текущие настройки. |
SpellLang | Variant | язык словаря. Может принимать значения одной из констант MsoLanguageID, например для русского языка SpellLang = 1049, для английского (США) SpellLang = 1033 и т.д. Более подробно про идентификаторы языков см. эту статью. |
Как проверить грамматику на листе Excel в Delphi?
MyExcel.ActiveWorkBook.ActiveWorkSheet.CheckSpelling(CustomDictionary:=EmptyParam, IgnoreUppercase:= false, AlwaysSuggest:=EmptyParam, SpellLang:=1033)
в этом случае MS Excel проверит текущий лист, включая проверку слов из прописных букв. Язык проверки — русский. Обратите внимание, что для того, чтобы вызвать метод мы явно указывали, какому параметру какое значение присвоить. Причём для того, чтобы пропустить какой-либо параметр, мы использовали EmptyParam (пустой параметр), который в Delphi представляет собой переменную типа OleVariant.
Понятно, что подобный способ вызова методов (с явным указанием всех параметров) для Вас не совсем удобен и широко не практикуется в программировании на Delphi, но тем не менее только так и никак иначе можно вызывать методы, используемые в Excel.
Метод SaveAs
Сохранение рабочего листа книги Excel.
Вызов метода:
expression.SaveAs(FileName, FileFormat, Password, WriteResPassword, ReadOnlyRecommended, CreateBackup, AddToMru,TextCodepage, TextVisualLayout, Local)
Параметр | Тип | Описание |
FileName | Variant | строка, представляющая собой имя сохраняемого файла. Необходимо указывать полный путь к файлу, иначе файл будет сохранен в папку Excel. |
FileFormat | Variant | формат файла, который используется при сохранении. По умолчанию файл сохраняется в формате, который вы выбирали в последний раз в Excel. |
Password | Variant | пароль для файла (не более 15 символов). Пароль чувствителен к регистру. |
WriteResPassword | Variant | пароль, который будет использоваться для внесения изменений в рабочую книгу. Если пароль не будет указан, то книга будет открыта в режиме «Только для чтения» |
ReadOnlyRecommended | Variant | если параметр равен True, то при открытии файла на дисплее появится сообщение, в котором рекомендуется, что бы файл был открыт только для чтения. |
CreateBackup | Variant | True, для того, чтобы создать резервный файл |
AddToMru | Variant | True, для того, чтобы добавить имя сохраняемого файла в список недавно открытых файлов в главном меню Excel |
TextCodepage и TextVisualLayout | Variant | в настоящее время не используются и сохранены для обеспечения обратной совместимости |
Local | Variant | не обязательный параметр, по-умолчанию равен False. Значение True — сохранение файлов с языковыми Microsoft Excel (в том числе настройки панели управления). |
Как сохранить активный лист рабочей книги Excel в Delphi?
MyExcel.ActiveWorkBook.ActiveWorkSheet.SaveAs('C:MyExcelFile.xls')
В этом случае при сохранении будут использованы настройки по умолчанию.
Если Вам необходимо сохранить файл Excel в другом формате, то в параметре FileFormat можно использовать одно из значений перечислителя xlFileFormat. Некоторые значения xlFileFormat представлены в таблице ниже:
Имя | Значение | Описание | Расширение файла |
xlCSV | 6 | CSV | *.csv |
xlExcel8 | 56 | Книга Excel 97-2003 | *.xls |
xlHtml | 44 | Формат HTML | *.htm; *.HTML |
xlOpenDocumentSpreadsheet | 60 | Электронная таблица OpenDocument | *.ods |
xlOpenXMLWorkbook | 51 | Книга Open XML | *.xlsx |
Как сохранить активный лист рабочей книги Excel в заданном формате?
Напишем небольшую процедуру, позволяющую сохранять лист Excel в различных форматах:
const xlCSV = 6; xlExcel8 = 56; xlHtml =44; xlOpenDocumentSpreadsheet = 60; xlOpenXMLWorkbook = 51; resourcestring rsESaveActiveSheet = 'Ошибка сохранения активного листа книги'; procedure SaveAs(const AFileName: TFileName; AFileFormat: integer); begin try MyExcel.ActiveWorkBook.ActiveSheet.SaveAs(AFileName, AFileFormat); except raise Exception.Create(rsESaveActiveSheet); end; end;
Метод Delete
Удаление рабочего листа Excel.
Этот метод используется без параметров. Например, представленный ниже код удаляет активный лист рабочей книги:
MyExcel.ActiveWorkBook.ActiveWorkSheet.Delete
Метод Select
Выделение рабочего листа книги Excel.
Вызов метода:
expression.Select(Replace)
Параметр | Тип | Описание |
Replace | Variant | True, чтобы заменить текущее выделение указанного объекта. False — продлить нынешний отбор включая все ранее выбранные объекты. По умолчанию используется True |
Не стоит путать активный лист — тот который отображается в данный момент в книге и выделенный — выделить Вы можете хоть 10 листов (в Excel это делается с зажатым Ctrl), но активный — только один.
Как выделить листа рабочей книги Excel в Delphi?
MyExcel.ActiveWorkBook.WorkSheets.Item[3].Select
Выделяет третий лист книги
Метод Copy
Копирование листа в другое место в рабочей книге.
Вызов метода:
expression.Copy(Before, After)
Параметр | Тип | Описание |
Before | Variant | лист до которого будет вставлен копируемый лист. |
After | Variant | лист после которого будет вставлен копируемый лист |
При этом, если вы используете параметр Before, то вы не должны использовать After и наоборот. Обращу Ваше внимание, что указывается именно ЛИСТ, а не индекс листа.
Как копировать лист Excel в Delphi?
MyExcel.ActiveWorkBook.WorkSheets.Item[1].Copy(After:=MyExcel.ActiveWorkBook.WorkSheets.Item[2])
В этом случае первый лист будет скопирован и вставлен после третьего.
Метод Paste
Вставка содержимого буфера обмена на лист Excel.
Вызов метода:
expression.Paste(Destination, Link)
Параметр | Тип | Описание |
Destination | Variant | диапазон ячеек листа, который определяет, где будет вставлено содержимое буфера. Если этот аргумент опущен, используется текущий диапазон. Этот аргумент может быть указан только, если содержимое буфера обмена можно вставить в заданном диапазоне. Если этот параметр задан, то аргумент Link может не указываться |
Link | Variant | True, для того чтобы установить связь с источником вставляемых данных. Если этот параметр задан, Destination не может быть использован. Значение по умолчанию False |
Как вставить содержимое буфера обмена на лист Excel в Delphi?
MyExcel.ActiveWorkBook.ActiveSheet.Paste(Destination:=MyExcel.ActiveWorkBook.ActiveSheet.Range("D1:D5"))
В этом случае содержимое буфера будет вставлено в столбец D в строки с 1 по 5. Следует отметить, что если содержимое буфера не удовлетворяет условию, например в буфере только 1 число, то вызывается исключительная ситуация.
Метод ChartObjects
Возвращает объект, который представляет собой либо одну диаграмму (объект ChartObject) или совокупность всех диаграмм (объект ChartObjects) на листе.
Вызов метода:
expression.ChartObjects[Index]
Параметр | Тип | Описание |
index | Variant | индекс диаграммы в коллекции (нумерация начинается с 1) |
Как получить диаграмму на листе Excel в Delphi?
MyExcel.ActiveWorkBook.ActiveSheet.ChartObjects[1]
В этом случае будет получена первая диаграмма на листе.
Метод Move
Перемещение листа. Этот метод аналогичен методу Copy. Различие лишь в том, что после вcтавки копируемый лист удаляется из книги.
Вот та часть методов, которые я использовал когда-либо при работе с Excel в Delphi. Вообще можно сказать, что в Delphi можно управлять MS Excel не хуже, чем при непосредственной работе с этим приложением, главное не забывать, какой метод или свойство за что отвечает :). Ну, а для того, чтобы не забыть, я создал небольшой MindMap, который буду периодически дополнять и обновлять. Перейдя по ссылке, Вы сможете посмотреть объекты Excel, методы ими используемые, параметры методов и их типы в соответствии с типами Delphi. В общем небольшая графическая шпаргалка для любителей поразбираться с Excel в Delphi.
Книжная полка
Название:Разработка приложений Microsoft Office 2007 в Delphi Описание Описаны общие подходы к программированию приложений MS Office. Даны программные методы реализации функций MS Excel, MS Word, MS Access и MS Outlook в среде Delphi. |
0
0
голоса
Рейтинг статьи
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Подготовка
Откроем нашу среду разработки 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.
Работа с EXCEL из Delphi
В этой статье я познакомлю вас как работать с MS Excel из Delphi
. Данная статья может быть полезна людям, которые хотят научиться создавать различные отчеты в Excel
из программ написанных на Delphi
. Статья содержит справочные данные необходимые для работы с MS Excel
. Здесь вы найдете информацию о том как:
Подключить и правильно отключить интерфейс Excel;
— Как изменить размер, цвет и тип шрифта;
— Как выделить, объединить, заполнить и размножить диапазон ячеек;
— Как повернуть и отцентрировать текст;
— Как нарисовать границы ячеек;
— Как ввести формулу в ячейку и многое другое…
И так, начнем…
Работать будем через модуль ComObj,
для этого в uses
необходимо добавить модуль ComObj
и модуль Excel_TLB
(для MS Excel 2007
).
Uses ……, ComObj, Excel_TLB;
Модуль Excel_TLB
содержит необходимые константы
для работы с Excel
, его можно не подключать, но тогда придется в ручную прописывать значения всех используемых констант из этого модуля. Значения констант можно найти внутри модуля или в интернете, но для разных версий MS Excel
они разные.
Внимание!!!
Модуль Excel_TLB
в других версиях MS Excel
может называться по другому. Перед подключением модуля Excel_TLB,
необходимо импортировать библиотеку Excel
. Для этого выберите Component->Import Component->Import a Type Library->
находим MS Excel
и следуем инструкциям.
В разделе описания переменных мы должны описать переменную типа Variant
или OleVariant
для подключения интерфейса Excel.
Я описал переменную excel
.
Form1: TForm1;
excel
: variant;
// Переменная в которой создаётся объект EXCEL
Создание документа
Внимание!!!
Всегда когда создаете объект интерфейса, заключайте процедуру создания в модуль обработки ошибок:
try
создаем интерфейс;
формируем отчет;
освобождаем интерфейс;
Except
обрабатываем ошибки;
освобождаем интерфейс;
end;
try
// создаем обьект EXCEL
// Чтоб не задавал вопрос о сохранении документа
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.WorkSheets.Name:= «Отчет1»;
excel.WorkBooks.WorkSheets.Name:= «Отчет2»;
//задаем формат числа для первой и четвертой колонки формат числа
excel.WorkBooks.WorkSheets.Columns.NumberFormat:= «0,00»;
excel.WorkBooks.WorkSheets.Columns.NumberFormat:= «0,0»;
// задаем ширину первой и второй колонки
excel.WorkBooks.WorkSheets.Columns.ColumnWidth:= 10;
excel.WorkBooks.WorkSheets.Columns.ColumnWidth:= 20;
// задаем начертание, цвет, размер и тип шрифта для первого ряда
excel.WorkBooks.WorkSheets.Rows.Font.Bold:= True; //жирный
excel.WorkBooks.WorkSheets.Rows.Font.Color:= clRed; // цвет красный
excel.WorkBooks.WorkSheets.Rows.Font.Size:= 12; //размер 12
excel.WorkBooks.WorkSheets.Rows.Font.Name:= «Times New Roman»; //шрифт
//присваиваем ячейке 1,4 и 2,4 значения (1 — ряд, 4 — колонка)
excel.WorkBooks.WorkSheets.Cells := «А так можно внести значение в ячейку»;
excel.WorkBooks.WorkSheets.Cells := «А так можно внести значение в ячейку»;
//ввод в ячейку «A12» формулы «=b5+c4»
excel.WorkBooks.WorkSheets.Range[«A12″].Formula:=»=b5+c4»;
// Выравнивам первый ряд по центру по вертикали
excel.WorkBooks.WorkSheets.Rows.VerticalAlignment:= xlCenter;
// Выравнивам первый ряд по центру по горизонтали
excel.WorkBooks.WorkSheets.Rows.HorizontalAlignment:= xlCenter;
// Выравнивам в ячейке по левому краю
excel.WorkBooks.WorkSheets.Cells.HorizontalAlignment:= xlLeft;
// Выравнивам в ячейке по правому краю
excel.WorkBooks.WorkSheets.Cells.HorizontalAlignment:= xlRight;
// Обьединяем ячейки «A1:A8»
excel.WorkBooks.WorkSheets.Range[«A1:A8»].Merge;
// Поворачиваем слова под углом 90 градусов для второго ряда
excel.WorkBooks.WorkSheets.Rows.Orientation:= 90;
// Поворачиваем слова под углом 45 градусов для диапазона ячеек «B3:D3»
excel.WorkBooks.WorkSheets.Range[«B3:D3»].Orientation:= 45;
//рисуем границы выделенного диапазона левая
excel.Selection.Borders.LineStyle:= xlContinuous; // стиль линии сплошная
excel.Selection.Borders.Weight:= xlMedium;// толщина линии
//рисуем границы выделенного диапазона верхняя
excel.Selection.Borders.Weight:= xlMedium;
//рисуем границы выделенного диапазона нижняя
excel.Selection.Borders.Weight:= xlMedium;
//рисуем границы выделенного диапазона правая
excel.Selection.Borders.Weight:= xlMedium;
//рисуем границы выделенного диапазона вертикальные внутрениие
excel.Selection.Borders.Weight:= xlMedium;
//рисуем границы выделенного диапазона горизонтальные внутрениие
excel.Selection.Borders.Weight:= xlMedium;
//автозаполнение выделенного диапазона
//для примера заполним область ячеек «A10:C10» словом «привет»
//и размножим его вниз еще на пять ячеек «A10:C15»
excel.WorkBooks.WorkSheets.Range[«A10:C10″].Value:=»привет»;
//выделяем диапазон ячеек «A10:C10»
excel.WorkBooks.WorkSheets.Range[«A10:C10»].Select;
//автозаполняем (копируем) выделенным диапазоном область ячеек «A10:C15»
excel.selection.autofill(excel.WorkBooks.WorkSheets.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;
//обрабатываем ошибки
//закроем все книги
excel.Workbooks.Close;
//закрываем Excel
excel.Application.quit;
//освобождаем интерфейсы
excel:= Unassigned;
end;
end;
При работе с листом Excel
мы можем использовать следующие варианты:
— работать с областью Range[«B3:D3»];
— работать с ячейкой Cells где 2 — ряд, 4 — колонка;
— работать с рядами Rows или с диапазоном рядов Rows[«1:5»];
— работать с колонками Columns или диапазоном колонок Columns[«A:I»];
Range[«A1»] и Cells обозначают одно и тоже.
После сформирования документа или возникновении ошибки вы должны правильно освободить интерфейсы.
Иначе при закрытии Excel
он скрывается с экрана, но если открыть диспетчер задач он продолжает там висеть и если данный процесс не завершить, то при каждом новом запуске их будет накапливаться больше и больше, пока компьютер не начнет виснуть. Поэтому обязательно необходимо освобождать все интерфейсы с вязанные с Excel
с его книгами и листами.
Например так:
//закроем все книги
excel.Workbooks.Close;
//закрываем Excel
excel.Application.quit;
//освобождаем интерфейсы
sheet:=Unassigned; //интерфейс листа если он был создан
WorkBook:= Unassigned;//интерфейс рабочей книги если он был создан
excel:= Unassigned;//интерфейс самого предложения если он был создан
Ниже привожу пример вывода в
Excel из Delphi таблицы умножения с подробными комментариями.
Unit Unit1;
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
Procedure TForm1.Button1Click(Sender: TObject);
begin
try
// Обьект EXCEL
excel:= CreateOleObject(«Excel.Application»);
// Чтоб не задавал вопрос о сохранении документа
excel.DisplayAlerts:= false;
// новый документ
excel.WorkBooks.Add;
//объявляем вариантный массив
MyData:= VarArrayCreate(,varVariant);
for I:= 1 to 9 do
for J:= 1 to 9 do
MyData:=i*j;
// Обьединяем ячейки «A1:I1»
excel.WorkBooks.WorkSheets.Range[«A1:I1»].Merge;
//Пишем заголовок
excel.WorkBooks.WorkSheets.Range[«A1″].Value:=»Таблица умножения»;
// Выравнивам заголовок по центру
excel.WorkBooks.WorkSheets.Range[«A1»].HorizontalAlignment:= xlCenter;
// задаем ширину колонок с A по I
excel.WorkBooks.WorkSheets.Columns[«A:I»].ColumnWidth:= 3;
//выделяем область таблицы умножения [«A2:I10»] и рисуем границы
excel.WorkBooks.WorkSheets.Range[«A2:I10»].select;
//рисуем границы выделенного диапазона левая
excel.Selection.Borders.LineStyle:= xlContinuous; // стиль линии сплошная
excel.Selection.Borders.Weight:= xlThin;// толщина линии
//рисуем границы выделенного диапазона верхняя
excel.Selection.Borders.LineStyle:= xlContinuous;
excel.Selection.Borders.Weight:= xlThin;
//рисуем границы выделенного диапазона нижняя
excel.Selection.Borders.LineStyle:= xlContinuous;
excel.Selection.Borders.Weight:= xlThin;
//рисуем границы выделенного диапазона правая
excel.Selection.Borders.LineStyle:= xlContinuous;
excel.Selection.Borders.Weight:= xlThin;
//рисуем границы выделенного диапазона вертикальные внутрениие
excel.Selection.Borders.LineStyle:= xlContinuous;
excel.Selection.Borders.Weight:= xlThin;
//рисуем границы выделенного диапазона горизонтальные внутрениие
excel.Selection.Borders.LineStyle:= xlContinuous;
excel.Selection.Borders.Weight:= xlThin;
//присваиваем диапазону [«A2:I10»] значения вариантного массива MyData это значительно ускоряет работу, нежели вывод по //ячеечно
Excel.WorkBooks.WorkSheets.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;
При написании статьи использовался материал с сайта
В этой статье мы рассмотрим основные конструкции, позволяющие получить доступ к книге MS Excel из Delphi.
Организация доступа к книге EXCEL
Для взаимодействия с MS Excel в программе необходимо использовать модуль ComObj
Uses ComObj;
и объявить переменную для доступа к MS Excel следующего типа:
Var MsExcel: Variant;
Инициализация переменной Excel в простейшем случае можно осуществить так:
MsExcel:= CreateOleObject(«Excel.Application»);
Создание новой книги:
MsExcel.Workbooks.Add;
Открытие существующей книги (где path — путь к фалу с расширением xls.):
MsExcel.Workbooks.Open;
Открытие существующей книги только для чтения:
MsExcel.Workbooks.Open;
Закрытие Excel:
MsExcel.ActiveWorkbook.Close;
MsExcel.Application.Quit;
Блокировка запросов (подтверждений, уведомлений) Ms Excel, например, запретить запрос на сохранение файла:
MsExcel.DisplayAlerts:=False;
Отображаем Excel на экране:
MsExcel.Visible:= True;
или скрываем:
MsExcel.Visible:= False;
Печать содержимого активного листа MS Excel:
MsExcel.ActiveSheet.PrintOut;
Чтение/запись данных в EXCEL
Доступ к ячейке в текущей книге Excel можно осуществить следующим образом:
Для записи значения в ячейку:
MsExcel.Range[«B2″]:=»Привет!»;
Для чтения значения из ячейки:
S:=MsExcel.Range[«B2»];
где B2
— адрес ячейки.
Или используя стиль ссылок R1C1:
MsExcel.Range]:=»Привет!»;
где
— координата ячейки.
Вообще, ячейке Excel можно присваивать любое значение (символьное, целое, дробное, дата) при этом Ms Excel установит форматирование в ячейке применяемое по умолчанию.
Формат ячеек в EXCEL
Выделить (выбрать) группу ячеек для последующей работы можно так:
MsExcel.Range, MsExcel.Cells].Select;
// или
MsExcel.Range[«A1:C5»].Select;
при этом будет выделена область находящаяся между ячейкой A1 и C5.
После выполнения выделения можно установить объединение ячеек, перенос по словам, а также горизонтальное и вертикальное выравнивание:
// объединение ячеек
MsExcel.Selection.MergeCells:=True;
// перенос по словам
MsExcel.Selection.WrapText:=True;
// горизонтальное выравнивание
MsExcel.Selection.HorizontalAlignment:=3;
// вертикальное выравнивание
MsExcel.Selection.VerticalAlignment:=1;
Для вертикального и горизонтального выравнивания используются следующие значения:
1 — используется выравнивание по умолчанию
2 — выравнивание слева
3 — по центру
4 — справа.
Граница ячеек
При значении 1 границы ячеек рисуются тонкими сплошными линиями.
Кроме этого можно указать значения для свойства Borders, например, равное 3. Тогда установится только верхняя граница для блока выделения:
MsExcel.Selection.Borders.LineStyle:=1;
Значение свойства Borders задает различную комбинацию граней ячеек. В обоих случаях можно использовать значения в диапазоне от 1 до 10.
Использование паролей в EXCEL
Установка пароля для активной книги может быть произведена следующим образом:
Try
// попытка установить пароль
MsExcel.ActiveWorkbook.protect(«pass»);
except
// действия при неудачной попытке установить пароль
end;
где pass
— устанавливаемый пароль на книгу.
Снятие пароля с книги аналогично, используем команду
MsExcel.ActiveWorkbook.Unprotect(«pass»);
где pass
Установка и снятие пароля для активного листа книги Excel производится командами
MsExcel.ActiveSheet.protect(«pass»); // установка пароля
MsExcel.ActiveSheet.Unprotect(«pass»); // снятие пароля
где pass
— пароль, установленный для защиты книги.
Вспомогательные операции в EXCEL
Удаление строк со сдвигом вверх:
MsExcel.Rows[«5:15»].Select;
MsExcel.Selection.;
при выполнении данных действий будут удалены строки с 5 по 15.
Установка закрепления области на активном листе Excel
// снимаем закрепление области, если оно было задано
MsExcel.ActiveWindow.FreezePanes:=False;
// выделяем нужную ячейку, в данном случае D3
MsExcel.Range[«D3»].Select;
// устанавливаем закрепление области
MsExcel.ActiveWindow.FreezePanes:=True;
Сохранение активной книги Excel
На каждой из ступеней этой модели можно останавливаться и изучать её месяцами. Если будет особая необходимость в изучении каких-либо дополнительных свойств и методов — мы обязательно вернемся и изучим. А теперь, приступим к работе в Delphi с листами рабочей книги.
2. Как активировать лист рабочей книги Excel?
Как Вы знаете при создании пустой рабочей книги Excel
автоматически добавляет в эту книгу 3 пустых листа. Чтобы работать с конкретным листом (WorkSheet
или просто Sheet
) этот лист необходимо активировать. Один из способов активации листа рабочей книги Excel
в Delphi
выглядит следующим образом:
resourcestring
rsEInvalidSheetIndex =
«Задан неверный индекс для WorkBooks. Активация листа прервана»
;
rsEInvalidSheetActivate =
«Активация листа завершена с ошибкой»
;
function
ActivateSheet(WBIndex:
integer
;
SheetName:
string
)
:
boolean
;
var
i:
integer
;
begin
Result :
=
false
;
if
WBIndex >
MyExcel.
WorkBooks
.
Count
then
raise
Exception.
Create
(rsEInvalidSheetIndex)
;
try
for
i :
=
1
to
MyExcel.
WorkBooks
[
WBIndex]
.
Sheets
.
Count
do
if
AnsiLowerCase
(MyExcel.
WorkBooks
[
WBIndex]
.
Sheets
.
Item
[
i]
.
Name
)
=
AnsiLowerCase
(SheetName)
then
begin
MyExcel.
WorkBooks
[
WBIndex]
.
Sheets
.
Item
[
i]
.
Activate
;
Result :
=
true
;
break;
end
;
except
raise
Exception.
Create
(rsEInvalidSheetActivate)
;
end
;
end
;
Здесь в качестве параметров функции задается индекс рабочей книги (WBIndex) в коллекции WorkBooks
и название листа.
Если хотите, то можете активировать тот же лист по индексу в коллекции WorkSheets
— при этом сама функция немного упрощается (не требуется условие проверки названия листа).
Также, если вы уверены, что в данный момент времени активна необходимая Вам рабочая книга, то можно избежать использования лишней переменной (индекса рабочей книги WBIndex) и активировать лист вот так:
MyExcel.
ActiveWorkBook
.
Sheets
.
Item
[
i]
.
Activate
;
Теперь рассмотрим более подробно методы, используемые объектом WorkSheet
.
3. Методы листа книги Excel
Теперь рассмотрим более подробно объект WorkSheet
.
На рисунке представлены те методы, которые я когда-либо использовал в своей работе.
Всего объект WorkSheet
насчитывает 30
различных методов, которые Вы можете использовать.
Метод |
Описание |
Activate
|
Делает текущий лист активным. Работу метода мы уже с Вами рассмотрели |
рассчитывает все открытые книги, конкретный лист в книге, или указанный диапазон ячеек на листе | |
проверка орфографии на выбранном листе | |
сохраняет все изменения в файле | |
удаляет текущий лист WorkSheet |
|
выделение листа | |
копирует лист в другое место в рабочей книге | |
вставляет содержимое буфера обмена на лист | |
возвращает объект, который представляет собой либо одну диаграмму (объект ChartObject ChartObjects ) на листе |
|
перемещение листа. Этот метод аналогичен методу Copy . Различие лишь в том, что после вcтавки копируемый лист удаляется из книги |
Рассмотрим теперь каждый из представленных выше методов.
Ниже, в качестве expression
должен выступать лист (WorkSheet
), если не сказано иное.
Метод Calculate
Расчёт рабочей книги, листа или диапазона ячеек.
Стоит отметить, что вызов метода Calculate
возможен не только для конкретного рабочего листа книги Excel. Рассмотрим варианты вызова метода Calculate.
var
MyExcel:
OleVariant;
MyExcel.
Calculate
в приведенном ниже фрагменте кода рассчитывается активный лист
MyExcel.
ActiveWorkBook
.
ActiveWorkSheet
.
Calculate
Рассчитаем все формулы в столбцах A, B и C:
MyExcel.
ActiveWorkBook
.
ActiveWorkSheet
.
UsedRange
.
Columns
(«A:
C»)
.
Calculate
Метод CheckSpelling
Вызов метода выглядит следующим образом:
expression
.
CheckSpelling(CustomDictionary, IgnoreUppercase, AlwaysSuggest, SpellLang)
При этом в качестве expression
должен выступать лист (WorkSheet
).
Параметр |
Тип |
Описание |
CustomDictionary |
Variant |
с трока, указывающая имя файла пользовательского словаря, который будет рассмотрен, если слово не найдено в основном словаре. Если этот аргумент опущен, то будет использоваться словарь по-умолчанию |
IgnoreUppercase |
Variant |
True , если необходимо, чтобы Microsoft Excel пропускал слова, которые написаны прописными буквами. False для того, чтобы Microsoft Excel проверить все слова. Если этот аргумент опущен, то используются текущие настройки Excel. |
AlwaysSuggest |
Variant |
True , для того, чтобы Microsoft Excel отображал список предложений других вариантов написания при обнаружении неправильного написанного слова. False , чтобы Microsoft Excel ожидал ввода правильного написание. Если этот аргумент опущен, то используются текущие настройки. |
SpellLang |
Variant |
язык словаря. Может принимать значения одной из констант MsoLanguageID , например для русского языка SpellLang = 1049 , для английского (США) SpellLang = 1033 и т.д. Более подробно про идентификаторы языков . |
Как проверить грамматику на листе Excel в Delphi?
MyExcel.
ActiveWorkBook
.
ActiveWorkSheet
.
CheckSpelling
(CustomDictionary:
=
EmptyParam,
IgnoreUppercase:
=
false
,
AlwaysSuggest:
=
EmptyParam,
SpellLang:
=
1033
)
в этом случае MS Excel
проверит текущий лист, включая проверку слов из прописных букв. Язык проверки — русский. Обратите внимание, что для того, чтобы вызвать метод мы явно указывали, какому параметру какое значение присвоить. Причём для того, чтобы пропустить какой-либо параметр, мы использовали EmptyParam
(пустой параметр), который в Delphi
представляет собой переменную типа OleVariant
.
Понятно, что подобный способ вызова методов (с явным указанием всех параметров) для Вас не совсем удобен и широко не практикуется в программировании на Delphi
, но тем не менее только так и никак иначе можно вызывать методы, используемые в Excel
.
Метод SaveAs
Сохранение рабочего листа книги Excel.
Вызов метода:
expression.SaveAs(FileName, FileFormat, Password, WriteResPassword, ReadOnlyRecommended, CreateBackup, AddToMru,TextCodepage, TextVisualLayout, Local)
Параметр |
Тип |
Описание |
FileName |
Variant |
строка, представляющая собой имя сохраняемого файла. Необходимо указывать полный путь к файлу, иначе файл будет сохранен в папку Excel . |
FileFormat |
Variant |
формат файла, который используется при сохранении. По умолчанию файл сохраняется в формате, который вы выбирали в последний раз в Excel. |
Password |
Variant |
пароль для файла (не более 15 символов). Пароль чувствителен к регистру. |
WriteResPassword |
Variant |
пароль, который будет использоваться для внесения изменений в рабочую книгу. Если пароль не будет указан, то книга будет открыта в режиме “Только для чтения” |
ReadOnlyRecommended |
Variant |
если параметр равен True , то при открытии файла на дисплее появится сообщение, в котором рекомендуется, что бы файл был открыт только для чтения. |
CreateBackup |
Variant |
True , для того, чтобы создать резервный файл |
AddToMru |
Variant |
True , для того, чтобы добавить имя сохраняемого файла в список недавно открытых файлов в главном меню Excel |
TextCodepage и TextVisualLayout |
Variant |
в настоящее время не используются и сохранены для обеспечения обратной совместимости |
Local |
Variant |
не обязательный параметр, по-умолчанию равен False. Значение True — сохранение файлов с языковыми Microsoft Excel (в том числе настройки панели управления). |
MyExcel.ActiveWorkBook.ActiveWorkSheet.SaveAs(«C:MyExcelFile.xls»)
В этом случае при сохранении будут использованы настройки по умолчанию.
Если Вам необходимо сохранить файл Excel в другом формате, то в параметре FileFormat
можно использовать одно из значений перечислителя xlFileFormat
. Некоторые значения xlFileFormat
представлены в таблице ниже:
Имя |
Значение |
Описание |
Расширение файла |
xlCSV | 6 | CSV | *.csv |
xlExcel8 | 56 | Книга Excel 97-2003 | *.xls |
xlHtml | 44 | Формат HTML | *.htm; *.HTML |
xlOpenDocumentSpreadsheet | 60 | Электронная таблица OpenDocument | *.ods |
xlOpenXMLWorkbook | 51 | Книга Open XML | *.xlsx |
Напишем небольшую процедуру, позволяющую сохранять лист Excel в различных форматах:
const
xlCSV =
6
;
xlExcel8 =
56
;
xlHtml =
44
;
xlOpenDocumentSpreadsheet =
60
;
xlOpenXMLWorkbook =
51
;
resourcestring
rsESaveActiveSheet =
«Ошибка сохранения активного листа книги»
;
procedure
SaveAs(const
AFileName:
TFileName;
AFileFormat:
integer
)
;
begin
try
MyExcel.
ActiveWorkBook
.
ActiveSheet
.
SaveAs
(AFileName,
AFileFormat)
;
except
raise
Exception.
Create
(rsESaveActiveSheet)
;
end
;
end
;
Метод Delete
Удаление рабочего листа Excel.
MyExcel.ActiveWorkBook.WorkSheets.Item.Select
Выделяет третий лист книги
Метод Copy
Копирование листа в другое место в рабочей книге.
Вызов метода:
expression.Copy(Before, After)
При этом, если вы используете параметр Before
, то вы не должны использовать After
и наоборот. Обращу Ваше внимание, что указывается именно ЛИСТ, а не индекс листа.
Как копировать лист Excel в Delphi?
MyExcel.ActiveWorkBook.WorkSheets.Item.Copy(After:=MyExcel.ActiveWorkBook.WorkSheets.Item)
В этом случае первый лист будет скопирован и вставлен после третьего.
Метод Paste
Вставка содержимого буфера обмена на лист Excel.
Вызов метода:
expression.Paste(Destination, Link)
Как вставить содержимое буфера обмена на лист Excel в Delphi?
MyExcel.ActiveWorkBook.ActiveSheet.Paste(Destination:=MyExcel.ActiveWorkBook.ActiveSheet.Range(«D1:D5»))
В этом случае содержимое буфера будет вставлено в столбец D в строки с 1 по 5. Следует отметить, что если содержимое буфера не удовлетворяет условию, например в буфере только 1 число, то вызывается исключительная ситуация.
Метод ChartObjects
Возвращает объект, который представляет собой либо одну диаграмму (объект ChartObject
) или совокупность всех диаграмм (объект ChartObjects
) на листе.
Вызов метода:
expression.ChartObjects
Как получить диаграмму на листе Excel в Delphi?
MyExcel.ActiveWorkBook.ActiveSheet.ChartObjects
В этом случае будет получена первая .
Метод Move
Перемещение листа. Этот метод аналогичен методу . Различие лишь в том, что после вcтавки копируемый лист удаляется из книги.
Вот та часть методов, которые я использовал когда-либо при работе с Excel
в Delphi
. Вообще можно сказать, что в Delphi
можно управлять MS Excel
не хуже, чем при непосредственной работе с этим приложением, главное не забывать, какой метод или свойство за что отвечает:). Ну, а для того, чтобы не забыть, я создал небольшой MindMap , который буду периодически дополнять и обновлять. Перейдя по ссылке, Вы сможете посмотреть объекты Excel, методы ими используемые, параметры методов и их типы в соответствии с типами Delphi. В общем небольшая графическая шпаргалка для любителей поразбираться с Excel в Delphi.
Обмен данными с 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
у пользователя:
Function IsXlsInstall: boolean;
var
CLSID: TCLSID;
begin
Result:= (CLSIDFromProgID(«Excel.Application», CLSID) = S_OK);
end;
Если Excel
установлен, тогда выполним подключение к нему. Сделать это можно двумя способами: GetActiveOleObject
— Получить ссылку на уже запущенный экземпляр Excel
или CreateOleObject
— Создать новый экземпляр Excel
.
Если у нас стоит задача получать данные из запущенного Excel
, тогда мы должны использовать только первый вариант, в остальных случаях пробуем подключиться и если не получается, то создаем.
Напишем 2 функции, для подключения XlsConnect
и запуска нового XlsStart
:
Добавим переменную FXlsApp
с типом Variant
, которая будет содержать в себе ссылку на объект Excel
.
Private
FXlsApp: variant;
***
function XlsConnect: boolean;
begin
Result:= False;
try
FXlsApp:= GetActiveOleObject(«Excel.Application»);
Result:= True;
except
end;
end;
procedure XlsStart;
begin
FXlsApp:= CreateOleObject(«Excel.Application»);
end;
Теперь можно добавить кнопку, на клик которой подключимся к MS Excel
используя написанные функции:
Procedure btnConnectClick(Sender: TObject);
begin
if not IsXlsInstall then
raise Exception.Create(«Приложение MS Excel не найдено на данном компьютере!»);
if not XlsConnect then
XlsStart;
FXlsApp.Visible:= True;
end;
По умолчанию окно Excel
запускается в фоновом режиме. Строка FXlsApp.Visible:= True;
делает фоновое окно Excel
видимым.
Окно Excel
запускается пустое и в него нужно добавить рабочую книгу. Делается это при помощи метода WorkBooks.Add
, который добавляет новую книгу или открывает ранее сохраненную, если указать путь к файлу.
Добавим процедуру, которая будет это делать:
Procedure XWorkbookAdd(const FilePath: string = «»);
begin
FXlsApp.WorkBooks.Add(FilePath);
end;
Книга добавлена, теперь попробуем записать что-нибудь в неё.
FXlsApp.Cells := «Тестовая строка»;
Где Row
— индекс строки, и Col
— индекс столбца, которые начинаются с единицы.
FXlsApp.Range[«A1»] := «Ячейка А1»;
Где Range
— массив ячеек, а А1
— привычные для Excel
координаты ячейки.
В качестве координат может быть указан диапазон. Например, код
FXlsApp.Range[«A3:A10»] := 5;
заполнит цифрой 5 все ячейки с А3
по А10
, а код
FXlsApp.Range[«A3:A10»].Interior.Color:= clMoneyGreen;
выделит тот же диапазон светло-зеленым цветом.
В обратную сторону, то есть для получения данных из Excel
, работает так же. Строка
ShowMessage(FXlsApp.Cells);
Выведет сообщение с содержимым ячейки с координатами: Строка=5, Столбец=1.
После того, как мы произвели необходимые нам манипуляции с Excel
, мы можем сохранить полученную книгу в файл следующей командой:
FXlsApp.ActiveWorkbook.SaveAs(«C:Test.xlsx»);
Где ActiveWorkbook
— текущая книга.
И закрыть приложение Excel
командой:
FXlsApp.Quit;
Как понимаете этим возможности управления Excel
из Delphi
не ограничиваются. И есть один достаточной простой способ узнать, как выполнить необходимо действие с Excel
из Delphi
.
Называется оно — Макросы.
Представим, что нам необходимо выполнить объединение нескольких ячеек в одну и мы не знаем как это сделать. Но хотим узнать. Для этого выполняем следующие шаги:
1. Запускаем Excel
и создаем пустую книгу.
2. Запускаем команду «Записать макрос», по умолчанию название макроса будет «Макрос1». (В разных версиях Excel
данная команда находится в разных пунктах меню).
3. Выделяем некоторый диапазон ячеек и нажимаем кнопку «Объединить и поместить в центре».
4. Останавливаем запись макроса.
5. Вызываем список макросов и выбираем там свой записанный макрос.
6. Нажимаем кнопку «Изменить»
Запускается редактор Microsoft Visual Basic for Application
в котором видим код проделанных действий:
Sub Макрос1()
»
» Макрос1 Макрос
»
With Selection
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlBottom
.WrapText = False
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
End With
Selection.Merge
End Sub
Давайте разберем по подробнее, что же такого он нам тут написал:
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:
Выделяем нужный нам диапазон.
FXlsApp.Selection.MergeCells:= True;
Объединяем ячейки задав свойство. Или при помощи метода:
FXlsApp.Selection.Merge;
Таким способом можно получать код практически для любых необходимых манипуляций.
А если какое-то свойство или метод вызывает вопросы, то можно воспользоваться справкой на MSDN.
Обратите внимание на особенность работы с массивами в VBA
. Индексы в массивах в Delphi
оборачиваются в квадратные скобки, в то время как в VBA
они будут в круглых. И код в Delphi
FXlsApp.Range[«B5:C8»].Select;
в VBA
будет выглядеть как
Range(«D5:H14»).Select;
Ниже приведу небольшой FAQ
по вопросу взаимодействия с Excel
из Delphi
Как определить значения констант в Excel для использования в Delphi?
В редакторе VBA
ставим точку остановки напротив интересующей константы. Нажимаем выполнить и когда выполнение остановиться, наводим на интересующую константу:
Как отключить выводы сообщений в Excel?
FXlsApp.DisplayAlerts:= False;
Как получить список книг из Excel?
For i:= 1 to FXlsApp.Workbooks.Count do
ListBox1.Items.Add(FXlsApp.Workbooks.Item[i].Name);
Как отключить отображение сетки?
FXlsApp.ActiveWindow.DisplayGridlines:= False;
Как вывести текущий лист на предпросмотр печати?
FXlsApp.ActiveWindow.SelectedSheets.PrintPreview;
Как выделить жирным часть текста в ячейки?
Var
Row: integer; // Индекс строки
Col: integer; // Индекс ячейки
TextSelStart: integer; // Начиная с символа
TextSelLength: integer; // Кол-во выделенных символов
begin
FXlsApp.Cells.Characters(TextSelStart, TextSelLength).Font.Bold:= True;
end;
Как выполнить автоподбор высоты строки для склеенной ячейки?
Var
merge_area: variant;
cell_width,
cells_width,
i: integer
begin
// Сохраняем диапазон склеенных ячеек в переменную
merge_area:= FXlsApp.Range[«D5»].MergeArea;
// Сохраняем ширину ячейки, для которой будем подбирать высоту
cell_width:= FXlsApp.Range[«D5»].ColumnWidth;
cells_width:= 0;
for i:= 1 to merge_area.Columns.Count do
// Получаем общую ширину всех столбцов склеенного диапазона
cells_width:= cells_width + merge_area.Columns[i].ColumnWidth;
// Разъединяем ячейки
merge_area.UnMerge;
// Устанавливаем ширину интересуемой ячейки равной общей ширине
FXlsApp.Range[«D5»].ColumnWidth:= cells_width;
// Вызываем стандартный метод автоподбора высоты строки
FXlsApp.Rows.EntireRow.AutoFit;
// Возвращаем исходную ширину интересуемой ячейки
FXlsApp.Range[«D5»].ColumnWidth:= cell_width;
// Склеиваем обратно диапазон
merge_area.Merge;
end;
Как получить используемый диапазон ячеек?
Result:= exApp.ActiveSheet.UsedRange;
Как получить букву столбца по индексу?
Uses Math;
***
function ColIdxToStr(const Col: integer): string
const
CharsCount: integer = 26;
Offset: integer = 64;
var
Rank: byte;
Col, Tmp: integer;
begin
Result:= «»;
while Col > 0 do begin
Rank:= 0;
Tmp:= Col;
while Tmp > CharsCount do begin
Tmp:= Ceil(Tmp / CharsCount — 1);
Inc(Rank);
end;
Result:= Result + Chr(Tmp + Offset);
Col:= Col — Trunc(Power(CharsCount,Rank)) * Tmp;
end;
end;
Очень многие документы создаются и хранятся в формате электронных таблиц 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
;
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:=Excel.WorkSheets.Item[«Лист1»].Cells;
Маленькое предупреждение: если при отладке проверять внесение данных, то перед нажатием нашей кнопки нужно завершить ввод в Excel — нажать Enter. Ведь если ячейка таблицы Excel останется в режиме редактирования, то мы получим отказ от Excel.
И ещё. Данные в Excel адресуются начиная с 1. Попытка получить содержимое фиксированных ячеек не удаётся. Поэтому фиксированные ячейки в таблице StringGrid при необходимости нужно заполнять самому, отдельно.
А получить содержимое одной ячейки можно как указав номер строки и столбца, так и непосредственно указав адрес ячейки:
var
S1, S2: String
;
begin
S1:=Excel.WorkSheets.Item[«Лист1»].Cells;
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:=Grid.Cells;
Если эти операции производятся с активным листом Excel, то можно сократить написание, и вместо:
Excel.WorkSheets.Item[«Лист1»].Cells
Excel.Cells
Или можно создать переменную и присвоить ей значение того листа Excel, с которым производится работа:
var
Sheet: Variant;
S1, S2: String;
begin
Sheet:=Excel.WorkSheets.Item[«Лист1»];
S1:=Sheet.Cells;
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
end;
В частности, регион может состоять и из одной ячейки:
Range:=Excel.Range, Excel.Cells];
Эту запись проще выполнить с указанием адреса как в таблице 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];
with
StringGrid1 do
for
i:=1 to
100 do
for
j:=1 to
100 do
Cells:=Range.Cells;
end;
Вот и всё! На моём компьютере, эта операция переписи региона 100х100 ячеек Excel в таблицу StringGrid длится около 300 мсек, что на 2 порядка быстрее, чем чтение и запись по одной ячейке.
А, например, операция занесения какого-либо одного значения во все ячейки региона выполняется ещё проще. Занесём в наш вышеопределённый регион 100х100 слово «Привет» :
Excel.Range, Excel.Cells]:=»Привет»;
Очистка региона выполняется методом Clear:
Excel.Range, Excel.Cells].Clear;
Часть 3. Использование COM-серверов Microsoft Office
Основные объекты серверов Excel и Word
Объекты Excel
Объекты Word
Позднее связывание
Раннее связывание
Практика
показывает, что приложения Microsoft
Office (Excel,
Word, Power
Point и т.п.)
являются одними из наиболее часто
используемых Windows-приложений.
Каждое из них является СОМ-сервером, а
следовательно, любой входящий в него объект
может быть использован вашей программой
как собственный.
Существуют два способа обращения к методам и свойствам СОМ-объекта: путем ссылки
на его библиотеку типов (раннее связывание) и по имени (позднее связывание).
Для Object Pascal предпочтительным является раннее связывание, так как в этом
случае компилятор может проконтролировать правильность обращения к свойствам
и методам внешних объектов, а создаваемый им код исполняется, как правило, быстрее.
В то же время базовый язык обращения к серверам Microsoft Office — Visual Basic
for Application (VBA) не поддерживает работу с указателями и, следовательно,
не может использовать интерфейсы. Специально для такого рода языков (помимо
VBA c указателями не работают также языки JavaScript, SmallTalk и некоторые
другие) в технологию СОМ введены диспинтерфейсы, позволяющие обращаться к методам
и свойствам по имени, а не по адресу. При инсталлировании Office можно установить
справку по VBA, в которой детально описываются интерфейсы серверов Microsoft
Office с указанием назначения методов и свойств, а также параметров обращения
к ним. Фактически это единственные доступные программисту документы, на которые
ему следует опираться при программировании доступа к мощным возможностям серверов
Microsoft Office. Замечу, что при стандартном инсталлировании Microsoft Office
справки по VBA не устанавливаются. Если в каталоге Program Files | Microsoft
Office | Office вы не найдете файлов vbaxl8.hlp1
(справка по Excel), vbawrd8.hlp (справка по Word) и т. п., вы должны их
добавить с помощью аплета Пуск | Настройка | Панель управления | Установка и
удаление программ.
В версию 5 Delphi включены компоненты страницы Servers,
позволяющие обращаться к СОМ-объектам этих
серверов с помощью библиотек типов, однако
эти компоненты практически не
документированы. Более того, сами
библиотеки уже внедрены в пакет dclaxserver50,
так что с помощью этой версии Delphi
мне так и не удалось получить их тексты. Во
всех случаях изучение обширных текстов
библиотек (например, файл Excel_TLB.pas
содержит более 20 тыс. строк) мало что дает
даже опытному программисту.
В этом разделе приводятся краткое
описание основных объектов двух наиболее
популярных серверов — Excel
и Word, а
также примеры использования Excel
в стиле VBA
(по имени) и с помощью компонентов страницы Servers.
Поскольку специально для версии MS
Office 97
язык VBA
был существенно расширен, этот материал
нельзя использовать для работы с более
ранними версиями пакета.
Основные объекты серверов Excel и Word
В терминологии VBA
используются
понятия «объект» и «коллекция». Объект —
это обычный интерфейсный объект СОМ,
имеющий свойства, методы и события.
Коллекция — это группа однотипных объектов.
Например, главный объект сервера Excel
— Application
определяет основные свойства и методы
сервера, а коллекция Worksheets
представляет собой
набор табличных страниц в текущей рабочей
книге и т.д. Представленные ниже иерархии
объектов и коллекций взяты из файлов vbaXXX.hlp. В отличие от объектов VCL
они построены не по принципу наследования,
а по функциональной подчиненности.
Объекты Excel
Сервер Excel — это мощный табличный процессор,
реализующий размещение и обработку
различного рода данных (как числовых, так и
текстовых), в том числе построение
на их основе графиков и диаграмм. При работе
с Excel создается
так называемая рабочая книга (файл данных) с
одним или несколькими листами. Все листы
одной рабочей книги могут быть связаны друг
с другом, что позволяет организовать
совместные вычисления над размещенными на
них данными.
На рис. 1 представлена функциональная структура объектов
и коллекций Excel.
Объект Application имеет многочисленные свойства,
методы и события, управляющие сервером в
целом. Только с его помощью, например, можно
визуализировать полнофункциональное окно
текстового процессора. Его центральное
свойство Workbooks предоставляет доступ ко всем
открытым в процессоре рабочим книгам.
У каждой рабочей книги есть
свойства Worksheets
и Charts,
представляющие собой коллекции листов и
диаграмм. Первоначально коллекция Workbooks
пуста. Чтобы создать хотя бы одну рабочую
книгу, нужно обратиться к методу Workbook.Add,
который создает рабочую книгу с
количеством пустых листов, определяемым
значением свойства Application.SheetsInNewWorkbook. У
каждого рабочего листа есть свойство Cells(I,J), определяющее содержимое
ячейки, лежащей на пересечении I-го
ряда с J-м
столбцом (нумерация рядов и столбцов
начинается с 1). Если при обращении к Cells
номера столбца и ряда опущены, считается,
что речь идет о текущем диапазоне ячеек,
заданном значением свойства Worksheets.Range.
Если необходимо изменить умалчиваемые
свойства столбца или ряда, используются
объекты Worksheets.Columns и
Worksheets.Rows. Помимо рабочих листов с рабочей книгой
связывается объект Charts,
представляющий собой коллекцию диаграмм. С
каждой диаграммой связывается объект SeriesCollection,
хранящий данные, по которым строится
диаграмма.
Объекты Word
Текстовый процессор Word
является популярнейшим средством создания
и оформления (форматирования) текстовых
документов. При работе с Word
фундаментальными понятиями являются
документ, абзац и стиль. Документ
определяет файл данных. Абзац — это
совокупность символов, обрамленная
служебными символами конца строк, разрыва
колонки или разрыва раздела. Наконец, стиль
— это совокупность признаков оформления
текста: его шрифт, положение на странице,
выравнивание и т.п. Стиль — непременный
атрибут каждого абзаца, то есть изменение
стиля абзаца автоматически приводит к его
переформатированию. Однако стиль может
изменяться внутри абзаца — для выделения
группы символов шрифтом, цветом символов и (или)
фона и т.п.
На рис. 2 показана функциональная иерархия объектов Word.
Центральный объект Application
имеет такое же назначение, что и
одноименный объект Excel,
– он определяет свойства, методы и события
на уровне всего сервера. Его свойство Documents представляет собой коллекцию открытых
документов. Посредством метода Open этого объекта можно открыть ранее
созданный документ, а метода Add — создать новый документ, основанный на
стандартном шаблоне Normal.dot. Каждый документ имеет коллекцию абзацев
Paragraphs.
С помощью таких методов этого объекта, как Add, InsertParagraph,
InsertParagraphAfter,
InsertParagraphBefore,
можно вставить новый абзац в уже
существующий текст или добавить абзац в
конец документа. В свою очередь, каждый
абзац имеет многочисленные свойства,
позволяющие нужным образом
отформатировать текст. Как и в Excel,
важную роль в иерархии объектов Word
играет объект Range, определяющий диапазон абзацев. Свойство
Text этого объекта содержит текст диапазона.
Позднее связывание
Приведенный ниже пример взят из моей
практики и, думаю, сможет пригодиться и вам.
В нем прайс-лист крупного оптового
поставщика книг создается с помощью Excel.
Необходимость в обращении к Excel возникла по той причине, что прайс-лист
периодически (примерно раз в две недели)
рассылается многочисленным покупателям,
которые составляют на его основе заказы на
поставку книг. У получателей прайс-листов
нет средств прочтения отчетов в
стандартном для Delphi
формате Quick Report
(файлы с расширением qrp). Экспорт прайс-листов в файлы других
форматов не позволяет получать документы
высокого качества, поэтому я решил для
создания прайс-листов использовать
средства Excel.
На рис. 3 показан прайс-лист в окне Excel, а на рис.
4 — вид формы примера на этапе конструирования.
Перед началом работы над проектом следует скопировать все файлы BOOKS.*
в отдельную папку на жестком диске (потребуется чуть больше 800 Кбайт
свободного пространства) и связать с папкой псевдоним BDE BIBLDATA типа Standard.
Эту процедуру упростит программа SetupBooks.exe, расположенная в том же каталоге
CD-ROM.
Начните новый проект и поместите на форму компоненты Query1, Label1, Button1 и ProgressBar1.
Для компонента Query1 измените значение свойства Name на Books, свяжите его
с псевдонимом BIBLDATA и поместите в свойство SQL такой запрос:
SELECT BookID, bName, bAuthor, bPublish, bOpt, bPages, bYear FROM Books WHERE bQuan>0 ORDER BY
bName
Создайте для него все объекты-поля.
В свойство Caption
компонента Label1
поместите значение Щелкните по кнопке Пуск,
чтобы создать таблицу Excel,
в такое же свойство кнопки — значение Пуск и измените имя компонента ProgressBar1 на pb.
В окне кода в разделе private класса TForm1 поместите поле Excel типа Variant.
В предложении uses укажите ссылку на модуль COMObj и напишите следующий обработчик
события OnClick кнопки Button1 (см. листинг 1).
Теперь небольшие пояснения. Переменные Sheet и Range
введены только для сокращения текста
программы: везде вместо Sheet,
например, можно писать Excel.Workbooks[1].Sheets[1]. С версией Delphi 4 поставлялись файлы XLCONST.PAS и XLCONST.DCU, в которых определены используемые в
документации vbaxl8.hlp константы xlXXX.
С версией 5 эти файлы не поставляются,
поэтому я использую их числовые
эквиваленты. Ширина полей печатного
документа Excel
задается во внутренних единицах,
соответствующих приблизительно 3,5 мм, так
что указанные в операторах Sheet.PageSetup.ХХХMargin значения установят левое, нижнее и
правое поля шириной 1,1 см, а верхнее — 1,4 см.
Ширина столбца определяется в символах
текста, умещающегося в столбце без
отсечения.
Переменная Excel
определяет поле класса TForm1. При создании класса в него
автоматически помещается значение VarEmpty. После завершения работы с Excel
пользователь может закрыть его. Но в моей
программе Excel не визуализировался, его работа
проходила «за кулисами», а созданная
таблица записывалась в указанный
пользователем файл с помощью оператора Excel.Workbooks[1].SaveAs(FileName).
После этого Excel закрывался. Поскольку в нашем случае Excel
показывает свое окно, а пользователь может
его не закрыть, полезно написать такой
обработчик события OnDestroy формы:
procedure TForm1.FormDestroy(Sender: TObject); begin if not VarIsEmpty(Excel) then Excel.Quit end;
Запуская пример, помните, что
создание прайс-листа с помощью Excel
— процесс достаточно длительный. На моем
компьютере (400 МГц, 64 Мбайт) он занял около
минуты (для примера — аналогичный прайс-лист
средствами Quick Report
создается менее чем за 2 с). В конце
обработчика в метку lb
помещается общее время работы.
Раннее связывание
Следующий пример в функциональном плане повторяет предыдущий. В нем также с помощью Excel
создается прайс-лист, но на этот раз используется доступ непосредственно через
интерфейсы сервера. Вас ожидает «сюрприз»: время выполнения второго примера
на 40 с больше! Я не смог найти разумного объяснения этому феномену, но оба
примера находятся на сопровождающем диске, так что вы в любой момент можете
убедиться в этом сами.
Поскольку форма второго примера в точности повторяет форму первого, я не буду
объяснять, что нужно сделать для ее создания. Добавьте только на форму компонент
TExcelApplication и настройте его свойства: Name=Excel, AutoConnect=True, AutoQuit=True.
Если вы используете форму предыдущего примера как шаблон, не вставляйте поле
Excel в класс TForm1. Обработчик Button1Click должен выглядеть так (см. листинг
2).
Как видите, он во многом напоминает
обработчик предыдущего примера. Поэтому
остановлюсь на различиях.
При обращении к свойству SheetsInNewWorkbook,
как и во многих других случаях обращения к
интерфейсным свойствам и методам,
требуется указание идентификатора языка
локализации (lcid).
Значением 0 кодируется умалчиваемый язык.
Этот же идентификатор передается вторым
параметром обращения к методу Excel.Workbooks.Add. Первым параметром нужно указать имя
файла (в формате WideString),
если рабочая книга уже была ранее создана,
или «пустой» параметр EmptyParam,
если книга создается впервые.
Все мои попытки работать с объектами Range оказались неудачными. Чтобы вы не
слишком осуждали меня, я поместил
библиотеку типов Excel_TLB.pas
в каталог размещения примера — полистайте
ее на досуге и попробуйте найти нужное
решение для изменения ширины колонок и
полей листа, а также для раскрашивания
диапазона, выравнивания текста и т.п.
Есть свои нюансы и при обращении к
ячейкам. Во-первых, ими владеет объект Application,
а не Sheet.
Во-вторых, обращение к конкретному элементу
коллекции Cells (как и любой другой коллекции) возможно
только через ее свойство Item.
Подводя итоги, еще раз хочу обратить ваше
внимание на то, что по времени выполнения
позднее связывание хотя бы не проигрывает
раннему — во всяком случае, для
рассмотренных примеров. Если учесть, что
единственными доступными подавляющему
большинству программистов документами по
серверам MS
Office
являются справочные файлы vbaXXX.hlp, можно сделать вывод: использование
вариантов (позднее связывание) проще,
удобнее, а главное — намного понятнее, чем
непосредственная работа с интерфейсами (раннее
связывание).
КомпьютерПресс 6’2001