1

Тема: Файли(Делфі)

Всім доброго дня!
Є програмка - має два поля вводу - Edit1, Edit2, і одну кнопку. Користувач вводе дату та температуру, а програма зберігає його у файл(при цьому якщо файлу не існує, то вона створює його).
Компіляцію пройшла успішно. Хоч файл і створює, але нічого в нього не записує і при закритті програми файл не закриває, а повинно це робити.
Пробував зберігати і в .db i .txt .
Код:

procedure TForm1.FormActivate(Sender: TObject);

const
DBNAME= 'D:\Документы\МОЇ ПРОГРАММИ\Delfi\Вывод у файл(погода)\pogoda.txt';

var
db: TextFile;

begin
AssignFile(db, DBNAME);
{$I-}
Append(db);
If (IOResult=0) then
                    begin
                    Edit1.Text:= DateToStr(Date); // получить текущюю дату
                    Edit2.SetFocus; // перевести курсор в поле температури
                    end
else
    begin
    Rewrite(db);
    If (IOResult<>0) then
                         begin
                         {делаем неактивними поля ввода и кнопку и выводим сообщение}
                         Edit1.Enabled:= False;
                         Edit2.Enabled:= False;
                         Button1.Enabled:= False;
                         ShowMessage('Ошибка создания ' + DBNAME);
                         end;
    end;
end;

procedure TForm1.Button1Click(Sender: TObject);

const
DBNAME= 'D:\Документы\МОЇ ПРОГРАММИ\Delfi\Вывод у файл(погода)\pogoda.txt';

var
db: TextFile;

begin
AssignFile(db, DBNAME);
If (Edit1.Text='') or (Edit2.Text='') then
                                                            ShowMessage('Ошибка ввода!' + #13 + 'Все поля должны быть заполнены.')
else
    writeln(db, Edit1.Text, ' ', Edit2.Text);                                                        
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);

const
DBNAME= 'D:\Документы\МОЇ ПРОГРАММИ\Delfi\Вывод у файл(погода)\pogoda.txt';

var
db: TextFile;

begin
AssignFile(db, DBNAME);
CloseFile(db); // закрываем фаил при закритии формы
end;

Допоможіть, будь ласка.

2

Re: Файли(Делфі)

Навіть не знаю, з чого почати. Для початку почитайте, що роблять функції AssignFile, Append, Rewrite, IOResult. А також що за подія Activate. А, так, і про область дії ідентифікаторів почитайте - чи спробуйте пояснити, чому у вас стільки різних TextFile використовується.

3

Re: Файли(Делфі)

Ось цитати з підручника по якому вчусь:

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

Имя файла задается вызовом процедуры AssignFiie, связывающей файловую переменную с конкретным файлом.

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


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

-добавление в существующий файл.

Для того чтобы открыть файл в режиме создания нового файла или замены существующего, необходимо вызвать процедуру Rewrite(f), где f — файловая переменная типа TextFile.


Для того чтобы открыть файл в режиме добавления к уже существующим данным, находящимся в этом файле, нужно вызвать процедуру Append (f), где f — файловая переменная типа TextFile.

Программа может взять на себя задачу контроля за результатом выполнения инструкции открытия файла. Сделать это можно, проверив значение функции IOResult (input-Output Result — результат ввода/вывода). Функция IOResuit возвращает 0, если операция ввода/вывода завершилась успешно; в противном случае — код ошибки (не ноль).

Для того чтобы программа смогла проверить результат выполнения операции ввода/вывода, нужно разрешить ей это делать. Для этого надо перед инструкцией вызова процедуры открытия файла поместить директиву компилятору — строку {$I-}, которая запрещает автоматическую обработку ошибок ввода/вывода. Эта директива сообщает компилятору, что программа берет на себя контроль ошибок. После инструкции открытия файла следует поместить директиву {$I+}, восстанавливающую режим автоматической обработки ошибок ввода/вывода.

Що робе подія, але не в цій программі.

Ячейки первой зафиксированной строки таблицы используются в качестве заголовков колонок таблицы. Во время создания формы приложения нельзя установить значения элементов массива cells, т. к. элементы массива доступны только во время работы программы. Поэтому значения элементов массива Сells, соответствующих первой строке таблицы, устанавливаетпроцедура обработки события OnActivate (ее текст приведен в листинге 5.11), которое происходит во время активизации формы приложения. Кроме того, эта процедура вписывает в первую колонку таблицы названия стран-участниц соревнований.

---------------------
Щодо області дії індетифікаторів - потрібно було перед всіма процедурами оголосити DBNAME i db?
---------------------
Ось код цієї ж програми, але з підручника(за відступи вибачаюсь - але саме такі вони в підручнику):

