Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Проектирование БД в Delphi ВТиП.doc
Скачиваний:
57
Добавлен:
17.03.2016
Размер:
3.62 Mб
Скачать
      1. Обработчики событий OnGetText полей нд и компонента визуализации данныхTdbGrid

Событие OnGetText возникает всякий раз, когда программа обращается к полю НД с целью отображения его содержимого в любом визуализирующем компоненте, например TDBGrid. Программист в обработчике этого события должен поместить нужную строку в переменную Text соответсвующего объекта-поля.

Как видно из заголовка нашего примера в нижней сетки DBGrid2 ее 1-ый столбец должен содержать текст, составленный из значений 3-х уже существующих подстановочных объектов-полей tbMoveName, tbMoveAuthor и tbMovePublish набора данных tbMove. Напомним, что по умолчанию Delphi присваивает объекту-полю имя, полученное сцеплением имени НД - tbMove и имени поля - Name.

Чтобы реализовать такое составное поле, воспользуемся обработчиком события OnGetText объекта-поля tbMoveName набора данных tbMove.

В рассматриваемом случае строка Text объекта-поля tbMoveName получается объединением значений в полях tbMoveName, tbMoveAuthor и tbMovePublish.

Перейдите к форме модуля данных и вызовите редактор полей для НД tbMove. Щелкните на поле Name и откройте вкладку Events в окне инспектора объектов. Дважды щелкнув в правой части строки события OnGetText, напишите такой обработчик события:

procedure TDM.tbMoveNameGetText(Sender: TField;

var Text: string;

DisplayText: boolean);

begin

Text := tbMoveName.Value + '/' + tbMoveAuthor.Value + '/' +

tbMovePublish.Value;

end;

      1. Установка системных переменных в обработчике событяOnCreate

Во время работы программы можно заметить, что денежные суммы в сетках DBGrid1 и DBGrid2 содержат округленные до гривен значения. Такое отображение денежных сумм, предлагается по умолчанию, что не всегда допустимо.

С другой стороны программе доступны общесистемные переменные, зависящие от локализации Windows, и в том числе - переменная CurrencyDecimals, с помощью которой можно управлять форматом отображения данных типа currency.

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

procedure TFinNakls.FormCreate (Sender: TObject);

begin

//Задается показ типа данных currency с двумя знаками после запятой

CurrencyDecimals := 2

end;

    1. Бизнес-правила иобработчики событий компонент работы с бд

Программа для отображения содержания накладных и связанных с ними списков книг готова. Ее можно запустить и просматривать накладные. Однако не рекомендуется вставлять, редактировать или удалять записи в накладных и списках книг, пока в программе не реализован комплекс бизнес-правил.

Бизнес-правила определяют реакцию системы на добавление, изменение или удаление данных, обеспечивая непротиворечивость и ссылочную целостность БД.

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

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

Для файл-серверных систем они обычно реализуются в комплексе обработчиков событий AfterXXXX - BeforeXXXX компонентов-наборов данных TTable или TQuery.

В клиент-серверных и некоторых локальных системах эти действия, как правило, реализуются на сервере БД с помощью триггеров - процедур, которые автоматически запускаются при вставке, изменении или удалении записей.

Рассмотрим небольшой пример, реализующий часть бизнес-правил, связанных с удалением данных о накладной. Перед удалением данных о накладной надо удалить список связанных с ней книг, иначе в таблице MOVEBOOK появятся записи, которые ссылаются на несуществующую запись в таблице NAKLS.

Примечание. Для данного примера при правильном проектировании БД, в частности задания свойства каскадное удаление, собственно корректное удаление будет выполнено автоматически за счет средств самой СУБД. Однако при более сложных бизнес-правилах, когда удаление данных требует дополнительной обработки БД, ответственность за правильное выполнение удаления все равно ляжет на программиста.

Наиболее подходящим местом для реализации этого бизнес-правила является обработчик события BeforeDelete набора данных tbNakls. Это событие автоматически генерируется перед удалением записи.

Перейдите к форме модуля данных, щелкните на НД tbNakls в правой панели модуля и дважды щелкните в строке события BeforeDelete в окне инспектора объектов. Напишите такой обработчик события:

procedure TDM.tbNaklsBeforeDelete(DataSet: TDataSet);

begin

while not tbMove.EOF do // Пока в списке книг есть хотя бы

tbMove.Delete // одна книга, удаляем ее

end;

Следует подчеркнуть, что в обработчике учитывается то обстоятельство, что НД tbMove связан с текущей записью НД tbNakls отношением многие к одному и, следовательно, содержит данные только по тем книгам, которые относятся к удаляемой накладной.

Аналогичным образом с помощью обработчика BeforeDelete набора данных tbMove реализуются бизнес-правила, связанные с удалением информации о книге из списка книг.

Примечание. Следует подчеркнуть, что хранение значений полей таблиц в разных типах БД реализуется по-разному (см. раздел 4). Поэтому для их обработки в Delphi необходимо явно указать, в каком виде представлять эти значения. Например, вражение

tbNaklsNSum.AsFloat

требует представления объекта-поля tbNaklsNSum как числа типа Float, что при вычислениях в Delphi эквивалентно real.

Более точный код обработчика tbNaklsBeforeDelete приведен ниже (проект Chapt04\FieldValues\BiblosPrg.dpr).

type

TDM = class (TDataModule)

DB: TDatabase; //База данных

tbNakls: TTable; //Наборы данных

tbMove: TTable;

tbFirms: TTable;

tbBooks: TTable;

tbTypeNakl: TTable;

DataSource1: TDataSource; //Источники данных

DataSource2: TDataSource;

tbNaklsNaklId: TAutoIncField; //Объекты-поля

tbNaklsNSum: TFloatField;

tbNaklsNPayedSum: TFloatField;

tbMoveMoveID: TAutoIncField;

tbMoveMNakl: TIntegerField;

tbFirmsFirmID: TAutoIncField;

tbFirmsFName: TStringField;

tbFirmsFFinDelta: TFloatField;

tbFirmsFChgDelta: TFloatField;

tbBooksBookID: TAutoIncField;

tbBooksBName: TStringField;

tbTypeNaklTypeID: TSmallintField;

tbTypeNaklTName: TStringField;

procedure tbMoveNameGetText(Sender: TField; var Text: string;

DisplayText: boolean);

procedure tbNaklsBeforeDelete(DataSet: TDataSet);

procedure tbMoveBeforeDelete(DataSet: TDataSet);

private

{ Private declarations }

IsNaklDel: boolean; //содержит True, если удаляется накладная

public

{ Public declarations }

end;

var

DM: TDM; //Модуль данных