Справочные таблицы

Справочники представаляют собой простые таблицы ( "planets", "continents", "countries", "features" и "occupations") , состоящие, как правило, из :

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

Также объединим просмотр данных с их редактированием ( так называемое "in-place editing", как в MicroSoft Excel & Access ), для чего идеально подходят табличные MSEgui-компоненты - "tdbwidgetgrid" ( которые в деталях будут рассмотрены в следующих главах ) .

Здесь же, вследствие похожести таблиц, а также их группировки по назначению ( справочники ) - напрашивается унификация их редактирования. В чем эта унификация может заключаться ?

Под эти пункты просто идеально подходит механизм так называемых субмодулей. Итак, начнем.

Субмодуль
как средство унификации интерфейса
и алгоритма обработки событий

File->New->Form->SimpleForm :

Также полезно показать пользователю. какие записи он изменил и какие - нет, а если "да" - то каким образом. Сделаем это через выделение цветом строк в таблице ( которая будет на форме, в корую будет вставлен наш субмодуль ). Но подсказать, какой цвет что означает - лучше на субмодуле, чтобы потом была унификация этих цветов во всех справочниках - и планет, и контнентов, и...

Роняем с палитры "Widget" :

tlabel (1)

tlabel (2)

Примечания :

 

Теперь добавим интерфейс к БД :

Теперь запретим закрытие формы без полной ясности относительно - все ли изменения данных сохраненены ( или отменены ) . Удобнее всего это сделать в процедуре проверки правильности данных, автоматически вызываемой при закрытии формы ( а также явно, через вызов "canclose"- при желании кое-что допроверить ) :

commonrefseditfo

procedure tcommonrefseditfo.commonrefseditfoclosequery(
  const sender: tcustommseform;
  var amodalresult: modalresultty);
begin
 with dsContents.dataset as tmsesqlquery do begin
  // есть измеменения, но команды на их сохранение - не было
  if (not isexpected) and (changecount > 0) then begin
   // говорим "Нужно кое-что доделать"
   showmessage(
    'There are unsaved changes in the table. Fix them !',
    'Unsaved changes',
    [mr_ok]
   );
   // отказываем форме в закрытии, чтобы
   // пользователь вернулся в нее и закончил недоделанное
   amodalresult:= mr_none;
  end;
 end;
end;

"(not isexpected)" - проверка флажковой переменной (см. ниже). Если "isexpected = true", то идет автоматическая проверка по сценарию ( запущенная кнопками "Save All" или "Add" ), поэтому пользователя мучать не надо.

Если же "isexpected = false", это значит, что процедура вызывана прямым закрытием формы ( или непрямым - например, через завершение приложения), без должного внимания к измененным данным. Вот и привлекаем это внимание - через "showmessage" !

Дополнительные модификации файла "commonrefseditform.pas" - добавление "msewidgets" в секцию "uses" , переменная под флаг "isexpected", и управление этим флагом :

implementation

uses
 commonrefseditform_mfm,
 msesqldb, // предоставляет "tmsesqlquery"
 msewidgets // предоставляет "showmessage"
;

var
  // флаг-признак использования кнопок"SaveAll" или "Add"
 isexpected : boolean;

// слегка модифицированная процедура
//
procedure tcommonrefseditfo.saveallexecute(
 const sender: TObject);
begin
 // чтобы не было ругани в "onclosequery"
 isexpected:= true;
 if parentwidget.container.canclose(nil) then begin
  with dsContents.dataset as tmsesqlquery do begin
   applyupdates;
   (transaction as tmsesqltransaction).commit;
   active:= true;
  end;
 end;
 // несохраненные данные - опять ненормальное явление
 isexpected:= false;
end;

и аналогично

procedure tcommonrefseditfo.addexecute(
  const sender: TObject);
begin
 isexpected:= true;
 if parentwidget.canparentclose(nil) then begin
  dsContents.dataset.append;
 end;
 isexpected:= false;
end;

Примечания :

Итоговый вид формы "commonrefeditfo" с компонентами :

 

Теперь эта форма, в качестве субмодуля ( submodule ) может использоваться как каркас для построения однотипных редакторов таблиц. Как это сделать - см . далее .