Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
DBM_1_X1.doc
Скачиваний:
2
Добавлен:
14.11.2019
Размер:
5.12 Mб
Скачать

If not RasxodTable.Eof then RasxodTable.Next

ELSE

Next.Enabled:=False;

end;

void __fastcall TForm1::NextClick(TObject *Sender)

{

if (RasxodTable->State = DsBrowse)

if (!RasxodTable->Eof) RasxodTable->Next();

ELSE

Next->Enabled=False;

}В нашем случае предполагается, что в зависимости от состояния таблицы программно ограничен доступ к соответствующим навигационным кнопкам (Код блокировок доступа к кнопкам здесь не приводится).

11 Вообще-то мы уже связывали эти таблицы, причем именно так же, при определении базы данных в WISQL. Однако смысл тех действий – определить ограничения целостности (требования правильности) БД, а смысл объявления операционной связи (Relation) – обеспечить соответствующее перемещение маркера текущей записи в таблице «Товары» при перемещении маркера текущей записи в таблице «Расход товара».

12 Простое действие «Стоимость:=Количество*Цена», пришлось обложить проверкой условия, причем довольно деликатной:

  • Событие OnDataChange случается гораздо чаще, чем нужно выполнять интересующее нас действие.

  • Это интересующее нас действие можно выполнять, только если таблица «Расход товара» находится в состоянии, допускающем ее обновление (State=dsEdit,dsInsert).

  • Однако самое деликатное – необходимость устранить возможность рекурсивного вызова. Событие OnDataChange почти последнее в цепочке действий, реализующих последствия изменений в строке (значения поля Kolvo или KOD_TOVAR, а значит Zena). Поэтому естественно, что наше действие, изменяющее значение поля Stoim, опять инициирует эту цепочку действий...

Возможно наиболее естественным и аккуратным было бы использование события OnChange поля Kolvo и Kod_Tovar объекта RasxodTable. Но к сожалению это событие происходит раньше, чем успевает установиться новая соответствующая строка в таблице Rasxod (с соответствующей ценой) при изменении значения поля Kod_Tovar и это влечет неправильное вычисление стоимости.

13 Другой вариант поручить этот контроль клиенту - установить свойство CustomConstraint поля Kolvo объекта RasxodTable равным Kolvo>=0, а свойство ConstraintErrorMessage равным: "Количество" должно быть неотрицательным. Заметим, что условия прописанные в процедуре вызывающуюся по событию OnValidate проверяются раньше проверки условий, прописанных в условии CustomConstraint.

14 Если эту связь определить в обратную сторону, то получим аналогичный двойственный результат, но… для правильного вычисления стоимости нам нужна связь именно та, какая определена.

15 Как выяснилось, использовать обработчик событий DBGrid1.OnEnter для переключения таблиц необходимо с определенной долей осторожности. Этот метод отрабатывает при установке фокуса на соответствующий Grid (в частности, для Grid1 при активизации формы). Поскольку открытие базы данных и открытие формы происходит параллельно, то в зависимости от ресурсов компьютера (в частности, скорости его работы), открытие базы данных может произойти после отрабатывания данного метода. В этом случае при открытии формы выполнение оператора TovaryTable.Refresh создаст исключительную ситуацию. Обойти это можно или добавлением проверки открыта ли база данных, или использованием другого обработчика (например, OnCellClick, этот метод отрабатывает только при установки фокуса на некоторую ячейку компонента Grid мышью, правда, в этом случае возникают новые проблемы: щелчок на заголовок Grid не даст необходимого эффекта)

16 Добавление Look-Up-поля можно делать только при закрытых таблицах.

17 Такая реализация работы с полями выбора (LookUp-поля, DBListBox, DBComboBox, DBLookUpComboBox) может создавать побочные эффекты: Эти объекты используют таблицу в качестве списка выбора, в рассмотренном случае – это таблица TOVARY, управляемая объектом TovaryTable (типа TTable). Проблема может возникать из-за того, что с этим же объектом TovaryTable связан объект DBGrid1 (через DataSource1). Перемещение к следующей записи в DBGrid1 («Товары») одновременно означает перемещение по списку выбора... с не очень ясными последствиями... Похоже, в нашем примере побочные эффекты не наблюдаются...

Устранить возможность побочного эффекта можно, поместив на форму еще один объект типа TTable, совпадающий с TovaryTable, но с другим именем, например TovaryTCombo, и установив в LookUp-поле TOVAR значение свойства LookUpDataSet равным TovaryTCombo.

Что хорошего и плохого в том, что для управления доступом к одной и той же таблице TOVARY используется несколько объектов типа TTable? Эта ситуация означает, что мы можем открыть для доступа несколько экземпляров одной и той же таблицы – данные в них одни и те же (и вообще говоря не дублируются), но положение маркера текущей записи разное. При этом, естественно мы имеем дополнительные расходы памяти на управляющую информацию, но зато имеем возможность безопасно (и без хлопот) обрабатывать записи одной и той же таблицы одновременно по нескольким разным схемам.

35

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