Delphi запись в файл. Запись в текстовый файл, Excel и пр

Технология работы с файлами в системе Delphi требует определённого порядка действий:

  1. Прежде всего файл должен быть открыт . Система следит, чтобы другие приложения не мешали работе с файлом . При этом определяется, в каком режиме открывается файл - для изменения или только считывания информации. После открытия файла в программу возвращается его идентификатор, который будет использоваться для указания на этот файл во всех процедурах обработки.
  2. Начинается работа с файлом . Это могут быть запись, считывание, поиск и другие операции.
  3. Файл закрывается. Теперь он опять доступен другим приложениям без ограничений. Закрытие файла гарантирует, что все внесённые изменения будут сохранены, так как для увеличения скорости работы изменения предварительно сохраняются в специальных буферах операционной системы.
В Delphi реализовано несколько способов работы с файлами . Познакомимся со классическим способом, связанным с использованием файловых переменных . Файловая переменная вводится для указания на файл. Делается это с помощью ключевого слова File :

Var F: File ;

Описанная таким образом файловая переменная считается нетипизированной , и позволяет работать с файлами с неизвестной структурой. Данные считываются и записываются побайтно блоками, размер которых указывается при открытии файла, вплоть от 1 байт.

Но чаще используются файлы, состоящие из последовательности одинаковых записей. Для описания такого файла к предыдущему описанию добавляется указание типа записи:

Var F: File of тип_записи ;

В качестве типа могут использоваться базовае типы, или создаваться свои. Важно только, чтобы для типа был точно известен фиксированный размер в байтах, поэтому, например, тип String в чистом виде применяться не может, а только в виде String[N] , как указывалось в уроке Delphi 5 .

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

Для текстовых файлов отдельно укажу, что тип файловой переменной в этом случае TextFile , а тип обычной - String .

Для открытия файла нужно указать, где он расположен. Для этого файловая переменная должна быть ассоциирована с нужным файлом, который определяется его адресом. Адрес файла может быть абсолютным, с указанием диска и каталогов ("C:\Мои документы\Мои рисунки\FileName.ini"), или относительным, тогда он создаётся в папке с .exe файлом программы. Для задания относительного адреса достаточно указать имя файла с нужным расширением. Делается это оператором AssignFile:

AssignFile(SaveF, "C:\Мои документы\Мои рисунки\FileName.ini");
AssignFile(SaveF, "FileName.ini");

Теперь файл должен быть открыт.
Открытие файла оператором Rewrite приведёт воссозданию файла заново, т.е. существующий файл будет без предупреждения уничтожен, и на его месте будет создан новый пустой файл заданного типа, готовый к записи данных. Если же файла не было, то он будет создан.
Открытие файла оператором Reset откроет существующий файл к считыванию или записи данных, и его указатель будет установлен на начало файла :

Rewrite(SaveF);
Reset(SaveF);

Каждый из этих операторов может иметь второй необязательный параметр, имеющий смысл для нетипизированных файлов, и указывающий длину записи нетипизированного файла в байтах:

Rewrite(SaveF, 1);
Reset(SaveF, 1);

Чтение файла производится оператором Read:

Read(SaveF, SaveV);

Запись в файл производится оператором Write:

Write(SaveF, SaveV);

При этом чтение и запись производится с текущей позиции указателя, затем указатель устанавливается на следующую запись. Можно проверить, существует ли нужный файл, оператором FileExists:

if FileExists("FileName.ini")
then Read(SaveF, SaveV);

Принудительно установить указатель на нужную запись можно оператором Seek(SaveF, N) , где N - номер нужной записи, который, как и почти всё в программировании, отсчитывается от нуля:

Seek(SaveF, 49); - установка указателя на 50-ю запись.

При последовательном чтении из файла рано или поздно будет достигнут конец файла, и при дальнейшем чтении произойдёт ошибка. Проверить, не достигнут ли конец файла, можно оператором EOF (аббревиатура E nd O f F ile), который равен true , если прочитана последняя запись и указатель находится в конце файла:

while (not EOF(SaveF)) do
Read(SaveF, SaveV);

Для текстовых файлов вместо Read и Write используются операторы Readln и Writeln , умеющие определять конец строки. В коментариях приведена процедура чтения текстового файла.

Оператор Truncate(SaveF) позволяет отсечь (стереть или, если хотите, удалить!) все записи файла, начиная от текущей позиции указателя, и до конца файла.

В конце работы с файлом его необходимо закрыть. Это делается оператором CloseFile(SaveF) ;

Теперь можно изменить программу из первой части урока, запоминающую своё положение на экране. Описание переменных опускаю, оно приведено на рисунке выше.

Создаём обработчик события Формы OnCreate со следующим содержимым:

procedure TForm1.FormCreate(Sender: TObject) ;
begin
AssignFile(SaveF, "Init.ini") ;
if FileExists("Init.ini") then
begin
Reset(SaveF) ;
Read(SaveF, SaveV) ;
Form1.Left:= SaveV.X ;
Form1.Top:= SaveV.Y ;
Form1.Caption:=SaveV.Caption ; //Наши переменные дополнительно сохраняют заголовок Формы!
end ;
end ;

