Каталог расширений

Популярные теги

3gp       avi       fb2       jpg       mp3       pdf      

Как в делфи создать файл


классика Pascal. Работа с типизированными файлами в Delphi – Delphi в Internet

Удивительно, но факт – запрос “delphi файлы” в Яндексе – это один из самых популярных запросов, касающихся Delphi. Популярнее только “delphi скачать” – видимо ещё не все слышали про такую штуку как Delphi Community Edition. Раз есть в Сети запрос – должен быть и ответ. Посмотрим, что получится в итоге.

Содержание статьи

Классика работы с файлами в Delphi – ключевое слово File

Этот способ, без преувеличения, можно назвать древнейшим способом работы с файлами в Pascal/Delphi. Однако и он до сих пор используется в работе, особенно, если это, например, лабораторная работа по информатике в школе или ВУЗе.

Для определения файловой переменной в Delphi/Pascal используется ключевое слово File. При этом, мы можем определить как типизированный файл, так и не типизированный, например:

type TPerson = record Name: string[20]; Family: string[20]; end;   var UntypedFile: File; //нетипизированный двоичный файл TypedFile: File of TPerson;//типизированный файл

Для типизированного фала мы можем задать тип данных фиксированного размера (ShortString, String[20], Integer, Single и так далее), например, мы можем определить такие типизированные файлы:

 IntFile: File of integer; StringFile: file of single; ShortStringFile: file of ShortString;

Или, как в примере выше использовать для указания типа запись (record), в которой все поля имеют фиксированный размер. Для типизированного файла нельзя указывать типы данных, размер которых не фиксирован, например, вот такие определения файловых переменных недопустимы:

type TIntArr = array of integer;   var StrFile: file of string; //недопустимо - размер string заранее не известен ArrFile: file of TIntArr;//недопустимо - размер динамического массива заранее неизвестен

Более того, даже компилятор Delphi укажет вам на ошибку, сообщив следующее:

[dcc32 Error] E2155 Type ‘string’ needs finalization – not allowed in file type

Определив файловую переменную можно приступать к работе с файлом. Алгоритм работы при этом будет следующим:

  1. Ассоциировать файловую переменную с файлом на диске
  2. Открыть файл
  3. Записать/Прочитать файл
  4. Закрыть файл

При этом, для типизированных и не типизированных файлов работа в части чтения/записи несколько различается в плане используемых методов.

Работа с типизированными файлами в Delphi

Рассмотрим несколько примеров работы с типизированными файлами в Delphi.
Для начала, рассмотрим вариант работы с типизированным файлом, например, представленном выше:

type TPerson = record Name: string[20]; Family: string[20]; end; var TypedFile: File of TPerson;

Пример №1. Запись данных в типизированный файл Delphi

Запишем в наш файл две записи:

program example_1;   {$APPTYPE CONSOLE}   {$R *.res}   uses System.SysUtils;   type TPerson = record Name: string[20]; Family: string[20]; end;   var TypedFile: File of TPerson; Person: TPerson; begin //связываем файловую переменную с файлом на диске AssignFile(TypedFile,'MyFile.txt'); //открываем файл для записи Rewrite(TypedFile); //задаем имя/фамилию человека Person.Name:='Иван'; Person.Family:='Иванов'; //добавляем запись в файл Write(TypedFile, Person); //задаем имя/фамилию второго человека Person.Name:='Петр'; Person.Family:='Петров'; //записываем в файл Write(TypedFile, Person); //закрываем файл CloseFile(TypedFile);   Readln; end.

Рассмотрим методы, используемые в этом примере:

function AssignFile(var F: File; FileName: String): Integer;

Связывает файловую переменную F с внешним файлом FileName. В качестве второго параметра может задаваться как абсолютный путь к файлу, например, ‘C:/MyFile.txt‘, так и относительный, например, в коде выше файл будет создан рядом с exe-файлом.

procedure Rewrite(var F: File; [ RecSize: Integer]);

Создает новый файл и открывает его. Если внешний файл с таким именем уже существует, он удаляется и на его месте создается новый пустой файл. Если F уже открыт, он сначала закрывается, а затем воссоздается. Текущая позиция файла устанавливается в начале пустого файла.
F – это переменная, связанная с внешним файлом с использованием AssignFile. RecSize – это необязательное выражение, которое можно указывать, только если F является нетипизированным файлом (об этом ниже).

procedure Write([var F: File]; P1; [ ..., PN]); overload;

Используется для записи в типизированный файл. F – файловая переменная, P1..PN – это переменная того же типа, что и тип файла F.

procedure CloseFile(var F: File);

Прекращает связь между файловой переменной и файлом внешнего диска. F – это файловая переменная любого типа. Внешний файл, связанный с F, полностью обновляется, а затем закрывается, освобождая дескриптор файла для повторного использования.

В результате выполнения представленного выше кода, рядом с exe-файлом будет создан новый файл MyFile.txt, содержащий две записи, при этом, каждая запись будет иметь фиксированный размер, вне зависимости от фактических имени/фамилии.

Для того, чтобы в delphi не перезаписывать каждый раз файл, а добавлять в конец файла новые записи необходимо открывать типизированные файлы методом Reset. Рассмотрим пример добавления новых записей в типизированные файлы Delphi.

Пример №2. Добавление записей в типизированный файл Delphi

