Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЭКТ / БДлаб7.doc
Скачиваний:
28
Добавлен:
16.04.2013
Размер:
478 Кб
Скачать

Свойства пунктов главного и дополнительных меню

Caption

Name

Shortcut

Регистрация

mmRegistrate

Таблицы

mmTables

Отчеты

mmReports

Справка

mmHelp

Житель

mmEditPerson

F5

Квартира

mmEditFlat

F6

Телефон

mmEditPhone

F7

Вид дохода

mmEditProfit

F8

-

mmDelimiter

Вы&ход

mmExit

F10

&Жители

mmShowPersons

Окончание

Caption

Name

Shortcut

&Квартиры

mmShowFlats

&Телефоны

mmShowPhones

&Виды доходов

mmShowProfits

Входные формы

mmInitData

Список жителей

mmPersonProfits

Таблица доходов

mmProfitsTable

Список видов доходов

mmProfits

Этикетки

mmLabels

О системе

mmAboutSys

F1

Примечание. При выборе значения свойства Name для компонента рекомендуется начинать значение двухсимвольным префиксом, обозначающим тип компонента. Например, fm - для компонента типа Form, mm - MainMenu, sp - SpeedButton, la - Label, de - DBEdit, te - DBText, ta - Table, ds - DataSource, bu - Button, dc - DBComboBox, lc - DBLookupCombo, na - DBNavigator, gr - DBGrid, qu - Query и т.д.

Предусмотрим процедуру обработки события, связанного с выбором пункта меню Выход. Для этого нужно щелкнуть на пункте меню Выход и в активизированном окне текстового редактора, начиная с позиции, отмеченной курсором, набрать оператор, вызывающий метод Close для главной формы fmMAINFORM. В результате этих действий создается процедура, приведенная на листинге 1. Эта процедура будет вызываться при выборе пункта меню Выход либо при нажатии функциональной клавиши F10 или клавиши х (русская буква "ха"), когда отображается дополнительное меню.

Листинг 1. Процедура обработки события, связанного с выбором пункта меню Выход

procedure TfmMAINFORM.mmExitClick (Sender: Tobject);

begin

fmMAINFORM.Close; {это набрал разработчик}

end;

Чтобы создать панель быстрого доступа, нужно расположить компонент Panel под главным меню, разместить на нем четыре компонента SpeedButton и задать для них значения свойств Name (имя кнопки), Glyph (файл с рисунком), Hint (текст подсказки), ShowHint=True (табл.3). Файлы с рисунками для кнопок находятся в каталоге F:\Program Files\Common Files\Borland Shared\ Images\Buttons.

Таблица 3

Свойства компонентов SpeedButton

Name

Glyph

Hint

sbNewPerson

picture.bmp

Регистрация жителя

sbNewFlat

doorshut.bmp

Регистрация квартиры

sbNewPhone

phone.bmp

Регистрация телефона

sbNewProfit

many2one.bmp

Регистрация вида дохода

Поместим в главную форму компонент DataBase, для которого установим значения свойств AliasName=TUTOR_DATABASE (выбирается из выпадающего списка) и DatabaseName=dbTUTOR.

Сохраним в каталоге D:\DELPHI\PROGRAM созданный проект прикладной системы, выбрав команду File|Save Project As и задав имя MAINFORM для файла с модулем главной формы (.pas) и имя PERSPROF для файла с проектом (.dpr).

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

Создание формы fmABOUTSYS. Эта форма создается на базе стандартного шаблона About box, выбираемого на закладке Forms в окне New Items, которое активизируется командой File|New. После включения шаблона в проект его нужно настроить, дополнив необходимыми компонентами, и подключить к пункту меню О системе.

Настройка шаблона начинается заданием значений свойств Name=fmABOUTSYS и Caption=О системе. Далее в форме fmABOUTSYS нужно исправить значения свойства Caption четырех компонентов Label, чтобы они соответствовали эскизу, показанному на рис.6, а у компонента Image установить свойство Picture, загрузив файл finance.bmp из каталога F:\DELPHI\SPLASH\256color.

Сохраним в каталоге D:\DELPHI\PROGRAM дополненный проект, выбрав команду File|Save Project и задав имя ABOUTSYS для файла с модулем формы fmABOUTSYS.

Созданную форму необходимо связать с пунктом меню в главной форме. Для этого после щелчка на пункте меню О системе в окне текстового редактора набирается оператор fmABOUTSYS.ShowModal, выполнение которого активизирует форму fmABOUTSYS, а в начале раздела Implementation модуля MAINFORM записывается предложение

uses ABOUTSYS;

Создание формы fmEDITFLAT. Выберем команду File|New Form, чтобы включить в проект пустую форму.

Поместим в эту форму пять компонентов Label для отображения поясняющего текста, три компонента DBEdit, два компонента Button и по одному компоненту DBComboBox и DBNavigator, расположив их так, как показано на рис.7. Поместим также на любое свободное место в форме компоненты Table и DataSource.

