Советы по Delphi

       

Модуль Db_QBF.PAS, позволяющий в Delphi осуществить форму запроса для компонентов DbGrid


Предлагаю Вашему вниманию модуль Delphi для модального диалога, поддерживающий форму запроса (Query By Form - QBF) для компонентов DbGrid с возможностью получения данных от Table-компонентов (не используя Query-компонентов).

Встроенные характеристики обмена данными в Delphi делают эту задачу намного труднее, чем, например, в таких ресурсоемких инструментальных средствах, как Oracle Forms (Оракловые формы). Данный модуль не такой мощный как встроенные QBF-возможности Оракловых форм, но он заполняет значительную брешь в функциональности Delphi.

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

unit Db_QBF; { Форма запроса базы данных }

{ Все права защищены. Автор Rick Rutt.
Данный модуль может без какой-либо оплаты быть использован в программе,скопирован или распространен любым человеком и для любой цели, если всекопии данного модуля сохраняют это авторское уведомление.Автор предоставляет разрешение каждому для создания производного кода, есликаждая производная работа содержит авторское уведомление и строку"Части данной работы основываются на Db_QBF.PAS, созданным Rick Rutt."}

{ Данный модуль обеспечивает простую, но эффективную форму запроса
для доступа приложений к базам данных, используя Borland Delphi.Данный модуль также располагает сервисом Sort By Form (форма сортировки).
Форма запроса отображает модальное диалоговое окно с компонентом StringGrid,содержащим искомые поля, полученные при вызове DbGrid. Пользователь можетввести точную величину поиска для любого количества полей и использоватьфункцию drag and drop (перетащи и брось) для изменения порядка сортировки полей.(Только тех полей, которые содержат искомые величины, влияющие на сортировку.)Когда пользователь щелкает в диалоговом окне на кнопку OK, данный модуль модифицируетзначение свойства IndexFieldNames компонента DbGrid, применяет диапазон поиска(точные величины), и обновляет данные.В случае, если пользователь не указывает ни одной из величин поиска, данный модуль очищаетзначение свойства IndexFieldNames компонента DbGrid, очищает диапазон поискаи обновляет данные.
Сервис Sort By Form работает аналогично, за исключением того,что не принимает в расчет величину поиска, введенную пользователем. Пользователь пользуется функцией drag and drop (перетащи и брось)для установления порядка сортировки и затем нажимает на кнопку OK. Данный модуль модифицируетзначение свойства IndexFieldNames компонента DbGrid, очищает диапазон поискаи обновляет данные.}

{ Создайте соответствуюшую форму диалога, используя меню "File/New.../Dialogs"
и выбрав пункт "Standard Dialog Box". Разместите на форме компонент StringGrid(Вы найдете его в палитре компонентов на странице "Additional").Установите следующие размеры StringGrid: высота 161 и ширина 305.И, наконец, замените исходный код новой формы (PAS-файл) данным модулем.}

interface

uses WinTypes, WinProcs, Classes, Graphics, Forms, Controls, Buttons,
StdCtrls, ExtCtrls, Grids, DBGrids;
{ Следующие две процедуры обеспечивают механизм доступа
сервисов данного модуля.
Кнопка (или пункт меню) вызывают процедуру,передавая ей в качестве аргумента DbGrid. (Не забудьте добавить строку"uses Db_QBF;" в секцию реализации модуля вызова форм.)
Ограничение: компонент DbGrid должен ссылаться на DataSource, который, в свою очередь,ссылается на DataSet, работающий с таблицой. Данный модуль не поддерживаетзапрос напрямую к DataSet ввиду отсутствия свойства IndexFieldNames.}

procedure QueryByForm(grid: TDbGrid);

procedure SortByForm(grid: TDbGrid);

{ Следующая секция управляется средой Delphi. }

type
TdlgQBF = class(TForm)OKBtn: TBitBtn;CancelBtn: TBitBtn;HelpBtn: TBitBtn;gridQBF: TStringGrid;procedure OKBtnClick(Sender: TObject);procedure CancelBtnClick(Sender: TObject);private{ Private declarations }public{ Public declarations }end;
var
dlgQBF: TdlgQBF;
implementation

{ Следующая секция пишется программистом
с помощью среды Delphi. }
uses Dialogs, Db, DbTables;

{$R *.DFM}