Рассмотрим такой пример Delphi:

program example_2;   {$APPTYPE CONSOLE}   {$R *.res}     uses System.SysUtils;   type TPerson = record Name: string[20]; Family: string[20]; Age: integer; end;   procedure ReadTypedFile; const cStr = '%s %s %d'; var F: File of TPerson; Person: TPerson; begin AssignFile(F, 'MyFile.txt'); Reset(F); while not Eof(F) do begin Read(F, Person); Writeln(Format(cStr, [Person.Name, Person.Family, Person.Age])); end; end;   procedure AppendTypedFile; var F: file of TPerson; Person: TPerson; begin AssignFile(F, 'MyFile.txt'); // открываем файл для записи Reset(F); Seek(F, FileSize(F)); // задаем имя/фамилию человека Writeln('Введите имя: '); Readln(Person.Name); Writeln('Введите фамилию: '); Readln(Person.Family); Writeln('Введите возраст: '); Readln(Person.Age); // добавляем запись в файл Write(F, Person); // закрываем файл CloseFile(F); end;   var TypedFile: File of TPerson; Person: TPerson; DoAppend: integer;   begin if not FileExists('MyFile.txt') then begin AssignFile(TypedFile, 'MyFile.txt'); // открываем файл для записи Rewrite(TypedFile); // закрываем файл CloseFile(TypedFile); end;   // связываем файловую переменную с файлом на диске repeat Writeln('Добавить в файл запись: 1 - Да; 2 - Нет'); Readln(DoAppend); case DoAppend of 1: AppendTypedFile; 2: break; end; until DoAppend = 0; //читаем все записи из типизированного файла ReadTypedFile; Readln; end.

Разберемся с тем, что здесь делается. Во-первых, условие:

if not FileExists('MyFile.txt') then

проверяет, существует ли файл на диске. Метод FileExist имеет следующее описание:

function FileExists(const FileName: string; FollowLink: Boolean = True): Boolean;

FileName – имя файла, существование которого необходимо проверить. Второй параметр – FollowLink учитывается только при использовании символической ссылки. То есть, если нужно проверить только наличие символической ссылки на файл, то параметр FollowLink устанавливается в False, а если нужно проверить наличие и символической ссылки на файл и самого файла, то FollowLink устанавливается в True (значение по умолчанию).

Таким образом, в нашем примере, если файла нет на диске то он создается пустым. Далее выполняется цикл:

repeat Writeln('Добавить в файл запись: 1 - Да; 2 - Нет'); Readln(DoAppend); case DoAppend of 1: AppendTypedFile; 2: break; end; until DoAppend = 0;

В этом цикле, если пользователь вводит 1, выполняется процедура AppendTypedFile, которая добавляет в файл очередную запись:

procedure AppendTypedFile; var F: file of TPerson; Person: TPerson; begin AssignFile(F, 'MyFile.txt'); // открываем файл для записи Reset(F); //смещаемся в конец файла Seek(F, FileSize(F)); // задаем имя/фамилию человека Writeln('Введите имя: '); Readln(Person.Name); Writeln('Введите фамилию: '); Readln(Person.Family); Writeln('Введите возраст: '); Readln(Person.Age); // добавляем запись в файл Write(F, Person); // закрываем файл CloseFile(F); end;

Здесь, в принципе, весь алгоритм расписан в комментариях к процедуре.
Метод Reset не воссоздает файл снова, как Rewrite, а открывает его для чтения/записи (в случае двоичных файлов). Что касается метода Seek, то он имеет следующее описание:

procedure Seek(var F: File; N: Integer);

F – файловая переменная, ассоциированная с файлом на диске, N – номер записи в файле (первый номер – 0). Чтобы переместиться сразу в конец файла, мы сделали такой вызов:

где FileSize – это метод Delphi имеющий следующее описание:

function FileSize(var F: File): Integer;

В случае использования типизированных файлов эта функция возвращает количество записей в файле.

После того, как пользователь вводит что-то кроме 1 срабатывает метод ReadTypedFile – чтение всех записей из файла:

procedure ReadTypedFile; const cStr = '%s %s %d'; var F: File of TPerson; Person: TPerson; begin AssignFile(F, 'MyFile.txt'); Reset(F); while not Eof(F) do begin Read(F, Person); Writeln(Format(cStr, [Person.Name, Person.Family, Person.Age])); end; end;

Здесь мы, опять же, открываем файл методом Reset и в цикле while..do проходим по всем записям файла, пока не дойдем до конца. Здесь мы использовали два новых метода Delphi:

function Eof([var F: File]): Boolean; overload;

Eof возвращает True, если текущая позиция файла находится за последним символом файла или файл пуст. В противном случае Eof возвращает False.
По аналогии с методом Write, метод Read производит чтение очередной записи из файла и имеет следующее описание:

procedure Read(var F: File; V1; [ ..., VN]);

Результат работы нашего примера может быть следующим:

Ещё одним полезным методом для работы с типизированными файлами может быть процедура Truncate:

procedure Truncate(var F: File);

Удаляет все записи после текущей позиции файла. Вызовите Truncate в коде Delphi, чтобы текущая позиция файла стала концом файла (Eof (F) вернет true).
Рассмотрим пример использования этой процедуры.

Пример №3. Удаление последних записей типизированного файла в Delphi