Зададим значение свойства Name формы равным fmEDITFLAT и значения свойств других компонентов согласно табл.4.

Таблица 4

Свойства компонентов, расположенных на форме fmEDITFLAT

Name

Caption

Name

Старое

Новое

Старое

Новое

Label1

laAddress

Адрес

DBEdit1

deAddress

Label2

laSkv

Площадь квартиры

DBEdit2

deSkv

Label3

laNrooms

Число комнат

DBEdit3

deNrooms

Label4

laKCategory

Категория квартиры

DBComboBox1

dcKCategory

Label5

laKvm

Кв.м.

Table1

taFLAT

Button1

buExit

Выход

DataSource1

dsFlat

Button2

buCancel

Отмена

DBNavigator1

naFLAT

Name

DatabaseName

Table Name

DataSet

Data Source

DataField

Visible Buttons

taFLAT

dbTUTOR

FLAT.DB

dsFLAT

taFLAT

naFLAT

dsFLAT

nbFirst, nbPrior,

nbNext, nbLast

deAddress

dsFLAT

Address

deSkv

dsFLAT

Skv

deNrooms

dsFLAT

NRooms

dcKCategory

dsFLAT

KCategory

Для компонента taFLAT последним устанавливается значение свойства Active=True.

Для кнопки Выход установим значение свойства Default=True, чтобы она реагировала на нажатие клавиши Enter, а для кнопки Отмена - значение свойства Cancel=True, чтобы она реагировала на нажатие клавиши Esc.

Компонент dcKCategory позволяет задавать значение поля (атрибута) KCategory нажатием на клавиатуре клавиш со стрелками или выбором одного из допустимых значений, предусмотренных в списке, который появляется при нажатии на кнопку со стрелкой. Список допустимых значений определяется свойством Items этого компонента. Для создания или проверки списка нужно дважды щелкнуть на свойстве Items, чтобы появилось окно String List Editor, в котором набираются строки, содержащие допустимые значения поля KCategory:

П

Н

К

Форма fmEDITFLAT используется как в режиме ввода, так и в режиме редактирования. Для задания режима необходимо предусмотреть признак Editing, объявив его в разделе public класса TfmEDITFLAT как Editing : Boolean. Editing=True, если форма используется в режиме редактирования; Editing=False, если форма используется в режиме ввода. Этот признак должен устанавливаться перед активацией формы.

Вывод полей записи в режиме редактирования можно обеспечить, зная значение первичного ключа этой записи. Для таблицы taFLAT таким ключом служит поле Adr. Перед активизацией формы в режиме редактирования значение первичного ключа нужной записи необходимо сохранить в признаке KeyValue, который следует объявить в разделе public класса TfmEDITFLAT как KeyValue : String. Тип признака KeyValue соответствует типу ключевого поля Adr.

При активизации формы происходит событие OnActivate, процедура обработки которого должна анализировать признак Editing и настраивать форму на заданный режим работы. Текст этой процедуры приведен на листинге 2.

Листинг 2. Процедура обработки события OnActivate

procedure TfmEDITFLAT.FormActivate(Sender: TObject);

begin

if Editing then

begin

Caption := 'Изменение сведений о квартире';

naFLAT.Enabled:=True; {Навигатор доступен}

with taFLAT do

begin

DisableControls;

First; SetKey;

FieldByName('Adr').AsString := KeyValue;

GotoKey; {Поиск записи по ключу}

EnableControls;

Edit; {Режим редактирования}

end;

end

else

begin

Caption := 'Регистрация сведений о квартире';

naFLAT.Enabled:=False; {Навигатор не доступен}

taFLAT.Append; {Режим дополнения}

end;

end;

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

Листинг 3. Процедуры обработки событий OnClick для кнопок Выход и Отмена

procedure TfmEDITFLAT.buExitClick(Sender: TObject);

begin

with taFLAT do

begin

if (State in [dsEdit,dsInsert]) and Modified then

Post;{Сохранить изменения, если действует режим}

end;{редактирования/дополнения и запись изменялась}

KeyValue := {Запомнить значение ключа для fmSHOWFLAT}

taFLAT.FieldByName('Adr').AsString;

fmEDITFLAT.Close;

end;

procedure TfmEDITFLAT.buCancelClick(Sender: TObject);

begin

taFLAT.Cancel; {Отменить изменения}

fmEDITFLAT.Close;

end;

На этом создание формы fmEDITFLAT завершается. Остается связать ее с пунктом меню Квартира в главной форме и кнопкой на панели быстрого доступа.

Сохраним сделанные в проекте изменения командой File|Save Project, задав имя EDITFLAT для файла с модулем формы fmEDITFLAT, и перейдем в окно главной формы.

Для связи формы fmEDITFLAT с главной формой нужно щелкнуть на пункте меню Квартира и в окне текстового редактора набрать два оператора, показанные на листинге 4, а предложение uses ABOUTSYS дополнить именем модуля EDITFLAT.

