- •Проектирование и создание прикладной системы для работы с базой данных
- •Теоретические сведения Методика построения прикладной системы для работы с базой данных
- •Использование методики для выполнения учебного задания
- •Формы, обеспечиваюшие пользовательский интерфейс
- •Свойства пунктов главного и дополнительных меню
- •Свойства компонентов SpeedButton
- •Свойства компонентов, расположенных на форме fmEditflat
- •Значения свойств компонентов Button
- •Значения свойств компонентов, связанных с данными
- •Значения свойств полей для компонента taFlat
- •Значения свойств компонентов Table
- •Значения свойств компонентов DataSource
- •Значения свойств полей для компонента taHave_d
- •Значения общих cвойств визуальных компонентов
- •Лабораторное задание и порядок выполнения работы
- •Требования к отчету
- •Литература
- •Содержание
Значения свойств полей для компонента 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.