Воспользуемся файлом, созданным в предыдущем примере и удалим из него две последние записи:

program example_3;   {$APPTYPE CONSOLE}   {$R *.res}     uses System.SysUtils;   type TPerson = record Name: string[20]; Family: string[20]; Age: integer; end;   procedure ReadTypedFile; const cStr = '%s %s %d'; var F: File of TPerson; Person: TPerson; begin AssignFile(F, 'MyFile.txt'); Reset(F); while not Eof(F) do begin Read(F, Person); Writeln(Format(cStr, [Person.Name, Person.Family, Person.Age])); end; end;   var TypedFile: File of TPerson; Person: TPerson; Count: integer; DoErase: integer; begin AssignFile(TypedFile,'MyFile.txt'); Reset(TypedFile); Count:=FileSize(TypedFile); if Count<2 then begin Writeln('Количество записей в файле меньше двух. Стереть все записи? 1 - Да; 2 - Нет'); Readln(DoErase); if DoErase=1 then Truncate(TypedFile); end else begin Seek(TypedFile, Count-2); Truncate(TypedFile); end; //читаем все записи из типизированного файла ReadTypedFile; Readln; end.

В этом примере мы делаем следующее:

  1. Открываем файл существующий AssignFile/Reset
  2. Определяем количество записей в файле (Count:=FileSize(TypedFile))
  3. Если количество записей меньше двух, то спрашиваем у пользователя стереть ли все записи и, в случае положительного ответа, вызываем метод Tuncate
  4. Если количество записей в файле больше двух, то смещаемся на нужную нам позицию в файле (Seek(TypedFile, Count-2)) и затираем две последние записи методом Truncate.

Подведем итог

Для работы с типизированными файлами в Delphi в самом общем случае нам необходимо выполнить следующую последовательность операций:

  1. Определить тип записей в файле – это могут быть стандартные типы данных Delphi с фиксированным размером: ShortString, integer, single и так далее или собственные типы данных, например, записи (record), но, в этом случае, главное условие – размер записи должен быть фиксированным.
  2. В коде Delphi/Pascal определить файловую переменную, используя ключевое слово file и, указав тип записей файла, определенный в пункте 1.
  3. Ассоциировать файловую переменную с внешним файлом на диске, используя метод AssignFile.
  4. Открыть файл для чтения/записи, используя методы Rewrite/Reset.
  5. Чтобы сделать в файл очередную запись используем метод Write, для чтения очередной записи из файла – используем метод Read.
  6. Закрыть файл методом CloseFile.

В целом, рассмотренные выше примеры не охватывают всех возможностей работы с типизированными файлами в Delphi, а, скорее, показывают основные операции по работе с типизированными файлами. Поэтому ниже представлен перечень методов которые могут применяться при работе с типизированными файлами в Delphi/Pascal.

Функции и процедуры для работы с типизированными файлами в Delphi/Pascal

Метод Краткое описание
procedure AssignFile(var F: File; FileName: String)
Ассоциирует файловую переменную F с внешним файлом FileName. Переменная FileName может быть как именем файла, так и содержать полный путь к файлу на диске.
procedure CloseFile(var F: File);
Закрывает файл, ассоциированный с переменной F и освобождает переменную для дальнейшего использования.
function Eof(var F: File): Boolean;
Проверяет конец файла и возвращает True, если файловый указатель стоит в конце файла. В случае записи True означает, что очередной компонент будет добавлен в конец файла, при чтении – что файл прочтен полностью.
procedure Erase(var F: File);
Удаляет внешний файл, связанный с файловой переменной F. Перед удалением файла его необходимо закрыть методом CloseFile.
 
function FilePos(var F: File): Integer;
Возвращает текущую позицию в файле. В коде Delphi используйте FilePos для файловой переменной открытого файла, чтобы определить текущую позицию в файле. Если текущая позиция в файле находится в начале, FilePos возвращает 0.
 
function FileSize(var F: File): Integer;

 

Для типизированных файлов возвращает количество записей в файле.
procedure Read(var F: File; V1; [ ..., VN]);
Считывает из типизированного файла одну или несколько записей
procedure Rename(var F: File; Newname: String);
Переименовывает файл, ассоциированный с переменной F
procedure Reset(var F: File; [ RecSize: Integer]);
Открывает файл для чтения. Второй параметр RecSize указывается в случае использования нетипизированных файлов и указывает размер записи в файле в байтах
procedure Rewrite(var F: File; [ RecSize: Integer]);
Воссоздает файл. Если файл существует, то Rewrite его удалит, а затем создаст снова. RecSize используется для нетипизированных файлов
procedure Seek(var F: File; N: Integer);
Перемещает текущую позицию в файле к записи N (первая запись имеет номер 0)
procedure Truncate(var F: File);
Стирает из файла данные, расположенные за текущей позицией
procedure Write([var F: File]; P1; [ ..., PN]);
Записывает в файл F одну или несколько записей
Take Our Poll

0 0 голос

Рейтинг статьи

Microsoft Word в Delphi. – Delphi в Internet

Сегодня, в последний рабочий день недели, практически весь день провозился над передачей данных из Delphi в Word. Так как подозрение есть, что работа продолжится то решил кое-какие моменты по работе с Microsoft Word в Delphi запечатлеть и у себя в блоге. Написать такую мини-шпаргалку (тем более, что по Excel уже кое что есть).