Листинг 4. Процедура вывода формы fmEDITFLAT в режиме ввода

procedure TfmMAINFORM.mmEditFlatClick(Sender: TObject);

begin

fmEDITFLAT.Editing:=False; {Задать режим ввода}

fmEDITFLAT.ShowModal; {Активизировать форму}

end;

Эти же операторы должны выполняться при нажатии кнопки sbNewFlat, поэтому в качестве процедуры обработки события OnClick для этой кнопки зададим процедуру mmEditFlatClick, приведенную на листинге 4. Для этого нужно в главной форме щелкнуть на строке события OnClick, щелчком на кнопке со стрелкой вызвать список имен процедур обработки событий и выбрать имя mmEditFlatClick.

Сохранив изменения командой File|Save Project, можно проверить работоспособность проекта, осуществив активизацию созданной формы из меню или кнопкой на панели быстрого доступа и убедившись в правильном функционировании формы fmEDITFLAT.

Аналогичным способом создаются две другие формы типа ввод/редактирование: fmEDITPHON и fmEDITPROF.

Создание формы fmSHOWFLAT. Выберем команду File|New Form, чтобы включить в проект пустую форму.

Поместим в эту форму три компонента Button и по одному компоненту DBGrid и DBNavigator, расположив их так, как показано на рис.8. Поместим также на любое свободное место в форме компоненты Table и DataSource.

Зададим для формы значения свойств Name=fmSHOWFLAT, Caption=Сведения о квартирах. Значения свойств других компонентов установим в соответствии с табл.5 и 6.

Таблица 5

Значения свойств компонентов Button

Name

Caption

Default

Старое

Новое

Button1

buEdit

&Изменить сведения

False

Button2

buAppend

&Новая квартира

False

Button3

buExit

Выход

True

Таблица 6

Значения свойств компонентов, связанных с данными

Свойство

Table1

DataSource1

DBGrid1

DBNavigator1

Name

taFLAT

dsFLAT

grFLAT

naFLAT

DatabaseName

dbTUTOR

TableName

FLAT.DB

DataSet

taFLAT

DataSource

dsFLAT

dsFLAT

ReadOnly

True

VisibleButtons

[nbFirst, nbPrior, nbNext, nbLast]

Active

True

Для трех кнопок, помещенных в форму, следует задать процедуры обработки события OnClick: при нажатии кнопки Изменить сведения должна активизироваться форма fmEDITFLAT в режиме редактирования строки (записи), отмеченной в сетке треугольником; при нажатии кнопки Новая квартира должна активизироваться форма fmEDITFLAT в режиме ввода; при нажатии кнопки Выход форма fmSHOWFLAT должна деактивизироваться. Тексты процедур приведены на листинге 5.

Листинг 5. Процедуры обработки события OnClick для кнопок

procedure TfmSHOWFLAT.buEditClick(Sender: TObject);

begin

fmEDITFLAT.Editing :=True; {Режим редактирования}

fmEDITFLAT.KeyValue:= {Запомнить значение ключа}

taFLAT.FieldByName('Adr').AsString;

fmEDITFLAT.ShowModal; {Активизировать форму}

Synchronize;

end;

procedure TfmSHOWFLAT.buAppendClick(Sender: TObject);

begin

fmEDITFLAT.Editing:=False; {Режим ввода}

fmEDITFLAT.ShowModal; {Активизировать форму}

Synchronize;

end;

procedure TfmSHOWFLAT.buExitClick(Sender: TObject);

begin

fmSHOWFLAT.Close; {Деактивизировать форму}

end;

Чтобы признаки Editing и KeyValue стали доступными для установки, в начале раздела Implementation модуля записывается предложение

uses EDITFLAT;

Чтобы изменения в таблице taFLAT, сделанные при работе с формой fmEDITFLAT, синхронно отображались в форме fmSHOWFLAT, при возврате в нее в процедурах buEditClick и buAppendClick вызывается процедура Synchronize, показанная на листинге 6. Текст этой процедуры помещается в конце модуля перед словом end, а в разделе private класса TfmSHOWFLAT записывается заголовок процедуры

procedure Synchronize;

Листинг 6. Процедура синхронизации отображения информации в формах fmEDITFLAT и fmSHOWFLAT

procedure TfmSHOWFLAT.Synchronize;

begin

with taFLAT do

if fmEDITFLAT.KeyValue<>'' then

begin {Синхронизация отображения информации}

DisableControls;

First;

SetKey;

FieldByName('Adr').AsString :=

fmEDITFLAT.KeyValue;

GotoKey; {Поиск записи по ключу}

EnableControls;

end

else First;

end;