Теперь необходимо создать обработчик события OnClose:

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction) ;
begin
Rewrite(SaveF) ; //Нет необходимости проверять наличие файла, создадим его заново!
SaveV.X:= Form1.Left ;
SaveV.Y:= Form1.Top ;
SaveV.Caption:= Form1.Caption ;
Write(SaveF, SaveV) ;
CloseFile(SaveF) ;
end ;

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

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

Для файла существует понятие текущей позиции. Она показывает номер элемента, который будет прочитан или записан при очередном обращении к файлу. Чтение-запись каждого элемента продвигает текущую позицию на единицу вперед. Для большинства файлов можно менять текущую позицию чтения-записи, выполняя прямой доступ к его элементам.

В зависимости от типа элементов различают три вида файла:

– файл из элементов определенного типа (типизированные файлы);

– файл из элементов, тип которых не указан (нетипизированный файл);

– текстовый файл, т.е. элементами являются текстовые строки.

Для работы с файлом в программе объявляется файловая переменная (логический файл) в разделе описания переменных:

имя_файла: file of тип_элементов_файлов;

Файл, компонентами которого являются данные символьного типа, называется символьным, или текстовым:

имя_файла: TextFile;

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

AssignFile(var f, имя_файла: String);

Функции и процедуры для работы с файлами:

1. Открытие файла для записи

– перезапись (запись нового файла поверх существующего или создание нового файла) – используется процедура

rewrite (файловая_переменная)

– добавление в конец файла – используется процедура

append (файловая_переменная)

1. Запись в файл

Write

Writeln (файловая_переменная, список_переменных)

Различие между инструкциями в том, что инструкция writeln после вывода всех значений, записывает в файл символ «новая строка».

2. Закрытие файла. Перед завершением работы все открытые файлы необходимо закрыть с помощью процедуры

CloseFile (файловая_переменная)

3. Открытие файла для чтения. Используется процедура Reset(файловая_переменная)

4. Чтение данных из файла

read (файловая_переменная, список_переменных)

readln (файловая_переменная, список_переменных)

Отличие между этими процедурами в том, что при вызове инструкции readln указатель чтения из файла автоматически перемещается в начало следующей строки файла.

5. Определение конца файла. Используется функция EOF (файловая_переменная). Значение функции равно false, если прочитанный элемент данных не является последним в файле, т.е. возможно дальнейшее чтение. Если прочитанный элемент файла является последним, то значение EOF равно true.

While not eof(f) do begin … end;

6. Rename (var F; NewName: string) – переименовывает неоткрытый файл F любого типа. Новое имя задается в NewName.

7. Seek ( var F; NumRec: Longint) – устанавливает позицию чтения-записи на элемент с номером NumRec; F – типизированный или нетипизированный файл.

8. IOResult : Integ er – возвращает код, характеризующий результат (была ошибка или нет) последней операции ввода-вывода.

9. FilePos (var F): Longint – возвращает для файла F текущую файловую позицию (номер элемента, на которую она установлена, считая от нуля). Не используется с текстовыми файлами.

10. FileSize (var F): Longint – возвращает число компонент в файле F. Не используется с текстовыми файлами.

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

– {SITELINK-S102}OpenDialog{/SITELINK};

– {SITELINK-S103}SaveDialog{/SITELINK} и др, которые находятся на вкладке Dialogs.

Мы подробно рассмотрим, как копировать, удалять, переименовывать файлы. Научимся считывать и записывать информацию в типизированные файлы.

Копирование файлов с помощью .

Для этого нам потребуется вызов всего одной функции, которая выполняет именно копирование файлов. Это функция CopyFile(). У нее три параметра, два из которых обязательны. Вот полный синтаксис.
CopyFile("путь до начального файла","Путь куда надо копировать",Перезаписывать или нет)

Пример: CopyFile("D:sekretBD.txt","C: ame.txt", true);

В первом параметре можно указывать не только полный путь до файла. Если укажем, например, такой путь "sekretBD.txt", то наша программа будет искать этот файл в своем каталоге. Имя и разрешение нужно указывать именно такими, какие они есть у файла, иначе программа просто не найдет файл.
Во втором параметре тоже можно указывать относительный путь и там вы можете указать имя и расширение файла такое, какое захотите. Т.е. с помощью этой функции можно делать и переименовывание тоже.
Третий параметр отвечает за перезапись файла. Если мы укажем true, то файл не будет перезаписан, а если false, то программа перезапишет файл.

Переименование файлов с помощью

За переименование файлов отвечает функция RenameFile(). У нее 2 параметра. Вот ее полный синтаксис
RenameFile("путь до файла","новое имя");
Честно говоря, синтаксис этой функции меня не особо радует. В нем тоже в обоих параметрах надо указывать полный путь. Т.е. если мы, например, напишем так

RenameFile("C:2.txt","3.txt");

То он скопирует файл в каталог программы. Т.е. получается, что она может выполнять роль копирования тоже. Это немного странно.

Удаление файлов с помощью

Ну здесь все совсем просто. Функция, с помощью которой можно удалить файл, вызывается так:

DeleteFile("C:myprofile.txt");

Единственное, что она не всегда 100% удаляет файл. Когда файл защищен, она его не сможет удалить.

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