Для начала, немного общих моментов по работе с MS Office в Delphi. И первое, что мы сделаем – это создадим объект Word.Application. Создается этот объект абсолютно также, как и объект Excel.Application:

uses ComObj; var Word: variant; [...] procedure CreateWord(const Visible: boolean); begin Word:=CreateOleObject('Word.Application'); Word.Visible:=Visible; end;

Всё достаточно просто. Далее мы можем работать с объектом следующим образом:

  1. Создавать документ Word с нуля
  2. Открыть уже существующий документ и изменить в нем текст для получения необходимой формы документа.

Рассмотрим оба варианта, т.к. оба они имеют как свои плюсы, так и недостатки.

1. Создание документа Microsoft Word в Delphi с нуля.

Чтобы создать новый документ необходимо выполнить метод Add у коллекции Documents, т.е.:

[...] Word.Documents.Add [...]

и после этой операции уже начинать работать с документам обращаясь к нему по индексу или имени в коллекции. Также, можно создать новый документ по шаблону (*.dot). Для этого необходимо выполнить тот же метод Add, но с одним входным параметром – путем к файлу-шаблону:

[...] Word.Documents.Add(TamplatePath:string); [...]

Чтобы получить список всех открытых в данный момент документов Word можно воспользоваться следующим листингом:

[...] var List: TStringList; i: integer; begin List:=TStringList.Create; for i:=1 to Word.Documents.Count do List.Add(Word.Documents.Item(i).Name); end; [...]

Обратите внимание, что нумерация начинается с 1, а не с нуля. Чтобы активировать любой документ из коллекции для работы, необходимо выполнить метод Activate:

Word.Documents.Item(index).Activate

где index – номер документа в коллекции.

Теперь можно приступать к записи и чтению документа. Для работы с текстов в документе Word, как и в Excel для работы с ячейками таблицы, определен объект Range. Именно методы этого объекта и дают нам возможность работы с текстом. Для начала рассмотрим работу двух основных методов: InsertBefore и InsertAfter.

Как следует из название – первый метод вставляет текст в начало содержимого Range, а второй – в конец. При этом сам объект Range может содержать как весть документ (Document) так и какую-либо его часть. Например, в следующем листинге я вставлю строку в начало документа и затем методом InsertAfter буду добавлять несколько строк текста в конец документа:

[...] Word.ActiveDocument.Range.InsertBefore('Hello World'); Word.ActiveDocument.Range.InsertAfter('текст после Hello World'); Word.ActiveDocument.Range.InsertAfter('окончание строки в документа'); [...]

При выполнении этих трех операции Range содержал весь документ.

Если работать со всем документом неудобно, а необходимо, например выделить фрагмент с 50 по 100 символ и работать с ним, то можно воспользоваться функцией Range, которая вернет нам необходимый объект Range:

var MyRange: variant; begin MyRange:=WordActiveDocument.Range(50,100); MyRange.InsertBefore('Привет');//всё, что было после 50-го символа сдвинулось вправо end;

Это что касается записи текста. Решение обратной задачи – чтения текста из документа ещё проще. Достаточно воспользоваться свойством Text у объекта Range:

[...] ShowMessage(Word.ActiveDocument.Range.Text) //весь текст в документе [...]

Также для чтения документа можно воспользоваться коллекцией документа Words (слова). За слово принимается непрерывный набор символов – цифр и букв, который оканчивается пробелом.

Перечисляются слова документа точно также как и при работе с коллекцией документов, т.е. первое слово имеет индекс 1 последнее – Word.Count.

[...] ShowMessage(Word.ActiveDocument.Words.Item(Word.ActiveDocument.Words.Count).Text) [...]

В данном случае я вывел на экран последнее слово в документе.

Очевидно, что приведенный выше способ работы с документам хорош в случае, когда требуется создать относительно простой документ Word и не требуется лишний раз рассчитывать фрагменты текста, правильно вставлять таблицы и т.д. Если же необходимо работать с документами, которые имеют сложное содержание, например текст в перемежку с рисунками, таблицами, а сам текст выводится различными шрифтами, то, на мой взгляд наиболее удобно использовать второй способ работы с Word в Delphi – просто заменить текст в уже заранее заготовленном документа.

2. Работа с документами Word в Delphi. Открытие готового документа и замена текста.

Чтобы открыть заранее заготовленный документ Word в Delphi достаточно воспользоваться методом Open у коллекции Documents, например так:

var FilePath: string; [...] Word.Documents.Open(FilePath) [...]

Метод Open можно вызывать с несколькими аргументами:

  • FileName: string – путь и имя файла;
  • ConfirmConversions: boolean – False – не открывать диалоговое окно “Преобразование файла” при открытии файла, формат которого не соответствует формату Word (doc или docx)
  • ReadOnly:boolean – True – открыть документ в режиме “Только для чтения”
  • AddToRecentFiles: boolean – True, чтобы добавить документ в список недавно открытых документов.
  • PasswordDocument: string – пароль для открытия документа
  • PasswordTemplate: string – пароль для открытия шаблона
  • Revert : boolean – True, чтобы вернуться к сохраненному документу, если этот документ открывается повторно.
  • WritePasswordDocument: string – пароль для сохранения измененного документа в файле
  • WritePasswordTemplate:string – пароль для сохранения изменений в шаблоне
  • Format:integer – формат открываемого документа.