Для улучшения пользовательского интерфейса предусмотрим, чтобы при двойном щелчке на выбранной строке компонента grFLAT происходила активизация формы fmEDITFLAT в режиме редактирования, т.е. реакция была такой же, как при нажатии кнопки Изменение сведений. Нужную реакцию можно задать, если в форме fmSHOWFLAT выбрать компонент grFLAT, затем в инспекторе объектов на странице событий выбрать строку события OnDblClick, нажать в этой строке кнопку со стрелкой и из появившегося списка имен процедур обработки событий выбрать имя buEditClick.

Сохраним сделанные в проекте изменения командой File|Save Project, задав имя SHOWFLAT для файла с модулем формы fmSHOWFLAT, и перейдем в окно главной формы.

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

fmSHOWFLAT.ShowModal;

а предложение uses ABOUTSYS,EDITFLAT дополнить именем модуля SHOWFLAT.

Сохранив изменения командой File|Save Project, проверим работоспособность проекта, активизировав созданную форму из меню, а форму fmEDITFLAT - с помощью кнопок Изменение сведений, Новая квартира и двойным щелчком в строке сетки grFLAT. Убедившись, что все созданные формы взаимодействуют правильно, перейдем к доработке внешнего вида сетки, чтобы он соответствовал эскизу, показанному на рис.8.

С каждым компонентом Table ассоциируется набор полей, обозначаемый в системе Delphi термином DataSet (рис.10).

По умолчанию набор полей формируется динамически, когда таблица открывается установкой значения свойства Active=True, и очищается, когда закрывается при задании значения свойства Active=False. При динамическом формировании набора полей в него добавляются описания всех полей (атрибутов) для находящейся в базе данных на диске таблицы, которая связана с компонентом Table через значение свойства TableName. Описание поля - объект типа TField. Значения полей, описанных в DataSet, передаются визуальным компонентам приложения с помощью компонента DataSource, который связан c компонентом Table через значение свойства DataSet.

Информационная цепочка тянется следующим образом (см. рис.10): данные из таблицы БД на диске выбираются с помощью DataBase компонентом Table, который передает их компоненту DataSource отфильтрованными в соответствии с набором полей DataSet. DataSource передает данные любому визуальному компоненту, управляющему данными, который имеется в форме. Если пользователь сделает какие-нибудь изменения в данных с помощью визуальных управляющих компонентов, то DataSource передает эти изменения обратно компоненту Table, который с помощью DataBase помещает измененные данные в таблицу на диске.

При использовании динамически формируемого набора полей в компоненте DBGrid (сетка) отображаются значения всех полей каждой записи (строки) таблицы, а заголовок сетки содержит названия полей, и

Рис.10. Взаимодействие компонентов, связанных с данными

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

Чтобы сетка выглядела в соответствии с эскизом на рис.8, и категория квартиры выводилась в расшифрованном виде, необходимо набор полей для компонента taFLAT сформировать с помощью редактора полей; сформированный набор полей будет автоматически использоваться вместо динамически формируемого. Редактор полей позволяет добавлять или удалять поля, отображаемые в визуальных компонентах; задавать тип данных, хранящихся в полях; изменять порядок следования полей в DataSet, ассоциированном с компонентом Table; модифицировать свойства отдельных полей.

Чтобы для компонента taFLAT сформировать набор полей с нужными свойствами, необходимо:

1) вызвать редактор полей двойным щелчком на этом компоненте. В появившемся окне область Fields пуста, поскольку набор полей, формируемый динамически, не отображается в редакторе полей;

2) нажать правую кнопку мыши для вызова контекстного меню и выбрать из него команду Add all fields, чтобы добавить поля в область Fields. На экране снова появится окно с областью Fields, заполненной именами выбранных полей;

3) выбрать в контекстном меню команду New field, чтобы дополнить набор полей полем, в котором будет содержаться полное название категории квартиры. На экране появится окно New Field;

4) задать имя CategoryName для поля, в котором будет содержаться название категории квартиры, вычисляемое по коду, хранящемуся в поле KCategory. В графе Component автоматически сформируется имя компонента, соответствующего вычисляемому полю;

5) задать тип вычисляемого поля, выбрав из списка Type название String;

6) убедиться, что выбран расположенный в области Field type селектор Calculated;

7) нажать кнопку ОК. В появившемся окне редактора полей область Fields будет содержать имена полей, включенных в набор, и среди них - вычисляемое поле CategoryName;

8) поменять местами поля KCategory и CategoryName. Для этого нужно установит курсор мыши на поле KCategory и, удерживая нажатой левую кнопку мыши, перетащить это поле вниз на место, занимаемое полем CategoryName (этот пункт необязательный, предусмотрен для демонстрации возможности изменять порядок следования полей в наборе);

9) последовательно щелкнуть мышью на каждом поле в области Fields и в окне инспектора объектов установить значения свойств полей согласно табл.7;

10) закрыть окно редактора полей.

Таблица 7

Значения свойств полей для компонента taFLAT

Имя поля

Calculated

DisplayLabel

Visible

Adr

False

Адрес

True

Skv

False

Площадь

True

Nrooms

False

Комнат