Что такое типизированный файл? Это файл с определенной структурой. Обычно это структурой выступают записи и базовые типы. В общем, важно, чтобы у типа был известен фиксированный размер, поэтому тип string применять нельзя, нужно делать так: String[N].
Вначале нам нужно объявить переменную, где будут храниться данные из файла. Делается это так:

Var f: file of <Тип>
Например, f: file of string;

Затем нам нужно соединиться с файлом. Для этого есть команда AssignFile. Для вызова надо прописать два параметра, это переменная, которую мы объявили выше и путь до файла. Например

AssignFile(f,"C:delphi.ini");

Теперь файл нужно открыть. Можно открыть двумя способами: с перезатиранием и без. Метод Rewrite открывает файл, предварительно создав его. Т.е. если файла в указанном нами пути не будет находиться, то он его создаст. Если там уже был такой файл, то он будет удален и заново создастся чистый файл. Метод Reset открывает файл и ставит указатель в самое начало файла. Но этот метод опасен тем, что если файла, указанного в подключении, нет, то программа вылетит с ошибкой. Так что для правильного применения функции Reset надо сказать компилятору об отключении ошибок. Задается это директивой {$I-} т.е. полный синтаксис функции reset будет таким:

{$I-}
Reset(f);
{$I+}

После этого надо проверить, был ли открыт файл или нет. Это можно сделать с помощью функции IOResult. Если она не равна нолю, то все успешно.
Полный синтаксис:

{$I-}
Reset(f);
{$I+}
If IOresult <> 0 then <ваш код>

Также осуществить проверку поможет функция FileExists. В ней нужно указать путь до файла.
Для чтения файла служит функция Read(), в которой указываются два параметра: переменная файла и тип записи, в нашем случае это string. Синтаксис:

Для записи в файл служит функция Write(), в которой указываются такие же два параметра: переменная файла и тип записи, в нашем случае это string. Синтаксис:

While not eof(f) do
Read(f,String);

Также есть функция seek, с помощью которой мы можем перейти на интересующую нас запись. Например, нам нужно обратиться к 20 записи и мы делаем так:

Еще есть функция truncate, С помощью которой мы можем удалить все записи файла, начиная от позиции указателя. Позицию можно указать с помощью функции seek, кто не понял.

После выполнения всех операций с файлом, необходимо его закрыть с помощью функции CloseFile(f);
Вот и все. На этом урок закончен. До встречи на сайте!

Тема : « Работа с типизированным файлом в Delphi »

Разработайте приложение, позволяющее работать с типизированным файлом путём выбора соответствующего пункта меню:

Файл

Просмотр

Редактирование

Печать

Справочники

Выход

Всех данных

Добавление

По условию

По условию

Корректировка

Документа

Поставщики

Удаление

Требования к приложению:

    Все глобальные типы данных, константы и переменные разместите в отдельном модуле (Unit2), который необходимо подключить к другим модулям проекта через пункт меню File / Use Unit.

    Для ввода исходных данных в файл (пункты меню «Корректировка» и «Добавление») разработайте экранную форму ввода. Предусмотрите проверку корректности ввода исходных данных используя событие OnKeyPress.

    Просмотр данных из файла надо реализовать выводом в таблицу StringGrid.

    При реализации пункта меню «Корректировка» на форму ввода должны быть выведены «старые» значения полей корректируемой записи.

    Пункт меню «Удаление» должен обеспечивать удаление одной записи из файла по выбору пользователя.

    Печать по условию реализуйте с помощью компонента QuickRep и дополнительного текстового файла.

    Печать документа можно реализовать с помощью метода Form10.Print, разместив предварительно на форму необходимую информацию.

    На форме, помимо главного меню, разместите:
    - картинку, соответствующую предметной области задачи;
    - инструментальную панель (компонент ToolBar) и вынесите не неё несколько кнопок SpeedButton, дублирующих некоторые пункты главного меню.

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

    При первом открытии формы, содержащей пункты главного меню задачи, доступными должны быть только пункты «Файл» и «Выход».

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

    При желании разместите слева от названия некоторых пунктов меню подходящее по смыслу изображение, используя свойство Bitmap (Program Files \ Common Files \ Borland Shared \ Images \ Buttons)

    На форме «Просмотр всех записей файла» организуйте поиск записи и обеспечьте вывод найденной записи на отдельной форме.

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

ПОРЯДОК ВЫПОЛНЕНИЯ ЗАДАНИЯ:

    Создайте новое приложение

    На Form1 создайте главное меню, согласно условию задачи.

    Вынесите на Form1 компонент Image1. В Инспекторе объектов компоненту Image1 назначьте свойства:
    Align = alClient

Stretch = true
Picture - файл с картинкой

    Добавьте к проекту новый модуль File / New / Unit и в разделе Interface пропишите

Ttov = record //структура записи, содержащая сведения о товаре для
// типизированного файла

DateP: TdateTime; //дата поставки

Postav: string ; // фирма-поставщик товара

Tovar: string; //название товара

Cena: real; //цена товара

Kol: integer; //количество товара

Var Tov: Ttov; //запись содержащая сведения о товаре

F1, F3: file of Ttov; // типизированный файл для хранения сведений о товаре

F2: textFile ; // текстовый файл для реализации печати по условию

Name_F: string; // имя файла