Обязательным параметром метода Open является только FileName, остальные – могут отсутствовать. Если же Вам необходимо воспользоваться несколькими параметрами, то их необходимо явно указывать при вызове метода, например:

[...] Word.Documents.Open(FileName:=FilePath, ReadOnly:=true) [...]

В этом случае документ открывается в режиме “Только для чтения”. При таком способе вызова (с явным указанием аргументов) положение аргументов может быть произвольным.

Что касается последнего аргумента – Format, то он может принимать  целочисленные значения (применительно к версиям Microsoft Word 2007 и выше) от 0 до 13. При этом, для того, чтобы открыть “родные” вордовские документы (doc) достаточно использовать значения 0 или 6.

Теперь, когда документ открыт его необходимо преобразовать. Обычно я делаю следующим образом: в тех местах документа, в которые необходимо вставить текст я расставляю либо закладки, либо простые строки текста, например, обрамленные символом $ или #. И затем просто выполняю поиск и замену подстрок следующим образом:

function FindAndReplace(const FindText,ReplaceText:string):boolean; const wdReplaceAll = 2; begin Word.Selection.Find.MatchSoundsLike := False; Word.Selection.Find.MatchAllWordForms := False; Word.Selection.Find.MatchWholeWord := False; Word.Selection.Find.Format := False; Word.Selection.Find.Forward := True; Word.Selection.Find.ClearFormatting; Word.Selection.Find.Text:=FindText; Word.Selection.Find.Replacement.Text:=ReplaceText; FindAndReplace:=Word.Selection.Find.Execute(Replace:=wdReplaceAll); end;

Приведенная выше функция позволяет провести поиск и замену текстового фрагмента во всём документе. Для того, чтобы ограничить возможности пользователя при работе с шаблоном документа я обычно ставлю на необработанный файл пароль, а после обработки – пароль снимаю и сохраняю документ с другим названием в необходимую директорию.

Вот, наверное, самые-самые простые методы работы с Word в Delphi. Кстати, пишу пост и, думаю, что у кого-то из читателей может возникнуть вопрос: причём тут Delphi в Internet и Word в Delphi? :) Честно говоря, приведенный выше фрагменты кода можно использовать для нужд в Internet с натяжкой, например, при автосоставлении небольших отчётов по чему-либо. А вообще, в недалеком будущем, есть в планах поразбираться с Тезаурусом Word и попробовать составить небольшой синонимайзер для собственных нужд – он-то и пригодится нам в Internet :)

5 1 голос

Рейтинг статьи

Как создать и открыть Excel - файл в Delphi

Открываем Excel в Delphi

Для этого, в раздел Uses программы, необходимо включить модуль ComObj.

Далее поместим на форму компонент TButton и в обработчике событий OnClick запишем следующий код:

procedure TForm1.Button1Click(Sender: TObject);

var

XL: Variant;

begin

XL := CreateOLEObject('Excel.Application'); // Создание OLE объекта

XL.WorkBooks.add; // Создание новой рабочей книги

XL.visible := true;

end;

 

Результатом выполнения станет запуск программы Microsoft Excel и открытие нового листа.

Для открытия уже существующего документа Excel следует воспользоваться методом Open:

XL.WorkBooks.Open('c:\example.xls');

Если необходимо открыть документ Excel только для чтения, пишем следующее:

XL.Workbooks.Open['c:\example.xls', 0, True];

Для закрытия документа Excel:

 

Если Вам необходимо при открытии файла использовать не абсолютный, а относительный путь, то необходимо предварительно воспользоваться функцией GetDir, рассмотрим пример ниже:

procedure TForm1.Button1Click(Sender: TObject);

var

   XL: Variant;

   AppLocation:string;

begin

   try

XL := CreateOLEObject('Excel.Application'); // Создание OLE объекта

   except

     ShowMessage('Cannot start MS Excel.');

   end;

 

GetDir(0,AppLocation); // Возвращает текущий каталог диска

XL.WorkBooks.Open(AppLocation +'\filename.xlsx');

XL.visible := true;

end;


Вконтакте

Facebook

Twitter

Google+

Одноклассники

Мой мир

E-mail

Работа с Excel в Delphi. Основы основ. – Delphi в Internet

Видимо любители экономить килобайты оперативной памяти могут меня закидать помидорами или ещё чем по-хуже, но все-таки я скажу, что интеграция приложений (мегабайты оперативы) – это большой плюс нынешней разработки приложений.
Как ни крути, а время DOS и килобайтов оперативной памяти прошло. Вряд ли кто-то всерьез сейчас задумывается над тем куда это с винчестера пропал мегабайт? Да и использование в своих приложениях функциональности программ, которых ты не писал, но которые выполняют что-то лучше – это всё-таки больший прогресс, нежели корпеть год-два над программой, а потом узнать, что время-то прошло.

Введение