const
qbfRowHeight = 16;qbfColWidth = 150;
qbfFieldLabel = '<<Поле>>';qbfValueLabel = '<<Значение>>';
qbfQueryCaption = 'Запрос для таблицы ';qbfSortCaption = 'Порядок сортировки для таблицы ';
var
{ Объявим некоторые элементы управления, участвующие в QBF-диалоге при нажатии кнопки OK. }CallingGrid: TDbGrid;CallingMode: (modeQuery, modeSort);
procedure SetupAndShowForm; { Инициализация формы, обеспечивающей визуализацию работы двух объявленных выше процедур }
var
i, j, n: integer;tbl: TTable;f: TField;begin
n := CallingGrid.FieldCount;if n <= 0 then begin { Вместо вывода сообщений могут генерится исключительные ситуации }MessageDlg('При обращении к DbGrid, модуль Db_QBF не обнаружил полей',mtWarning, [mbOK], 0);end else if CallingGrid.DataSource = NIL then beginMessageDlg('При обращении к DbGrid, модуль Db_QBF не обнаружил ссылки на DataSource',mtWarning, [mbOK], 0);end else if CallingGrid.DataSource.DataSet = NIL then beginMessageDlg('При обращении к DbGrid, модуль Db_QBF обнаружил подключенный DataSource без ссылки на DataSet',mtWarning, [mbOK], 0);end else if not (CallingGrid.DataSource.DataSet is TTable) then beginMessageDlg('При обращении к DbGrid, модуль Db_QBF обнаружил подключенный DataSource с сылкой на DataSet, не являющийся таблицей.',mtWarning, [mbOK], 0);end else with dlgQBF.gridQBF do begin{ Данные свойства могут быть изменены и в режиме проектирования }DefaultRowHeight := qbfRowHeight;Scrollbars := ssVertical;ColCount := 2; { Для режима сортировки необходимы две пустые колонки }
{ Данные свойства должны быть установлены во время выполнения программы }RowCount := Succ(n);Cells[0,0] := qbfFieldLabel;Options := Options + [goRowMoving];
tbl := TTable(CallingGrid.DataSource.DataSet);
if CallingMode = modeQuery then begindlgQBF.Caption := qbfQueryCaption + tbl.TableName;Cells[1,0] := qbfValueLabel;Options := Options + [goEditing]; { Позволяем пользователю ввести значение }DefaultColWidth := qbfColWidth;end else begindlgQBF.Caption := qbfSortCaption + tbl.TableName;Cells[1,0] := ''; { Ввод "пустышки" для первой, нефункциональной колонки }Options := Options - [goEditing]; { Убираем возможность редактирования }DefaultColWidth := (2 * qbfColWidth); { Этим трюком мы помещаем две пустых секции над одной колонкой }end;
j := 0; { Фактическое число полей, показываемое пользователю }for i := 1 to n do beginf := CallingGrid.Fields[Pred(i)];if f.DataType in [ftBlob,ftBytes,ftGraphic,ftMemo,ftUnknown,ftVarBytes]then RowCount := Pred(RowCount) { Игнорируем неиндексируемые поля }else beginInc(j);Cells[0,j] := f.FieldName;Cells[1,j] := ''; { Сбрасываем искомую величину }end;end;
dlgQBF.HelpBtn.Visible := False; { Помощь, понятно, отсутствует... }dlgQBF.ShowModal;end; { with dlgQBF.gridQBF }end;

procedure QueryByForm(Grid: TDbGrid);
begin
CallingGrid := Grid; { Сохраняем для использования при нажатии на кнопку OK }CallingMode := modeQuery;SetupAndShowForm;end;

procedure SortByForm(Grid: TDbGrid);
begin
CallingGrid := Grid; { Сохраняем для использования при нажатии на кнопку ОК }CallingMode := modeSort;SetupAndShowForm;end;

procedure TdlgQBF.CancelBtnClick(Sender: TObject);
begin
{ Просто прячем диалог, не делая никаких изменений в вызывающем Grid'е. }dlgQBF.Hide;end;

procedure TdlgQBF.OKBtnClick(Sender: TObject);
var
flds, sep, val: string;i, n, nfld: integer;begin
flds := ''; { Список полей, разделенных ';'. }sep := ''; { Разделитель ';' ставится после добавления первого поля. }nfld := 0; { Количество полей в списке. }
with dlgQBF.gridQBF do beginn := Pred(RowCount);if n > 0 then for i := 1 to n do beginval := Cells[1,i]; { Значение поиска, введенное пользователем (если имеется) }if (CallingMode = modeSort)or (val <> '') then beginflds := flds + sep + Cells[0,i];sep := ';';nfld := Succ(nfld);end;end;
with CallingGrid.DataSource.DataSet as TTable do beginIndexFieldNames := flds;if (CallingMode = modeSort)or (flds = '') then beginCancelRange;end else beginSetRangeStart;for i := 1 to n do beginval := Cells[1,i];if val <> '' then beginFieldByName(Cells[0,i]).AsString := val;end;end;
SetRangeEnd; { Устанавливаем конец диапазона так, чтобы он соответствовал его началу }for i := 1 to n do beginval := Cells[1,i];if val <> '' then beginFieldByName(Cells[0,i]).AsString := val;end;end;ApplyRange;end;
Refresh;end; { with CallingGrid.DataSource.DataSet }end; { with dlgQBF.gridQBF }
dlgQBF.Hide;end;

end.
[000069]



Содержание раздела