True

CategoryName

True

Категория

True

KCategory

False

KCategory

False

В результате заголовок сетки будет содержать названия колонок на русском языке (свойство DisplayLabel), колонка со значениями поля KCategory отображаться не будет (Visible=False), колонка со значениями вычисляемого поля CategoryName (Calculated=True) будет пустой. Чтобы заполнить эту колонку, необходимо для компонента taFLAT задать процедуру обработки события OnCalcFields. Эта процедура для каждой строки записи таблицы БД будет определять значения вычисляемых полей, предусмотренных в наборе полей для соответствующего компонента Table.

Чтобы задать процедуру обработки события OnCalsFields для компонента taFLAT, нужно:

1) выделить компонент taFLAT в форме fmSHOWFLAT;

2) в окне инспектора объектов на странице событий дважды щелкнуть в строке, соответствующей событию OnCalcFields;

3) в активизированном окне текстового редактора набрать текст процедуры, приведенной на листинге 7.

Листинг 7. Процедура задания значений вычисляемым полям

procedure TfmSHOWFLAT.taFLATCalcFields

(DataSet:TDataset); var s : string[20];

begin s := taFLAT.FieldByName('KCategory').AsString;

case s[1] of 'Н': s:='Неприватизированная';

'П': s:='Приватизированная';

'К': s:='Коммунальная';

end; taFLATCategoryName.Value := s; end;

Теперь создание формы fmSHOWFLAT полностью завершено, и следует сохранить проект командой File|Save Project и еще раз проверить работоспособность приложения.

Аналогичным способом создаются три другие формы типа сетка: fmSHOWPHON, fmSHOWPROF, fmSHOWPERS.

Создание формы fmEDITPERS. Выберем команду File|New Form, чтобы включить в проект пустую форму.

Поместим в эту форму восемь компонентов Label, пять компонентов Button, четыре компонента DBEdit и по одному компоненту DBText, DBComboBox, DBLookupCombo, DBGrid и DBNavigator, расположив их так, как показано на рис.9. Поместим также на любое свободное место в форме пять компонентов Table и три компонента DataSource.

Зададим для формы значение свойства Name=fmEDITPERS. Значения свойства Name для других компонентов установим в соответствии с указаниями, приведенными на рис.9, и примечанием, следующим за табл.2.

Значения свойства Caption для компонентов Label устанавливаются согласно надписям, поясняющим содержимое областей создаваемой формы и показанным на рис.9. Значение свойства Caption для компонентов Button задаются согласно надписям на кнопках (см. рис.9).

Свойства компонентов Table и DataSource устанавливаются в соответствии с табл.8 и 9.

Таблица 8

Значения свойств компонентов Table

Свойство

Table1

Table2

Table3

Table4

Table5

Name

taPERSON

taHAVE_D

taFLAT

taTPHONE

taPROFIT

Database Name

dbTUTOR

dbTUTOR

dbTUTOR

dbTUTOR

dbTUTOR

Table Name

PERSON.DB

HAVE_D.DB

FLAT.DB

TPHONE. DB

PROFIT. DB

Active

True

True

True

True

True

Таблица 9

Значения свойств компонентов DataSource

Свойство

DataSource1

DataSource2

DataSource3

Name

dsPERSON

dsHAVE_D

dsFLAT

DataSet

taPERSON

taHAVE_D

taFLAT

С помощью редактора полей для каждого компонента Table следует сформировать набор полей, используя ранее описанную последовательность действий. Для таблиц taFLAT, taTPHONE и taPROFIT набор полей совпадает с перечнем полей (атрибутов) для находящейся в базе данных на диске таблицы с именем TableName, которая связана с компонентом Table.

Для таблицы taPERSON в набор полей включаются все поля, имеющиеся в таблице (файле) PERSON.DB, и одно вычисляемое поле Ntel типа String для хранения номера телефона, установленного в квартире. Для вычисления значения этого поля необходимо предусмотреть процедуру обработки события OnCalcFields для таблицы taPERSON. Текст этой процедуры, имя которой формируется автоматически системой Delphi, приведен на листинге 8. Значение вычисляемого поля Ntel таблицы taPERSON в процедуре обозначается как taPERSONNtel.Value.

Листинг 8. Процедура определения номера телефона

procedure TfmEDITPERS.taPERSONCalcFields

(DataSet : TDataset);

begin

with taTPHONE do {Найти номер телефона по адресу}

begin

Open;

IndexName := 'Adr'; {Задать вторичный индекс}

First;

SetKey;

FieldByName('Adr').AsString :=

taPERSON.FieldByName('Adr').AsString;

if GotoKey then {Запись найдена по ключу}

taPERSONNtel.Value := FieldByName('Ntel').AsString

else {Запись не найдена}

taPERSONNtel.Value := '';

end;

end;