Итак, цель сегодняшней статьи – поделиться с Вами опытом работы с Microsoft Excel в приложениях, написанных на Delphi.
Вспомнился сейчас один случай. Когда я только начинал работать по своей специальности, пригласили меня написать программу-расчётник для экологов нашего нефтезавода. В принципе ничего серьёзного – программа считает выброс от нагревательной печи и выдает табличку результатов, которую необходимо распечатать и уложить в толстую папку с отчётами. Естественно, что в области разработки подобных приложения я далеко не пионер, поэтому дали взглянуть на аналог будущей программы, который работал ещё под DOS и печатались отчёты на дико скрипящем матричном принтере с 12-ю иголками. Ну посмотрел, элементарная таблица, расчёт немного запутан, но жить можно – начал по-тихоньку писать. И попалась мне тогда на глаза статейка про работу с Excel в Delphi. Вот я и решил попробовать выдавать отчёт не только на форму приложения, а ещё и скидывать весь ход расчёта с формулами и прочим делом в Excel…Надо сказать более сильно детской радости начальника отдела я не видел до сих пор :). Люди, всю жизнь проработавшие в DOS увидели как тот же самый расчёт может выглядеть в современных условиях. Вот теперь при определении технических заданий на каждую новую программу, обязательно присутствует пункт, гласящий, что программа должна передавать данные либо в MS Word либо в MS Excel.Соответственно и цена на разработку возрастает, иногда значительно.

Отсюда можно сделать простой и однозначный вывод – заказчики готовы пожертвовать лишними деньгами только для того, чтобы всё в программе было красиво. Excel может дать вашему приложению ту самую красоту и удобство.

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

1. Как проверить установлен ли Excel на компьютере пользователя?

Создаем новый модуль (unit) и подключаем в uses следующие модули:

uses ComObj, ActiveX, Variants, Windows, Messages, SysUtils, Classes;

теперь объявляем глобальную переменную:

Одну константу (для удобства):

const ExcelApp = 'Excel.Application';

И пишем простенькую функцию:

function CheckExcelInstall:boolean; var ClassID: TCLSID; Rez : HRESULT; begin // Ищем CLSID OLE-объекта Rez := CLSIDFromProgID(PWideChar(WideString(ExcelApp)), ClassID); if Rez = S_OK then  // Объект найден Result := true else Result := false; end;

Или ещё короче:

function CheckExcelInstall: boolean; var ClassID: TCLSID; begin Result:=CLSIDFromProgID(PWideChar(WideString(ExcelApp)), ClassID) = S_OK; end;

Если функция CLSIDFromProgID находит CLSID OLE-объекта, то, соответственно – Excel установлен.

Но проверка на наличие установленного Excel – это только часть необходимых операций перед началом работы. Другой немаловажной проверкой является проверка на наличие уже запущенного экземпляра Excel. Если этого не делать, то может случиться такая нехорошая ситуация, когда в системе будет зарегистрировано …дцать процессов Excel и все оперативная память волшебным образом утекает “в трубу” – за такое могут и по ушам надавать. Но мы-то свои уши бережем. Пишем вторую функцию проверки.

2. Определяем запущен ли Excel

function CheckExcelRun: boolean; begin try MyExcel:=GetActiveOleObject(ExcelApp); Result:=True; except Result:=false; end; end;

Думаю тут лишних объяснений не потребуется? Всё предельно просто – если есть активный процесс Excel, то мы просто получаем на него ссылку и можем использовать Excel для своих корыстных целей. Главное – не забыть проверить – может кто-то этот самый Excel забыл закрыть, но это другой момент. Будем считать, что Excel в нашем полном распоряжении.

3. Как запустить Excel?

Одно дело, когда мы получаем в распоряжение уже запущенный Excel, другое – когда Excel требуется запустить из Delphi. Напишем функцию запуска Excel:

function RunExcel(DisableAlerts:boolean=true; Visible: boolean=false): boolean; begin try {проверяем установлен ли Excel} if CheckExcelInstall then begin MyExcel:=CreateOleObject(ExcelApp); //показывать/не показывать системные сообщения Excel (лучше не показывать) MyExcel.Application.EnableEvents:=DisableAlerts; MyExcel.Visible:=Visible; Result:=true; end else begin MessageBox(0,'Приложение MS Excel не установлено на этом компьютере','Ошибка',MB_OK+MB_ICONERROR); Result:=false; end; except Result:=false; end; end;

Здесь мы в начале проверяем, установлен ли Excel в принципе и, если он все же установлен, запускам. При этом мы можем сразу показать окно Excel пользователю – для этого необходимо выставить параметр Visible в значение True.

Также рекомендую всегда отключать системные сообщения Excel, иначе, когда программа начнет говорить голосом Excel – пользователь может занервничать.

Переходим к следующему этапу работы – созданию рабочей книги.

4. Создаем пустую рабочую книгу Excel

Для создания пустой рабочей книги я обычно использую вот такую функцию:

function AddWorkBook(AutoRun:boolean=true):boolean; begin if CheckExcelRun then begin MyExcel.WorkBooks.Add; Result:=true; end else if AutoRun then begin RunExcel; MyExcel.WorkBooks.Add; Result:=true; end else Result:=false; end;

Второй вариант (более лаконичный):

function AddWorkBook(AutoRun: boolean = true): boolean; begin Result := CheckExcelRun; if (not Result) and (AutoRun) then begin RunExcel; Result := CheckExcelRun; end; if Result then MyExcel.WorkBooks.Add; end;

То есть сразу проверяю запущен ли Excel и, если он не запущен, то либо запускаю и добавляю книгу, либо просто выхожу – всё зависит от ситуации.