unit pogoda_;


interface


uses


Windows, Messages, SysUtils, Variants, Classes,

Graphics, Controls, Forms, Dialogs, StdCtrls;


type


TForm1 = class(TForm)


Edit1: TEdit; // дата 


Edit2: TEdit; // температура 


Button1: TButton; // кнопка Добавить 


Label1: TLabe1;


Label2: TLabe1;


procedure FormActivate(Sender: TObject);


procedure ButtonlClick(Sender: TObject);


procedure FormClose(Sender: TObject;

var Action: TCloseAction); private


{ Private declarations } public


{ Public declarations } end;


var


Form1: TForm1;


implementation

{$R *.dfm}

const
DBNAME = 'a:\pogoda. db';
var
db: TextFile; // файл — база данных 
procedure TForm1.FormActivate(Sender: TObject); 
begin
AssignFile(db, DBNAME);. {$I-}
Append(db); if IOResult = 0 then
begin
Edit1.Text := DateToStr(Date); // получить текущую дату 
Edit2.SetFocus; // курсор в поле Edit2 
end
else begin
Rewrite(db); if IOResult <> 0 then begin
// сделать недоступными поля ввода // и командную кнопку 
Edit1.Enabled := False; Edit2.Enabled := False; 
Buttonl.Enabled := False; ShowMessage('Ошибка создания '+DBNAME);
end; 
end;
end;
// щелчок на кнопке Добавить 
procedure TForml.Button1Click(Sender: TObject);
begin
if (Length(edit1.text)=0) or (Length(edit2.text)=0)
then ShowMessage('Ошибка ввода данных.'
+#13+'Bce поля должны быть заполнены.')
else writeln(db, editl.text,' ',edit2.text); 
end;
// Событие OnClose возникает при закрытии формы 
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
CloseFile(db); // закрыть файл БД 
end;
end.

4

Re: Файли(Делфі)

Чудово. То, може, знайдете відмінності між своїм кодом і кодом з підручника?

5

Re: Файли(Делфі)

Потрібно винести

const
DBNAME= 'D:\Документы\МОЇ ПРОГРАММИ\Delfi\Вывод у файл(погода)\pogoda.txt';
 
var
db: TextFile;


в головну программу - за межі процедур?
А функцію AssignFile використати тільки тут:

procedure TForm1.FormActivate(Sender: TObject);

begin
AssignFile(db, DBNAME);

Зробив так - до файлу записи робе, але тільки після закриття програми.

------
Ще десь помилка? Я чогось не помітив?
------
Код оновленої програми:

implementation

{$R *.dfm}

const
DBNAME= 'D:\Äîêóìåíòû\Ìί ÏÐÎÃÐÀÌÌÈ\Delfi\Âûâîä ó ôàéë(ïîãîäà)\pogoda.db';

var
db: TextFile;

procedure TForm1.FormActivate(Sender: TObject);

begin
AssignFile(db, DBNAME);
{$I-}
Append(db);
If (IOResult=0) then
                    begin
                    Edit1.Text:= DateToStr(Date); // ïîëó÷èòü òåêóùþþ äàòó
                    Edit2.SetFocus; // ïåðåâåñòè êóðñîð â ïîëå òåìïåðàòóðè
                    end
else
    begin
    Rewrite(db);
    If (IOResult<>0) then
                         begin
                         {äåëàåì íåàêòèâíèìè ïîëÿ ââîäà è êíîïêó è âûâîäèì ñîîáùåíèå}
                         Edit1.Enabled:= False;
                         Edit2.Enabled:= False;
                         Button1.Enabled:= False;
                         ShowMessage('Îøèáêà ñîçäàíèÿ ' + DBNAME);
                         end;
    end;
end;

procedure TForm1.Button1Click(Sender: TObject);

begin
If (Edit1.Text='') or (Edit2.Text='') then
                                                            ShowMessage('Îøèáêà ââîäà!' + #13 + 'Âñå ïîëÿ äîëæíû áûòü çàïîëíåíû.')
else
    writeln(db, Edit1.Text, ' ', Edit2.Text);                                                        
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
CloseFile(db); // çàêðûâàåì ôàèë ïðè çàêðèòèè ôîðìû
end;

6

Re: Файли(Делфі)

A.N.Onim написав:

Потрібно винести

const
DBNAME= 'D:\Документы\МОЇ ПРОГРАММИ\Delfi\Вывод у файл(погода)\pogoda.txt';
 
var
db: TextFile;


в головну программу - за межі процедур?

Головне - щоб файл був один і той самий. Втім, краще оголошувати не глобальні змінні, а всередині класу.

A.N.Onim написав:

А функцію AssignFile використати тільки тут:

procedure TForm1.FormActivate(Sender: TObject);

begin
AssignFile(db, DBNAME);

Тобто ви так і не прочитали, що то за подія - Activate.

A.N.Onim написав:

Зробив так - до файлу записи робе, але тільки після закриття програми.
------
Ще десь помилка? Я чогось не помітив?

Це не помилка, це нормальна поведінка системи: запис до файлу - процедура довга (стандартний диск робить 7200 обертів на хвилину - самі порахуйте, скільки це в герцах, а доки диск потрібним місцем не прокрутиться, дані не будуть записані), тому для прискорення система (точніше, це робиться в кілька "каскадів", спершу бібліотекою вводу-виводу Delphi, потім системою, вже мовчу про кеші) накопичує дані в буфері, а потім записує - наприклад, при закритті файлу. Щоб примусово зкинути буфери на диск, треба викликати процедуру

Flush(db);
Подякували: A.N.Onim1

7

Re: Файли(Делфі)

І ще - раджу вам якщо не змінити підручник, то хоча б знайти і прочитати ще один. Бо цей... неякісний.

Подякували: A.N.Onim1

8 Востаннє редагувалося A.N.Onim (22.08.2013 14:46:00)

Re: Файли(Делфі)

koala написав:

Тобто ви так і не прочитали, що то за подія - Activate.

Знайду в Інтернеті і обов'язково прочитаю. Дякую.

koala написав:

Щоб примусово зкинути буфери на диск, треба викликати процедуру

 Flush(db);

Прочитаю і про неї.

koala написав:

І ще - раджу вам якщо не змінити підручник, то хоча б знайти і прочитати ще один. Бо цей... неякісний.

Дякую. Але шукаючи в Інтернеті знаходив або цей або вже не для початківців.  :(

9

Re: Файли(Делфі)

Читав цей підручник - там вроді як і розжовують, але в коді дуже багато помилок(може й спеціально так, щоб читач сам думав, а не тупо копі-паст  *SCRATCH* ).
А щодо хорошого підручника - то це мабуть рідний Help (в делфі 7 він якийсь більш зручніший, аніж в нових версіях, в тій же XE), статті на блогах, форуми(такі як наш).

Тут мала би бути якась влучна фраза(вибачте, що витратив кілька секунд вашого часу на прочитання).

10

Re: Файли(Делфі)

DOP написав:

А щодо хорошого підручника - то це мабуть рідний Help (в делфі 7 він якийсь більш зручніший, аніж в нових версіях, в тій же XE), статті на блогах, форуми(такі як наш).

А щодо блогів - знаєте якісь для новачків та не нудні?

11

Re: Файли(Делфі)

@A.N.Onim
Щоб не було нудно - робіть якийсь проект.

Бодай вас Бог любив, а мене – молодиці!

12

Re: Файли(Делфі)

Очі.завидющі написав:

@A.N.Onim
Щоб не було нудно - робіть якийсь проект.

Не зрозумів. Який проект? Про Делфі?
Детальніше, буль ласка.

13

Re: Файли(Делфі)

A.N.Onim написав:
Очі.завидющі написав:

@A.N.Onim
Щоб не було нудно - робіть якийсь проект.

Не зрозумів. Який проект? Про Делфі?
Детальніше, буль ласка.

Я думаю, що він має на увазі Вам взятись за якийсь проект, тобто, взяти собі за мету зробити якийсь софт чи таке, що буде:

  • цікавим Вам

  • принесе багато практичних навичок

  • можливо навіть і стане основою для вдосконалень, та подальшого вивчення

Тут мала би бути якась влучна фраза(вибачте, що витратив кілька секунд вашого часу на прочитання).
Подякували: Очі.завидющі, A.N.Onim2

14 Востаннє редагувалося A.N.Onim (24.08.2013 11:01:20)

Re: Файли(Делфі)

Цікаво... Гм...
Але спочатку напевне потрібно ще  хоча б закінчити вивчення по підручнику.

15

Re: Файли(Делфі)

Читав про головні події створення та закриття форми.

koala написав:

Тобто ви так і не прочитали, що то за подія - Activate.

Ви мали на увазі що код розміщений мною в процедурі Activate краще розмістити у процедурі Create ?
Бо перша подія виникає при переведенні фокусу на дану форму.
Чи я знову не зрозумів?

Подякували: koala1

16

Re: Файли(Делфі)

У вас немає процедури Activate. Я теж необережно з назвами поводився, визнаю.
Треба розміщувати код в обробнику події OnCreate (стандартно FormCreate, якщо не помиляюся). Create - це конструктор, це зовсім інша історія.

17

Re: Файли(Делфі)

Дякую.