. . . // другие переменные, которые понадобятся для решения задачи

    Справочник Товаров » (File / New / Form). Форма «Справочник Товаров» должна содержать компоненты ListBox, Edit, Label и две кнопки BitBtn, позволяющие сохранить содержимое Edit в список ListBox и всё содержимое ListBox в текстовый файл. Компоненту ListBox в Инспекторе объектов назначьте свойству Sorted значение True, тогда элементы будут отсортированы в алфавитном порядке.

    В Инспекторе объектов для формы «Справочник Товаров» выберите событие OnActivate. Напишите в процедуре программный код:

If FileExists(‘tovar.txt’) = true then ListBox1.items.LoadFromFile(‘tovar.txt’);

    В Инспекторе объектов для кнопки «Добавить в список» выберите событие OnClick. Напишите в процедуре программный код:

Listbox1.Items.Append(Edit1.text);

Edit1.Text:= "";

    В Инспекторе объектов для кнопки «Удалить из списка» выберите событие OnClick. Напишите в процедуре программный код:

If MessageDlg ("Удалить запись? ", mtConfirmation, , 0) = mrYes

then ListBox1.items.Delete (ListBox1.itemindex);

    В Инспекторе объектов для кнопки «Закрыть» выберите событие OnClick. Напишите в процедуре программный код:

ListBox1.items.SaveToFile(‘tovar.txt’);

    В Инспекторе объектов для кнопки «Закрыть» выберите событие OnClick. Напишите в процедуре программный код: Form3.Close ;

    Аналогично выполните работу с формой «Справочник фирм-поставщиков ».

    В процедуре вызова пункта меню «Товары» пропишите программный код:
    Form3.Show;

    В процедуре вызова пункта меню «Поставщики» пропишите программный код:
    Form4.Show;

    Вынесите на Form1 компонент SaveDialog1. Напишите программный код процедуры пункта меню «Создать »:

If SaveDialog1.Execute = true then

Name_F:= SaveDialog1.FileName ;

AssignFile(F1, Name_F) ;

Rewrite(F1); // файл будет создан и открыт для записи

CloseFile(F1); // закрытие файла

N1.Enabled:= true; // пункт меню Файл

N2.Enabled:= true; // пункт меню Просмотр

N3.Enabled:= true; // пункт меню Редактирование

N4.Enabled:= true; // пункт меню Печать

N5.Enabled:= true; // пункт меню Справочники

N6.Enabled:= true; // пункт меню Выход

    Вынесите на Form1 компонент OpenDialog1. Напишите программные код процедуры пункта меню «Открыть »:

if OpenDialog1.Execute = true then

Name_F:= OpenDialog1.FileName ;

AssignFile(F1, Name_F);

N1.Enabled:= true; // пункт меню Файл

N2.Enabled:= true; // пункт меню Просмотр

N3.Enabled:= true; // пункт меню Редактирование

N4.Enabled:= true; // пункт меню Печать

N5.Enabled:= true; // пункт меню Справочники

N6.Enabled:= true; // пункт меню Выход

    В Инспекторе объектов для формы Form1 выберите событие OnCreate. Напишите в процедуре программный код:

N1.Enabled:= true; // пункт меню Файл

N2.Enabled:= false; // пункт меню Просмотр

N3.Enabled:= false; // пункт меню Редактирование

N4.Enabled:= false; // пункт меню Печать

N5.Enabled:= false; // пункт меню Справочники

N6.Enabled:= true; // пункт меню Выход

    Добавьте к приложению новую форму «Добавление » для ввода исходных данных в файл. Разместите на форме компоненты dateTimePicker1, Combobox1, Combobox2, edit1, edit2, Button1. Обеспечьте проверку корректности ввода данных в компоненты edit1, edit2 используя событие OnKeyPress.

    Для компонентов Combobox запретите ввод данных с клавиатуры (т.к. данные должны выбираться только из справочников). Для этого в процедуре события OnKeyPress пропишите программный код: If not (key in ) then key:= #0;

    В Инспекторе объектов для формы «Добавление» свойству Caption введите значение «Добавление записи» и выберите событие OnActivate. Напишите в процедуре программный код:

Exit ; //

Tov.Tovar:= Combobox1.text;

Tov.Postav:= Combobox2.text ;

Reset (f1); // открыли файл для записи

Seek (F1, Filesize (F1)); // переход на последнюю запись файла

Write (F1,Tov); // записываем в файл запись

Edit1.text:= ‘’; // очистка

Edit2.text:= ’’;

ComboBox1.text:= ‘’;

ComboBox2.text:= ‘’;

    Добавьте к приложению новую форму «Просмотр всех данных » для вывода данных из файла. Разместите на форме компонент StringGrid1. В Инспекторе объектов для формы «Просмотр всех данных» выберите событие OnActivate. Напишите в процедуре программный код:

Reset(F1); // открыли файл для чтения

StringGrid1.RowCount: = FileSize(F1)+1 ; //

ширина первого поля таблицы

ширина второго поля таблицы

Stringgrid1.ColWidths := 100; //

Stringgrid1.ColWidths := 100; // ширина пятого поля таблицы

Reset (f1); // открыли файл для чтения

WhiLe not eof(F1) do