Здесь, думаю, следует напомнить, что, если вы выполните эту функцию, например пять раз, то получите пять открытых рабочих книг и работать с ними как Вам захочется. Главное при этом правильно обратиться к необходимой книге, а для этого можно использовать вот такую функцию:

function GetAllWorkBooks:TStringList; var i:integer; begin try Result:=TStringList.Create; for i:=1 to MyExcel.WorkBooks.Count do Result.Add(MyExcel.WorkBooks.Item[i].FullName) except MessageBox(0,'Ошибка перечисления открытых книг','Ошибка',MB_OK+MB_ICONERROR); end; end;

Функция возвращает список TStringList всех рабочих книг Excel открытых в данный момент. Обратите внимание, что в отличие от Delphi Excel присваивает первой книге индекс 1, а не 0 как это обычно делается в Delphi при работе, например, с теми же индексами в ComboBox’ах.

Ну, и наконец, после того, как поработали с книгами – их требуется закрыть. Точнее сохранить, а потом уж закрыть.

5. Сохраняем рабочую книгу и закрываем Excel

Для того, чтобы сохранить рабочую книгу, я использовал такую функцию:

function SaveWorkBook(FileName:TFileName; WBIndex:integer):boolean; begin try MyExcel.WorkBooks.Item[WBIndex].SaveAs(FileName); if MyExcel.WorkBooks.Item[WBIndex].Saved then Result:=true else Result:=false; except Result:=false; end; end;

Если у Вас открыто 10 книг – просто вызываете функцию 10 раз, меняя значение параметра WBIndex и имени файла и дело в шляпе.

А закрывается Excel вот так:

function StopExcel:boolean; begin try if MyExcel.Visible then MyExcel.Visible:=false; MyExcel.Quit; MyExcel:=Unassigned; Result:=True; except Result:=false; end; end;

Вот набор тех основных функций с которых начинается вся интеграция Excel в приложения написанные на Delphi. В следующий раз займемся работой с конкретной книгой – научимся записывать и читать данные из книг.

Книжная полка

Автор: Юрий Магда

Название:Разработка приложений Microsoft Office 2007 в Delphi

Описание Описаны общие подходы к программированию приложений MS Office. Даны программные методы реализации функций MS Excel, MS Word, MS Access и MS Outlook в среде Delphi.

 

5 1 голос

Рейтинг статьи

Как в Delphi записать в файл

const txFileName = 'myFile.txt';

 

//оформим пример в виде процедуры

//на входе сторока, которую надо сохранить в файл

procedure saveIntoTextFile(txt: string);

var

     txtfile: TextFile;

begin

   //для начало нужно собрать файла, куда мы сохраняем текст

   path:= ExtractFilePath(application.ExeName) + '/' + txFileName;

   //ассоциируем название файла с файловой переменной

   AssignFile(txtfile, path);

   //выключаем проверку ошибок ввода-вывода

   //это такой вариант - для ленивых, чтобы и программа не парилась

   //и нам чтобы не реализовывать все проверки по-честному

   {$I-}

   if not FileExists(path) then

      //файла нет - создадим

      Rewrite(txtfile)

   else

      //если есть - откроем и установим указатель записи в конец

      Append(txtfile);

   {$I+}

   //пишем наш текст в открытый файл

   Write(txtfile, txt);

   //освобождаем дескрипторы, закрываем файл

   Closefile(txtfile);

end;

первое знакомство с HHW. – Delphi в Internet

Help…как же я ненавижу всю работу, связанную с созданием всякого рода хелпов. И ведь никуда от это работы не деться. Без полноценного, качественного help’a, контекстных справок, hint’ов и т.д. любая сколь угодно функциональная программа с “интуитивно понятным” интерфейсом может превратиться в нечто непостижимое для пользователя. Понятно, что редко кто читает Help к медиаплееру или текстовому редактору. Но совсем другое дело, когда пишется какая-то специализированная программа, например, ГИС или, как приходилось писать мне – программы расчёта приземных концентраций загрязняющих веществ – тут хочешь-не хочешь, а на пальцах всё объяснить пользователю за пять минут не получится – большое количество переменных, задаваемых пользователем, работа с БД – все эти моменты приходится прописывать в справку. До сих пор я обходился в работе простыми html-файлами, но рано или поздно надо было переходить на использование возможностей Windows. И видимо сегодня этот день настал :).

Как Вы знаете, для хранения справочной информации Windows активно использует chm-файлы. Достаточно удобный и легкий в плане работы формат. Именно такую справку мы и будем писать сегодня.
Для компиляции и работы с chm-файлами воспользуемся тем, что предлагает нам Microsoft – программой “HTML Help Workshop” скачать которую можно, перейдя по ссылке. Там же скачайте и всю документацию по API работы со справочной системой – она нам пригодиться на будущее.
И первое, что мы сделаем – это установим “HTML Help Workshop” (HHW) и создадим новый проект, содержащий всего один файл.
Жмем в главном меню HHW File–>New и в открывшемся окне выбираем “Project” – запустится мастер создания нового проекта.

Первый шаг можно пропустить т.к. мы ничего не конвертируем. Далее нас попросят задать расположение файла проекта на диске – указываем и остальные шаги пропускаем. В конце жмем “Готово” и hhw сгенерирует нам новый пустой проект справки:

