Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lab7_new.doc
Скачиваний:
3
Добавлен:
20.08.2019
Размер:
213.5 Кб
Скачать

7. Пример реализации приложения

Пусть требуется хранить следующую информацию о лицах: Фамилия, Имя, Возраст. Запрос: подсчитать средний возраст всех лиц.

Создадим новый проект приложения. На главной форме (назовем ее Main – в свойстве Name) разместим компонент MainMenu с пунктами: «Файл» (Открыть, Сохранить, Сохранить как…, Выход), и «Поиск». Также разместим StringGrid и кнопки «Добавить», «Удалить», «Изменить».

Настроим компонент StringGrid. Свойство FixedRow = 1 (фиксированное число строк для заголовков), FixedCols = 0, ColCount = 4 (Количество столбцов - Фамилия, Имя, Пол, Возраст). В составном свойстве Options установим goEditing = False (запретим ручное редактирование в таблице), goRowSelect = True (разрешим выделение всей строки).

Кнопки «Изменить» и «Добавить» первоначально сделаем недоступными (свойство Enabled = False).

Главная форма на этапе проектирования приложения представлена на рис. 1.

Рис. 1. Главная форма на этапе проектирования

С событием OnShow для формы свяжем следующий код:

procedure TMain.FormShow(Sender: TObject);

begin

//Задаем заголовки столбцов

StringGrid1.Cells[0,0]:='Фамилия';

StringGrid1.Cells[1,0]:='Имя';

StringGrid1.Cells[2,0]:='Пол';

StringGrid1.Cells[3,0]:='Возраст';

Kol:=0;

Nomer:=1;

end;

После запуска приложения (F9) форма примет следующий вид (рис.2):

Рис. 2. Главная форма на этапе выполнения приложения

Опишем необходимые переменные в модуле главной форме (Unit1).

Type

Zap = Record //описание записи

Fam: String[20];

Name: String[15];

Pol: Char;

Age: 18..60;

End;

Var

F: File of Zap; //описание типизированного файла

Rec: Zap;

Nomer: Integer; //номер редактируемой строки

I: integer;

Kol: integer; // количество записей

S: integer; // сумма всех возрастов

Sr: Real; //средний возраст

add: boolean;//признак нажатия кнопки «Добавить»

Для доступа к конкретному элементу записи используется следующая конструкция:

Zap.Fam:=’Иванов’;

Или с оператором присоединения (With):

With Zap do

begin

Fam:=’Сидоров’;

Name:=’Сидор’;

Pol:=’м’;

Age:=20;

end;

При нажатии кнопок «Добавить» и «Изменить» должно открываться окно для добавления/редактирования записи (назовем его EditRecord). Свойство BorderStyle (рамка формы) желательно установить равным bsDialog.

Компоненты ввода связываются с конкретными полями записи. Разместим на форме Label, Edit, SpinEdit (страница Samples) RadioGroup, две кнопки.

Пример формы ввода/корректировки (рис. 3):

Рис. 3. Форма редактирования на этапе проектирования приложения

Для компонента SpinEdit, содержащего информацию о возрасте, установим максимальное (MaxValue=60) и минимальное значение (MinValue=18), Value = 18 (текущее значение), EditorEnabled = False (значение будет только выбираться).

Для компоненты RadioGroup зададим свойства Caption, Items («мужской» и «женский» – должны располагаться в разных строках), ItemIndex = 0 (включенный переключатель. Нумерация с нуля. Значение «-1» означает, что никакой переключатель не выбран). Можно также использовать компонент ComboBox.

Если в главной форме была нажата кнопка «Добавить», то все элементы ввода должны очиститься, если «Изменить» - заполниться значениями изменяемой записи.

Реакция на нажатие кнопки «Добавить»:

procedure TMain.Button1Click(Sender: TObject);

begin

Edit_Record.Caption:='Добавление записи';//Меняем заголовок

add:=true;

Edit_Record.ShowModal;//Вызываем форму Edit_Record

end;

Реакция на нажатие кнопки «Изменить»:

procedure TMain.Button2Click(Sender: TObject);

begin

Edit_Record.Caption:='Изменение записи';//Меняем заголовок

add:=false;

Edit_Record.ShowModal;//Вызываем форму Edit_Record

end;

При отображении формы Edit_Record сделаем необходимые действия (для события OnShow):

procedure TEdit_Record.FormShow(Sender: TObject);

begin

if add=true then //была нажата кнопка "Добавить"

begin

//Очищаем поля ввода

Edit_Record.Edit1.Text:='';

Edit_Record.Edit2.Text:='';

//Задаем значения по умолчанию

Edit_Record.SpinEdit1.Value:=18;

Edit_Record.RadioGroup1.ItemIndex:=0;

end else //нажали кнопку "Изменить"

begin

//необходимо занести поля выделенной записи в элементы ввода

Edit1.Text:=Main.StringGrid1.Cells[0,Nomer];

Edit2.Text:=Main.StringGrid1.Cells[1,Nomer];

SpinEdit1.Value:=StrToInt(Main.StringGrid1.Cells[3,Nomer]);

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

if Main.StringGrid1.Cells[2,Nomer]='м' then

RadioGroup1.ItemIndex:=0 else RadioGroup1.ItemIndex:=1;

end;

end;

Реакция на нажатие кнопки «ОК» на форме редактирования Edit_Record:

procedure TEdit_Record.Button1Click(Sender: TObject);

var d:integer;

begin

//добавляем в таблицу строку, если была нажата кнопка "Добавить"

if add then

begin

Kol:=Kol+1;

Main.StringGrid1.RowCount:= Kol+1;

d:=Kol;

if kol>0 then begin

//Делаем доступными кнопки "Изменить" и "Удалить"

Main.Button2.Enabled:=True;

Main.Button3.Enabled:=True;

end;

end else d:=Nomer;

//Заносим введенные значения в таблицу

Main.StringGrid1.Cells[0,d]:=Edit1.Text;

Main.StringGrid1.Cells[1,d]:=Edit2.Text;

Main.StringGrid1.Cells[3,d]:=IntToStr(SpinEdit1.Value);

//IntToStr - преобразует целое значение в строковое

if RadioGroup1.ItemIndex=0 then Main.StringGrid1.Cells[2,d]:='м'

else Main.StringGrid1.Cells[2,Kol]:='ж';

Close;//Закрываем форму редактирования

end;

Реакция на нажатие кнопки «Отмена» на форме редактирования Edit_Record:

procedure TEdit_Record.Button2Click(Sender: TObject);

begin

Close;//закрываем форму

end;

В событии OnSelectCell для StringGrid, которое возникает при выборе строки таблицы, сохранить номер строки:

procedure TMain.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;

var CanSelect: Boolean);

begin

Nomer:=Arow; {сохраняем номер выделенной строки}

end;

Реакция на нажатие кнопки «Удалить»:

procedure TMain.Button3Click(Sender: TObject);

begin

if Kol<>0 then

BEGIN

for i:=Nomer to StringGrid1.RowCount-1 do

with StringGrid1 do begin

//сдвигаем строки

cells[0,i]:= cells[0,i+1];

cells[1,i]:= cells[1,i+1];

cells[2,i]:= cells[2,i+1];

cells[3,i]:= cells[3,i+1];

end;

Kol:=Kol-1;

if Kol<>0 then StringGrid1.RowCount:= Kol+1 else

begin

//Делаем недоступными кнопки "Изменить" и "Удалить"

Button2.Enabled:=False;

Button3.Enabled:=False;

end;

end;

end;

Теперь опишем сохранение и открытие файла записей. Для отображения стандартных диалоговых окон сохранения/открытия будем использовать компоненты SaveDialog и OpenDialog со страницы Dialogs, которые разместим на главной форме. В свойство Filter установим «Файл данных|*.dat». Умалчиваемое расширение файлов (DefaultExt) – «dat». В свойстве InitialDir можно задать начальный диск/каталог для открытия/сохранения файла.