Read(F1,tov) ; // считали запись из файла

    Добавьте к приложению новую форму «Просмотр по условию » для вывода данных из файла. Разместите на форме компоненты Label, ComboBox1, BitBtn1 и StringGrid1. В Инспекторе объектов для формы «Просмотр по условию» выберите событие OnActivate. Напишите в процедуре программный код:

If FileExists(‘postav.txt’) = true then ComboBox1.items.LoadFromFile(‘postav.txt’);
StringGrid1.visible:= false ;

    В Инспекторе объектов для компонента BitBtn1назначьте свойству Caption значение ‘Просмотр’ и выберите событие OnClick. Напишите в процедуре программный код:

If ComboBox1.text = ‘’ Then // если не выбран Поставщик тогда …

ShowMessage(‘Заполните все поля!’);

Exit ; // принудительный выход из процедуры

Reset(F1); // открыли файл для чтения

WhiLe not eof(F1) do

Read(F1,tov) ; // считали запись из файла

If tov.Postav = ComboBox1.text then K: = K + 1 ;

If k = 0 Then // если нет товара от выбранного Поставщика тогда …

ShowMessage (‘Нет товара от выбранного поставщика!’);

Exit ; // принудительный выход из процедуры

StringGrid1.RowCount: = k+1 ; // установили количество строк в таблице

StringGrid1.CoLCount: = 5 ; // установили количество столбцов в таблице

StringGrid1. FixedCols:= 0 ; // количество фиксированных столбцов

StringGrid1. FixedRows:= 1; // количество фиксированных строк

Stringgrid1.ColWidths := 100; // ширина первого поля таблицы

Stringgrid1.ColWidths := 120; // ширина второго поля таблицы

Stringgrid1.ColWidths := 130; // ширина третьего поля таблицы

Stringgrid1.ColWidths := 100; // ширина четвертого поля таблицы

Stringgrid1.ColWidths := 100; // ширина пятого поля таблицы

StringGrid1.CeLLs := ‘Дата поставки’ ;

StringGrid1.CeLLs := ‘Название товара’ ;

StringGrid1.CeLLs := ‘Поставщик’ ;

StringGrid1.CeLLs := ‘Цена за единицу’ ;

StringGrid1.CeLLs := ‘Количество’ ;

Reset (f1); // открыли файл для чтения

i:= 1; // i – номер строки таблицы для вывода данных из файла

WhiLe not eof(F1) do

Read(F1,tov) ; // считали запись из файла

If tov.Postav = ComboBox1.text then

StringGrid1.CeLLs := DateToStr(tov.DateP) ;

StringGrid1.CeLLs := tov.Tovar ;

StringGrid1.CeLLs := tov.Postav ;

StringGrid1.CeLLs := FloatToStr(tov.cena) ;

StringGrid1.CeLLs := intToStr(tov.kol) ;

i:= i + 1 ; // переход на следующую строку

StringGrid1.visible:= true ;

    Добавьте к приложению новую форму «Корректировка данных » для изменения записи файла (например, Form8). Разместите на форме компоненты такие же как на форме «Добавление». Обеспечьте проверку корректности ввода данных в компоненты edit1, edit2 используя событие OnKeyPress.
    В Инспекторе объектов для формы «Корректировка данных» выберите событие OnActivate. Напишите в процедуре программный код:

If FileExists(‘tovar.txt’) = true then ComboBox1.items.LoadFromFile(‘tovar.txt’);

If FileExists(‘postav.txt’) = true then ComboBox2.items.LoadFromFile(‘postav.txt’);

    В процедуру пункта меню «Корректировка» напишите программный код:

Form6.Show ; //
Z:= 44; //
// «Корректировка»

В Инспекторе объектов для компонента StringGrid1 формы «Просмотр всех данных» выберите событие OnDbLClick. Напишите в процедуре программный код:

If z = 44 then

Y:= StringGrid1.Row ; //

Reset (F1) ; // открыли файл для чтения

Seek (F1, y – 1) ; //

Read(F1, Tov) ; // считали из файла запись

Form8.dateTimePicker1.Date:= Tov.DateP ;

Form8.Combobox1.text:= Tov.Tovar ;

Form8.Combobox2.text:= Tov.Postav ;

Form8.edit1.text:= FLoatToStr (Tov.Cena) ;

Form8.edit2.text:= intToStr (Tov.Kol) ;

If (Edit1.tetx = ‘’) or (Edit2.text = ‘’) or (ComboBox1.text = ‘’) or (ComboBox2.text = ‘’) Then Begin

ShowMessage(‘Заполните все поля!’);

Exit ; // принудительный выход из процедуры

Reset (F1) ; // открыли файл для записи

Seek (F1, y – 1) ; // переместились в файле на запись с номером у-1

Tov.DateP:= dateTimePicker1.Date;

Tov.Tovar:= Combobox1.text;

Tov.Postav:= Combobox2.text ;

Tov.Cena:= StrToFloat (edit1.text);

Tov.Kol:= StrToInt (edit2.text);

Write (F1,Tov); // записываем в файл запись

Edit1.text:= ‘’; // очистка

Edit2.text:= ’’;

ComboBox1.text:= ‘’;