Для таблицы taHAVE_D в набор полей включаются все поля, имеющиеся в таблице (файле) HAVE_D.DB, и два вычисляемых поля: Source типа String с названием источника дохода и Size типа Currency с размером дохода. Для вычисления значений этих полей необходимо предусмотреть процедуру обработки события OnCalcFields для таблицы taHAVE_D. Текст этой процедуры taHAVE_DCalcFields приведен на листинге 9. Значения вычисляемых полей отыскиваются в таблице taPROFIT по идентификатору вида дохода Id.

Листинг 9. Процедура вычисления полей Source и Size таблицы taHAVE_D

procedure TfmEDITPERS.taHAVE_DCalcFields(DataSet: TDataset);

begin

with taPROFIT do

begin

DisableControls; Open; First; SetKey;

FieldByName('Id').AsInteger :=

fmEDITPERS.taHAVE_D.FieldByName('Id').AsInteger;

GotoKey; {Поиск записи по ключу}

EnableControls;

end;

taHAVE_DSource.Value := taPROFITSource.Value;

taHAVE_DSize.Value := taPROFITMoneys.Value;

end;

Данные из таблицы taHAVE_D отображаются в компоненте grHAVE_D. Чтобы на экране были видны значения только полей Source, Size и Comment с соответствующими заголовками Источник, Размер, Пояснение, значения свойств полей в сформированном наборе должны быть установлены согласно табл.10.

Значения свойств, общих для визуальных компонентов, управляющих данными, задаются в соответствии с табл.11. Для компонента dcPol дополнительно устанавливается значение свойства Items, содержащего допустимое обозначение пола, которое помещается в поле Pol таблицы taPERSON. Действия по установке значения свойства Items были описаны при создании формы fmEDITFLAT. Для компонента deSumD дополнительно задается значение свойства ReadOnly=True, чтобы запретить запись общего дохода с помощью клавиатуры, поскольку целесообразно общий доход вычислять автоматически на основе данных, имеющихся в таблицах taHAVE_D и taPROFIT.

Таблица 10

Значения свойств полей для компонента taHAVE_D

FieldName

Calculated

DisplayLabel

Visible

Nom

False

Nom

False

Id

False

Id

False

Source

True

Источник

True

Size

True

Размер

True

Comment

True

Пояснение

True

Таблица 11

Значения общих cвойств визуальных компонентов

Name

DataSource

DataField

Name

DataSource

DataField

teNom

dsPERSON

Nom

deSumD

dsPERSON

SumD

deFIO

dsPERSON

FIO

deNtel

dsPERSON

Ntel

deRdate

dsPERSON

Rdate

grHAVE_D

dsHAVE_D

dcPol

dsPERSON

Pol

naHAVE_D

dsHAVE_D

lcAdr

dsPERSON

Adr

Для компонента naHAVE_D дополнительно устанавливается значение свойства VisibleButtons=[nbFirst,nbPrior, nbNext, nbLast, nbDelete, nbEdit, nbPost, nbCancel], поскольку вместо кнопки навигатора nbInsert в форме предусмотрена кнопка Новый доход.

С помощью компонента lcAdr значение поля Adr таблицы taPERSON устанавливается путем выбора из списка возможных значений, хранящихся в таблице taFLAT; список появляется при щелчке на кнопке со стрелкой. Для настройки компонента lcAdr нужно задать значения свойств DataSource и DataField, указанные в табл.12, а также значения свойств LookupSource, LookupField, LookupDisplay, необходимые для связи с таблицей taFLAT: LookupSource=dsFLAT (DataSource, соответствующий таблице taFLAT); LookupField=Adr (ключевое поле таблицы taFLAT, значение которого должно соответствовать значению поля, указанного в свойстве DataField); LookupDisplay=Adr (поле таблицы taFLAT, значение которого отображается на экране в компоненте lcAdr).

Примечание. Компонент DBLookupCombo обеспечивает равенство значений полей DataField и LookupField в таблицах, связанных с DataSource и LookupSource соответственно, и позволяет отображать значение поля LookupDisplay на экране в компоненте DBLookupCombo.

В компоненте grHAVE_D должны отображаться виды доходов жителя, номер которого выводится в области компонента teNom. Для этого между таблицами taPERSON и taHAVE_D необходимо установить связь главная/подчиненная (master/detailed), задав следующие значения свойств подчиненной таблицы taHAVE_D: MasterSource=dsPERSON; MasterFields=Nom. Строки (записи) в подчиненной таблице должны быть упорядочены с помощью существующего индекса по значениям полей, соответствующих полям, указанным в свойстве MasterFields. Для таблицы taHAVE_D действует первичный индекс с составным ключом (Nom, Id), обеспечивающим автоматическую сортировку по значениям поля Nom, поэтому специального указания об используемом индексе не требуется, хотя для полной ясности можно было бы установить свойство IndexFieldNames=Nom.