Данные компоненты являются невизуальными (т.е. не отображаются при запуске приложения).

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

AssignFile(F, FileName) – связывает файл FileName с файловой переменной F.

Reset(F) – открывает файл F для чтения.

RewriteFile(F) – создает новый файл F. Если создаваемый файл уже имеется, перезаписывает его.

Read(F, V1, V2, …) – чтение данных из файла F в переменные.

Write(F, V1, V2, ...) – запись значений переменных в файл F.

Seek(F, N:LongInt) – передвигает указатель файла на N-ю компоненту (N-целое выражение). Первая компонента имеет номер 0. Для того, чтобы расширить файл, следует передвинуть указатель в конец файла функцией Seek.

Seek (F, FileSize(F)) – возвращает число записей в файле F, то есть указывает номер следующей компоненты после последней.

CloseFile(F) – закрывает файл F.

DeleteFile(F) – удаляет файл F.

RenameFile(OldName, NewName) – переименовывает файл OldName на NewName.

Реакция на выбор пункта меню «Открыть»:

procedure TMain.N3Click(Sender: TObject);

var i:integer;

begin

if Opendialog1.Execute //если диалог выполнился

and FileExists(OpenDialog1.FileName) then //выбранный файл существует

begin

//связываем имя файла с файловой переменной

AssignFile(f,OpenDialog1.FileName);

Reset(f); //открываем файл

i:=0; //номер строки

while not eof(f) do begin //пока не конец файла

read(f,Rec); //читаем очередную запись

inc(i);

stringgrid1.cells[0,i]:=Rec.Fam;

stringgrid1.cells[1,i]:=Rec.Name;

stringgrid1.cells[2,i]:=Rec.Pol;

stringgrid1.cells[3,i]:=IntToStr(Rec.Age);

stringgrid1.RowCount:=i+1; //Увеличиваем количество строк

end;

kol:=i; //сохраняем прочитанное количество строк

closefile(f);//закрываем файл

end else ShowMessage('Файл не существует!')

end;

Реакция на выбор пункта меню «Сохранить»:

procedure TMain.N5Click(Sender: TObject);

var i:integer;

begin

if SaveDialog1.Execute then //если диалог выполнился

begin

assignfile(f,savedialog1.FileName);//связь файла с переменной

if FileExists(SaveDialog1.FileName) then

begin

if MessageDlg('Файл с таким именем уже существует. Перезаписать?', mtConfirmation,[mbYes,mbNo],0)=mrNo then exit; //Выход

end;

rewrite(f,savedialog1.FileName); //создание файла

i:=0;

while i<>StringGrid1.rowCount-1 do begin //пока I <>кол-ву строк

inc(i);//увеличиваем счетчик прочитанных строк

Rec.Fam:=stringgrid1.cells[0,i];

Rec.Name:=stringgrid1.cells[1,i];

Rec.Pol:=stringgrid1.cells[2,i][1];

Rec.Age:=StrToInt(stringgrid1.cells[3,i]);

write(f,Rec); //сохраняем строку в файл

end;

closefile(f); //закрываем строку

end;

end;

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

procedure TMain.N8Click(Sender: TObject);

begin

S:=0;

i:=0;

if Kol<>0 then

while i<>StringGrid1.RowCount-1 do

begin //пока I <>количеству строк

inc(i);//увеличиваем счетчик прочитанных строк

S:=S+StrToInt(stringgrid1.cells[3,i]);//суммируем возраст

end;

Sr:=S/I;

ShowMessage('Средний возраст='+FloatToStrF(Sr,ffGeneral,10,3));

end;

Если запрос должен возвращать несколько строк результата, то их можно отобразить на отдельной форме в StringGrid или заносить в ListBox/Memo (методы Clear – очищает список, Lines.Add (строка) – добавляет новую строку)

Рис. 4. отображает пример работающего приложения.

Рис. 4. Окно работающего приложения

На рис. 5 представлен результат запроса.

Рис. 5. Выдача сообщения с результатом запроса

15

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]