ComboBox2.text:= ‘’;

    В процедуру пункта меню «Удаление » напишите программный код:

Form6.Show ; // вызов формы «Просмотр всех данных»
Z:= 55; // признак того, что мы открыли форму «Просмотр» из пункта меню
// «Удаление»

В Инспекторе объектов для компонента StringGrid1 формы «Просмотр всех данных» выберите событие OnDblClick. Дополните процедуру программным кодом:

If z = 55 then

Otv:= MessageDlg ("Удалить запись? ", mtConfirmation, , 0) ;

if Otv = mrYes then

Y1:= StringGrid1.Row ; // определили номер текущей строки таблицы

Y2:= Y1 -1 ; // номер записи в файле, которую надо удалить

AssignFile(F3, ‘result.dat’);

Rewrite(F3); //

Reset (F1) ; // открыли файл для чтения

While not eof(F1) do

If FilePos(F1) Y2 then

Read(F1, tov) ; // считали запись из файла F 1

Write(F3, tov) ; // записали запись в файл F 3

ELSE Read(F1,tov);

Deletefile(Name_F) ; // удалили исходный файл

RenameFile(‘result.dat’, Name_F); // переименовали файл result.dat

    Добавьте к приложению новую форму «Печать по условию ». Разместите на форме компоненты Label, DateTimePicker, BitBtn.

    Выбрав событие OnClick для кнопки «Печать» напишите в процедуру программный код, обеспечивающий формирование текстового файла, содержащего записи из типизированного файла, удовлетворяющие условию печати:

AssignFile(F2, ‘pechat.txt’);

Rewrite(F2); // создали и открыли файл для записи

Reset (F1) ; // открыли файл для чтения

K1:= 0; //первоначальное значение для подсчёта количества записей за указанную дату

While not eof(F1) do

Read(F1, tov) ; //

If DateToStr(tov.DateP) = DateToStr (DateTimePicker1.date) then

D:= DateToStr(DateTimePicker1.date) ;

K1:= K1 + 1; // подсчёт количества записей за указанную дату

WriteLN (F2, tov.Tovar: 20, tov.Postav: 20, tov.Cena: 20: 2, tov.Kol: 15) ; // записали в
текстовый файл

    Добавьте к приложению новую форму (Form10).

    установите на Form10 компонент QuickRep1, который находится на странице QREPORT палитры компонентов;

    в Инспекторе объектов выберите в свойстве Bands подсвойство HasPageHeader и установите ему значение True, что обеспечит наличие верхнего колонтитула в
    выходном документе;

    в Инспекторе объектов выберите в свойстве Bands подсвойство HasTitle и установите ему значение True, что обеспечит наличие заголовочной полосы в выходном документе;

    установите на компонент QuickRep1 компонент QRStringsBand, который находится на странице QREPORT палитры компонентов;

    в Инспекторе объектов для компонента QuickRep1 выберите в свойстве Bands подсвойство HasPageFooter и установите ему значение True, что обеспечит наличие нижнего колонтитула в выходном документе;

    установите на полосу отчёта HasPageHeader компонента QuickRep1 компонент QRMemo1, который находится на странице QREPORT палитры компонентов. В Инспекторе объектов в свойстве Lines запишите информацию об организации на чей склад поступают товары;

    установите на полосу отчёта HasTitle компонента QuickRep1 компонент QRLabel1, который находится на странице QREPORT палитры компонентов. В Инспекторе объектов свойству Caption назначьте значение "Информация о поступлении товаров за ". В Инспекторе объектов измените значения свойства Font, чтобы заголовок документа выделялся от основной информации;

    установите на полосу отчёта HasTitle компонента QuickRep1 компонент QRLabel2, который находится на странице QREPORT палитры компонентов. Дополните программный код кнопки «Печать» строчкой:
    Form10.QRLabel2.Caption:= D ;

    установите на компонент QRStringsBand компонент QRExpr1, который находится на странице QREPORT палитры компонентов. В Инспекторе объектов свойству Expression назначьте значение QRStringsBand1;

    установите на полосу отчёта HasPageFooter компонента QuickRep1 компонент QRLabel3, который находится на странице QREPORT палитры компонентов. В Инспекторе объектов свойству Caption назначьте значение "Дата и время формирования документа";

    установите на полосу отчёта HasPageFooter компонента QuickRep1 компонент QRSysData1, который находится на странице QREPORT палитры компонентов. В Инспекторе объектов свойству Data назначьте значение qrsDateTime;

    установите на полосу отчёта HasPageFooter компонента QuickRep1 компонент QRLabel4, который находится на странице QREPORT палитры компонентов. В Инспекторе объектов свойству Caption назначьте значение "Общее количество товаров:";

    установите на полосу отчёта HasPageFooter компонента QuickRep1 компонент QRLabel5, который находится на странице QREPORT палитры компонентов. В программный код кнопки "ПЕЧАТЬ" допишите строку:
    Form10.QRLabel5.Caption:= intToStr (k1);

    тело процедуры-обработчик события "Нажатие кнопки ПЕЧАТЬ" дополните следующим программным кодом:

ShowMessage (‘Поставки за выбранную дату отсутствуют!’);

Exit ; // принудительный выход из процедуры

form10.QRStringsBand1.Items.Clear;