Для вычисления общего дохода жителя и записи его в поле SumD таблицы taPERSON поместим в форму компонент Query со страницы Data Access палитры компонентов и зададим его свойства Name=quSumD, DatabaseName=dbTUTOR. Затем дважды щелкнем на свойстве SQL и в появившемся окне String List editor наберем запрос на языке SQL, с помощью которого будет вычисляться общий доход жителя, помещаемый в поле Summa компонента quSumD (листинг 10).

Листинг 10. SQL-запрос для вычисления общего дохода

select SUM(PROFIT.Moneys) Summa, HAVE_D.Nom

from HAVE_D, PROFIT

where HAVE_D.Id=PROFIT.Id and HAVE_D.Nom=:Nom

group by Nom

Параметром SQL-запроса является величина :Nom, обозначающая номер жителя. Тип параметра (Integer) задается как значение свойства Params компонента quSumD. С помощью редактора полей для компонента quSumD следует сформировать набор полей, включив в него поле Summa.

SQL-запрос должен выполняться каждый раз после записи новой строки в таблицу taHAVE_D или после удаления строки из нее, т.е. при наступлении события AfterPost или AfterDelete. Текст процедуры обработки события AfterPost приведен на листинге 11.

Листинг 11. Процедура вычисления общего дохода

procedure TfmEDITPERS.taHAVE_DAfterPost

(DataSet: TDataset);

begin

with quSumD do

begin

if Active then Close; {Закрыть таблицу}

{Задать значение параметра}

ParamByName('Nom').AsInteger:=taPERSONNom.AsInteger;

Open; {Выполнить SQL-запрос}

{Записать общий доход}

taPERSONSumD.Value:=quSumDSumma.Value;

end;

end;

Эта же процедура должна выполняться при наступлении события AfterDelete. Чтобы использовать ее повторно, нужно для таблицы taHAVE_D в окне инспектора объектов на странице событий выделить строку, соответствующую событию AfterDelete, щелкнуть в этой строке на кнопке со стрелкой и выбрать из появившегося списка имя процедуры taHAVE_DAfterPost.

Теперь перейдем к компонентам Button. Для кнопок Отмена и Выход процедуры обработки события OnClick во многом сходны с ранее рассмотренными (см. листинг 3) и приведены на листинге 12.

Листинг 12. Процедуры обработки события OnClick для кнопок Отмена и Выход

procedure TfmEDITPERS.buCancelClick(Sender: TObject);

begin

with taPERSON do

begin

Cancel; {Отменить изменения, }

Edit; { но }

taHAVE_DAfterPost(taHAVE_D);{вычислить и }

Post; {запомнить общий доход}

end;

fmEDITPERS.Close;

end;

procedure TfmEDITPERS.buExitClick(Sender: TObject);

begin

with taPERSON do

begin

if (State in [dsEdit,dsInsert]) and Modified then

Post;{Сохранить изменения, если действует режим}

end;{редактирования/дополнения и запись изменялась}

KeyValue := {Запомнить значение ключа для fmSHOWPERS}

taPERSON.FieldByName('Nom').AsInteger;

fmEDITPERS.Close;

end;

Процедура обработки события OnClick для кнопки Сведения о квартире активизирует форму fmEDITFLAT для просмотра, изменения или регистрации сведений о квартире (листинг 13). Если регистрируется новая квартира, то сведения о ней должны быть отражены в таблице taFLAT, принадлежащей форме fmEDITPERS, иначе новый адрес не будет появляться в списке, связанном с компонентом lcAdr. Для обновления таблицы taFLAT после возврата из формы fmEDITFLAT вызывается процедура Refresh_taFLAT, текст которой приведен на листинге 13. Заголовок процедуры Refresh_taFLAT помещается в разделе private класса TfmEDITPERS.

Листинг 13. Процедуры обработки события OnClick для кнопки Сведения о квартире и обновления таблицы taFLAT

procedure TfmEDITPERS.buEditFlatClick

(Sender : TObject);

begin

if taPERSONAdr.Value='' then {Адрес отсутствует}

begin

fmEDITFLAT.Editing :=False;

fmEDITFLAT.KeyValue:='';

end

else

begin

fmEDITFLAT.Editing := True;

fmEDITFLAT.KeyValue:= taPERSONAdr.Value;

end;

fmEDITFLAT.ShowModal;

Refresh_taFLAT; {Обновить таблицу}

if (fmEDITFLAT.KeyValue<>'') then {Адрес задан}

begin {Показать адрес}

lcAdr.DisplayValue := fmEDITFLAT.KeyValue;

{Записать адрес}

taPERSONAdr.Value := fmEDITFLAT.KeyValue;

{Вычислить номер телефона}

taPERSONCalcFields(taPERSON);

end;

end;

procedure TfmEDITPERS.Refresh_taFLAT;

begin

with taFLAT do

begin

First; SetKey;

FieldByName('Adr').AsString := fmEDITFLAT.KeyValue;

GotoKey; {Поиск записи по ключу}

end;

end;