Можете установить новые свойства вашего проекта – для этого надо сделать двойной щелчок по секции “Options” или нажать одноименную кнопку в левой части окна.
Теперь создадим наш первый (и единственный) в проекте файл справки. Для этого жмем в главном меню File–>New–>HTML File. В открывшемся окне пишем название нового раздела справки, например, “Hello World!” и HHW создаст для нас “скелет” нового документа:

Так как никаких визуальных средств для разработки hhw не использует, кроме редактора в стиле “а-ля блокнот”, то будем писать весь HTML-код ручками.
Для начала запишем следующее:

Заголовок второго уровня

Это наш первый html-файл для супер-спраки для супер-программы Hello World!

Жмем кнопку Save в верхнем тулбаре, задаем имя файла, например, index и сохраняем файл на диск.
Теперь прицепим этот файл к проекту. Для нажимаем кнопку “Add/Remove topic files”, затем в открвшемся окне кнопку “Add” и добавляем наш файл index.html к проекту:

Теперь надо наш проект скомпилировать. Для этого в главном меню программы необходимо выбрать File–>Compile и в открывшемся окне указать путь к файлу проекта (по умолчанию поле ввода содержит путь к текущему файлу проекта). В результате компиляции hhw выдаст нам в главном окне лог компиляции и создаст chm-файл справки.
Если Вы делали все как написано в посте, то Вы должны были получить в результате работы три файла: *.chm, *.hhp и *.html. Теперь можете открыть получившийся chm-файл и убедиться, что наш текст из index.htm в нем присутствует:
.
Теперь нам остается научиться вызывать этот файл из своей Delphi-программы.
В Сети вы можете встретить массу статей, касающихся запуска chm-фалов из своих программ. Обчно в этих статьях Вам сначала предлагают импортировать библиотеку, обявить вызов функции HtmlHelp и уж потом работать со справкой. Но дело в том, что модуль Windows.pas в Delphi 2010 уже содержит все необходимые типы данных и функции для работы с chm.
Создайте новый проект Delphi и поместите на главную форму всего одну кнопку. Убедитесь, что в uses подключен модуль windows и в событии onClick кнопки напишите всего одну строку:

HtmlHelp(handle,'Путь_к_файлу/help.chm',HH_DISPLAY_TOPIC,0);

Убедитесь, что файл справки запускается корректно. Теперь разберемся, что мы написали.
handle – первый параметр функции содержит всегда HWND окна вызывающего приложения.
Второй параметр – путь к файлу справки. В этом же параметре можно указать конкретный раздел справки, который необходимо открыть, название окна и т.д.
Третий параметр (HH_DISPLAY_TOPIC) – команда API. В конкретно нашем случае мы попросили открыть топик справки.
И последний параметр – ноль. Этот параметр используется, например, для команды вызова pop-up окна справки (об этом поговорим позже), в остальных случаях четвертый параметр должен быть равен нулю.
В следующий раз поговорим более подробно о структуре справочной системы и попробуем использовать другие возможности для работы со справкой, используя всё туже единственную функцию HtmlHelp.

0 0 голос

Рейтинг статьи

Как мне создать текстовый файл в Delphi

Переполнение стека
  1. Около
  2. Товары
  3. Для команд
  1. Переполнение стека Общественные вопросы и ответы
  2. Переполнение стека для команд Где разработчики и технологи делятся частными знаниями с коллегами
  3. Вакансии Программирование и связанные с ним технические возможности карьерного роста
.

Как создать файл, который невозможно удалить в Delphi

Переполнение стека
  1. Около
  2. Товары
  3. Для команд
  1. Переполнение стека Общественные вопросы и ответы
  2. Переполнение стека для команд Где разработчики и технологи делятся частными знаниями с коллегами
.

ini - Delphi создает файл Inifile

Переполнение стека
  1. Около
  2. Товары
  3. Для команд
  1. Переполнение стека Общественные вопросы и ответы
  2. Переполнение стека для команд Где разработчики и технологи делятся частными знаниями с коллегами
  3. Вакансии Программирование и связанные с ним технические возможности карьерного роста
  4. Талант Нанимайте технических специалистов и создавайте свой бренд работодателя
.

Создать XML-файл в Delphi 10.1 и выполнить основные XML-операции?

Переполнение стека
  1. Около
  2. Товары
  3. Для команд
  1. Переполнение стека Общественные вопросы и ответы
.

firemonkey - Как создать запись во время выполнения в delphi

Переполнение стека
  1. Около
  2. Товары
  3. Для команд
  1. Переполнение стека Общественные вопросы и ответы
  2. Переполнение стека для команд Где разработчики и технологи делятся частными знаниями с коллегами
  3. Вакансии Программирование и связанные с ним технические возможности карьерного роста
  4. Талант Нанимайте технических специалистов и создавайте свой бренд работодателя
.

Как мне добавить данные файла в мой EXE-файл во время выполнения в delphi

Переполнение стека
  1. Около
  2. Товары
  3. Для команд
  1. Переполнение стека Общественные вопросы и ответы
  2. Переполнение стека для команд Где разработчики и технологи делятся частными знаниями с коллегами
  3. Вакансии Программирование и связанные с ним технические возможности карьерного роста
  4. Талант Нанимайте технических специалистов и создавайте свой бренд работодателя
.

Смотрите также