form10.QRStringsBand1.Items.LoadFromFile("pechat.txt");

form10.QRExpr1.AutoSize:=false;

form10.QRExpr1.AutoStretch:=true;

form10.QRExpr1.Left:=0;

form10.QRExpr1.Width:=form10.QRStringsBand1.Width;

form10.QuickRep1.Preview;

    Добавьте к приложению новую форму (Form11). В Инспекторе объектов свойству Caption назначьте значение "Товарная карточка". Разместите на форме компоненты такие же как на форме «Добавление», но вместо компонентов dateTimePicker1, Combobox1 и Combobox2 используйте компоненты Edit3, Edit4 и Edit5, а кнопку «Сохранить» переименуйте в «Печать»

    В процедуру пункта меню «Печать документа » напишите программный код:

Form6.Show ; // вызов формы «Просмотр всех данных»
Z:= 66; // признак того, что мы открыли форму «Просмотр» из пункта меню
// «Печать документа»

В Инспекторе объектов для компонента StringGrid1 формы «Просмотр всех данных» выберите событие OnDbLClick. Дополните процедуру программным кодом:

If z = 66 then

Y:= StringGrid1.Row ; // определили номер текущей строки таблицы

Reset (F1) ; // открыли файл для чтения

Seek (F1, y – 1) ; // переместились в файле на запись с номером у-1

Read(F1, Tov) ; // считали из файла запись

CloseFile (F1) ;

Form11.Edit5.text:= DateToStr(Tov.DateP) ;

Form11.Edit4.text:= Tov.Tovar ;

Form11.Edit3.text:= Tov.Postav ;

Form11.Edit1.text:= FLoatToStr (Tov.Cena) ;

Form11.Edit2.text:= intToStr (Tov.Kol) ;

    В Инспекторе объектов для кнопки «Печать» на Form11 выберите событие OnClick. Напишите в процедуре программный код: Form11.Print ;

If Edit1.text = … then

End ELSE ShowMessage (‘Пароль неверный ’) ;


В Инспекторе объектов для кнопки «Найти» выберите событие OnClick. Напишите в процедуре программный код:

Reset (F1) ; // открыли файл для чтения

While not eof(F1) do

Read(F1, tov) ; // считали запись из типизированного файла

If (DateToStr (tov.DateP) = DateToStr (DateTimePicker1.date)) and (tov.Postav = Combobox1.text) then

Form13. Label6. caption:= DateToStr (Tov.DateP) ;

Form13. Label7. caption:= Tov.Tovar ;

Form13. Label8. caption:= Tov.Postav ;

Form13. Label9. caption:= FloatToStr (Tov.Cena) ;

Form13. Label10. caption:= IntToStr (Tov.Kol) ;

CloseFile (F1) ;

If XX = 0 then ShowMessage (‘Данные отсутствуют… ‘) ;

Эта статья ориентирована на новичков, которые желают научиться работать с файлами в дельфи. В статье рассматриваются стандартные I/O операции с файлами, типичные ошибки и методы их предотвращения.

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

Step 1 - Обьявление файловой переменной

Файловая переменная в общем виде обьявляется в разделе var примерно так:

F: file of Type;

Например:

F: File of integer;

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

Да и вообще текстовые файлы "особенные". Некоторые функции работают только с текстовыми файлами. Также можно обьявить не только файл целых чисел(integer), текстовый файл или файл какого либо другого типа, но и файл собственного типа или записи, поместив обьявление типа или записи выше обьявления файловой переменной. Например:

TDay = (MON, TUE, WED, THU, FRI, SAT, SUN);

F: File of TDay;

F: File of TDay;

Следует обратить внимание, что длина строковых полей в записи должна быть четко определена (Name: String)

Step 2 - Назначение и открытие файла

После обьявления файловой переменной нужно связать её с физическим файлом на диске. Сделать это можно с помощью процедуры AssignFile:

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

Например:

var F: TextFile;

AssignFile(F, "text.txt");

После выполнения процедуры файловая переменная F будет связана с файлом text.txt, находящимся в папке с программой. И все действия, производимые с переменной будут действовать именно на этот файл. Однако переменную можно освободить для дальнейшего использования с другим файлом процедурой CloseFile, но об этом ниже. Теперь необходимо открыть файл, причем одним из нескольких способов, в зависимости от ваших потребностей. Создать новый или перезаписать существующий можно с помощью процедуры Rewrite(F). Открыть для записи в конец файла можно с помощью процедуры Append(F). А открытие файла для чтения осуществляет процедура Reset.

Step 3 - Стандартные I/O опреации с файлами

I/O - это операции ввода/вывода (input/output). Здесь мы рассмотрим запись данных в файл и чтение этих данных. Сначала запись. Записать в файл можно переменную или константу того типа, которого был обьявлен файл. Например если файл был обьявлен вот так F: File of Integer, то в него можно будет записать данные только типа Integer. При попытке записать данные другого типа компилятор выдаст сообщение об ошибке. Запись в файл осуществляется процедурами Write(; P1; [...,Pn]) и WriteLn(; P1; [...,Pn]). Вторая отличается от первой тем, что она после записи параметра перемащает каретку на новую строку, т.е. следующий параметр запишется на новой строке. Вот пример использования процедур:

var F: TextFile;

Str:= "Some Text";

WriteLn(F, Str);

Write(F, "это будет на новой стоке ");

write(F, "а это на этой же строке");

Чтение данных происходит благодоря процедурам Read(; V1; [...,Vn]) и ReadLn(; V1; [...,Vn]). Отличиаются они тем, что после прочтения параметра процедурой ReadLn каретка перемещается на новую строку, даже если ещё были данные. Вот пример:

var F: TextFile;

ReadLn(F, Str2);//str2 будет содержать данные, идущие после str

Read(F, Str3);//str3 будет содержать данные, находящиеся на новой строке после str2

Думаю не все так сложно.

Step 4 - Закрытие файла

Файловую переменную после использования нужно обьязательно освободить, иначе программа не закроется и будет выдавать ошибку. Также освобождение файловой переменной будет полезно тогда, когда вам нужно работать с несколькими файлами последовательно, и после работы с первым файлом можно освободить переменную и связать её с новым файлом. Освобождение файловой перменной делает процедура CloseFile(F: File). Примера я думаю не надо, т.к. никаких особенностей у нее нет.

Я думаю новичку будет все же сложно будет без примеров разобраться в работе с файлами. Поэтому давайте расмотрим простейший пример программы, которая по нажатию одной кнопки будет запрашивать имя файла у пользователя и записывать содержимое TMemo. А по нажатию другой кнопки программа опять же будет запрашивать имя файла, читать от туда записанные данные и помещать их в TMemo. Знаю, что запись и чтение в TMemo можно организовать с помощью специальных методов. Но это всего лишь пример к статье. Вобщем кидайте на форму одну TMemo и две кнопки. Обработчик первой кнопки приведите к такому виду:

procedure TForm1.Button1Click(Sender: TObject);

FileName: String;

AssignFile(F, FileName);

for i:= 0 to Memo1.Lines.Count do

WriteLn(F, Memo1.Lines[i]);

Это кнопка будет сохранять текстовый файл. Итак, в разделе var я обьявил три локальные переменные: F типа TextFile это и есть файловая переменная для текстовых файлов; FileName типа String будет служить для хранения имени файла; И i типа Integer - для циклов. В первой строчке я запрашиваю у пользователя имя файла. Во второй я связываю файловую переменную с физическим файлом на диске. Строчка Rewrite(F) создает новый файл или перезаписывает существующий. ЧТо бы данные не заменялись а добавлялись в конец файла эту строчку нужно заменить на Append(F). Далее идет цикл с 0 до количества всех строк Memo1. В цикле содержимое все строк Memo1 по порядку записывается в файл. Обратите внимание, что я использую WriteLn для записи новой строчки. Если бы я использовал Write, то все строчки Memo1 в файле превратились в одну.

Обработчик второй кнопки должен выглядеть примерно так:

procedure TForm1.Button2Click(Sender: TObject);

FileName, tmp: String;

FileName:= InputBox("Имя файла", "Введите имя файла", "default.txt");

AssignFile(F, FileName);

while not EOF(f) do

Memo1.Lines.Add(tmp);

Назначение локальных переменных в этой процедуре аналогичны предудыщим. Первая и вторая строчка аналогичны строчками из обработчика первой кнопки. Reset(F) - это я открываю файл для чтения процедурой Reset. Далее запускается цикл по всему файлу (while not EOF(F) do). Функция EOF(F: File) возвращает true когда достигнут конец файла. В цикле читается одна строчка из файла в переменную tmp и добавляется в Memo1. Вот и все, думаю довольно просто. Однако программу легко обмануть и вызвать исключение. Например при чтении файла пользователь может задать имя несуществующего файла. Тогда возникнет ошибка. Далее мы поговорим о способах защиты программы от исключений

Способ 1 - Простейший

Конечно простейший, но достаточно эффективный способ защиты можно организовать с помощью вложенных блоков try - except и try - finally. Вы знаете, что если при выполнении инструкции в теле блока try - except происходит исключение, то выполнение дальнейших инструкций останавливается и выполняется то, что находится между except - end. Но если возникло исключение, а далее находится CloseFile(F), то эта процедура не выполняется и программа не сможет корректно работать и завершиться. Решение этой проблемы - использование вложенных try - except и try - finally. Вот пример

MessageDlg("Ошибка работы с файлом", mtError, , 0);

Но этот способ может не сработать, если была попытка открытия несуществующего файла (возникнет искючение при выполнении CloseFile(F)).

Способ 2 - Эффективный

Известно, что программа сама берет на себя обработку исключений. Но она не всегда делает это правильно. Поэтому лучшим решением было бы самому проконтролировать момент открытия файла. Для этого нужно сначала отключить автоматическую обработку исключений директивой {I-}. А включить можно так: {I+}. Потом свериться со значением функции IOResult. При успешном открытии файла она возвращает 0. Вот пример:

if IOResult<>0 then

MessageDlg("Файл "+PChar(FileName)+ " несуществует", mtError, , 0);

EXIT; //продолжать нельзя

Все это вставьте в процедуру чтения файла (в примере выше) вместо строки Reset(F). Так же можно застраховаться от сбоев вставив эту конструкцию в процедуру сохранения файла вместо строки Rewrite.