Процедура обработки события OnClick для кнопки Сведения о телефоне активизирует форму fmEDITPHON для просмотра, изменения или регистрации сведений о телефоне (листинг 14). Если регистрируется новый телефон, то сведения о нем будут отражены в таблице taTPHONE, принадлежащей форме fmEDITPERS, при поиске номера телефона по адресу процедурой taRERSONCalcFields.

Листинг 14. Процедура обработки события OnClick для кнопки Сведения о телефоне

procedure TfmEDITPERS.buEditPhoneClick

(Sender: TObject);

begin

if taPERSONNtel.Value='' then {Телефон отсутствует}

begin

fmEDITPHON.Editing := False;

fmEDITPHON.KeyValue:= ''; {Если не изменится,}

end {то была Отмена}

else

begin

fmEDITPHON.Editing := True;

fmEDITPHON.KeyValue:= taPERSONNtel.Value;

end;

fmEDITPHON.ShowModal;

taPERSONCalcFields(taPERSON);{Вычислить номер телефона}

end;

Процедура обработки события OnClick для кнопки Новый доход добавляет новую строку в таблицу taHAVE_D и активизирует форму fmEDITPROF, используемую для выбора нужного вида дохода (листинг 15). После возврата из формы fmEDITPROF заполняются поля Nom и Id добавленной строки в таблице taHAVE_D и строка записывается в таблицу.

Листинг 15. Процедура обработки события OnClick для кнопки Новый доход

procedure TfmEDITPERS.buNewProfitClick

(Sender: TObject);

begin

taHAVE_D.Append;

fmEDITPROF.Editing := True;

fmEDITPROF.KeyValue:= 0;

fmEDITPROF.ShowModal;

if fmEDITPROF.KeyValue>0 then {Выбор сделан}

begin

with taPERSON do

if (State in [dsEdit,dsInsert])

and Modified then

begin

Post; {Сохранить изменения, если действует}

{режим редактирования или дополнения}

{и запись изменялась, чтобы устано- }

Edit; {вить значение поля Nom }

end;

taHAVE_DNom.Value := taPERSONNom.Value;

taHAVE_DId.Value := fmEDITPROF.KeyValue;

taHAVE_D.Post;

end

else {Выбор не сделан}

taHAVE_D.Cancel;

end;

В процедуре учтена особенность полей типа Autoincrement: при добавлении новой строки в таблицу методом Append или Insert значение в поле этого типа заносится только после выполнения метода Post для таблицы.

Для автоматического определения номера телефона по заданному адресу предусмотрим для компонента lcAdr процедуру обработки события OnChange, которое наступает при переходе фокуса из области компонента lcAdr, если изменилось значение адреса (листинг 16).

Листинг 16. Процедура обработки события OnChange для компонента lcAdr

procedure TfmEDITPERS.lcAdrChange(Sender: TObject);

begin with taPERSON do

if (State in [dsEdit,dsInsert])

and Modified then {Определить номер телефона}

taPERSONCalcFields(taPERSON); end;

Создаваемая форма может вызываться в режимах регистрации или изменения сведений о жителе. При активизации формы fmEDITPERS необходимо задать соответствующий заголовок формы и обеспечить доступ к нужной записи таблицы taPERSON. Эти действия выполнит процедура обработки события OnActivate, текст которой приведен на листинге 17.

Листинг 17. Процедура обработки события OnActivate

procedure TfmEDITPERS.FormActivate(Sender: TObject);

begin

if Editing then

begin

Caption := 'Изменение сведений о жителе';

with taPERSON do

begin

DisableControls;

First;

SetKey;

FieldByName('Nom').AsInteger := KeyValue;

GotoKey; {Поиск записи по ключу}

EnableControls;

Edit; {Режим редактирования}

end;

end

else

begin

Caption := 'Регистрация сведений о жителе';

taPERSON.Append; {Режим дополнения}

end;

end;

В этой и других процедурах используется признак режима Editing типа Boolean и признак KeyValue типа Longint, содержащий значение первичного ключа таблицы taPERSON. Эти переменные следует объявить в разделе public класса TfmEDITPERS.

Создаваемая форма активизирует формы fmEDITFLAT, fmEDITPROF и fmEDITPHON. Чтобы они были доступны, в раздел Implementation модуля создаваемой формы следует поместить предложение

uses EDITFLAT, EDITPROF, EDITPHON;

Сохраним созданную форму и проект командой File|Save Project, указав в качестве имени модуля созданной формы имя EDITPERS. На этом создание формы fmEDITPERS завершается. Остается связать ее с пунктом меню Житель в главной форме и кнопкой на панели быстрого доступа sbNewPerson аналогично тому, как подобные связи устанавливались для формы fmEDITFLAT.

Сохранив изменения командой File|Save Project, можно проверить работоспособность проекта, осуществив активизацию созданной формы из меню или кнопкой на панели быстрого доступа и убедившись в правильном функционировании формы fmEDITPERS.

Соседние файлы в папке ЭКТ