Delphi World - это проект, являющийся сборником статей и малодокументированных возможностей  по программированию в среде Delphi. Здесь вы найдёте работы по следующим категориям: delphi, delfi, borland, bds, дельфи, делфи, дэльфи, дэлфи, programming, example, программирование, исходные коды, code, исходники, source, sources, сорцы, сорсы, soft, programs, программы, and, how, delphiworld, базы данных, графика, игры, интернет, сети, компоненты, классы, мультимедиа, ос, железо, программа, интерфейс, рабочий стол, синтаксис, технологии, файловая система...
Модуль, позволяющий в Delphi осуществить форму запроса для компонентов DBGrid

Автор: Rick Rutt

Визит министра здравоохранения (МЗ) в одну из психиатрических лечебниц. Осмотрев палаты, процедурные залы, столовую МЗ изьявляет желание проверить, как содержатся буйнопомешанные больные, опасные для окружающих. Спускаются на 1-й этаж, Главный врач (ГВ) отпирает стальную кованую дверь. За дверью длинный коридор. МЗ переходит от камеры, к камере, читает таблички, иногда заглядывает внутрь. Около одной из камер. МЗ:
- Так-так. Острая паранойя, OS/2 Warp, мания величия...
Заглядывает в окошко. Угрюмый тип, увидев МЗ, начинает метаться по камере, крича: "Ла-а-меры!!! Ла-а-а-меры!!! Суксь, Суксь МастДайная!!!"
МЗ: (Обращается к ГВ) Часто он так?
ГВ: Как новое лицо увидит, сразу приступ... Идут дальше.
МЗ: Так-так. Острая паранойя.
UNIX, мания величия... Заглядывает в окошко. Угpюмый тип, оторвавшись от созерцания собственных рук, поворачивается, и расплывшись в улыбке, изрекает: "Истинная многозадачность, полный контроль, Рулез Форева!"
МЗ: (Обращается к ГВ) Тихий какой! Выздоравливает?
ГВ: Hет, временное улучшение.
(Повернувшись к окошку) - NT!
Больной, вскочив с кровати, начинает метаться по камере, крича: "А-а-а!!! Вытесняющая многозадачность!!! Исходные тексты!!! Суксь!!! Ла-а-а-меpы!!!"
Идут дальше.
МЗ: Так-так. Острая паранойя.
Windows'95, мания величия. Заглядывает в окошко... Камера пуста. МЗ: (Hедоумённо поворачивается к ГВ)
- А где же больной? Hа процедурах?
ГВ: Видите ли... Только поймите нас правильно... Бухгалтерия у нас на Excel, личные дела больных на Access...

Предлагаю Вашему вниманию модуль 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
  begin
    MessageDlg(
      'При обращении к DbGrid, модуль Db_QBF не обнаружил ссылки на DataSource',
      mtWarning, [mbOK], 0);
  end
  else if CallingGrid.DataSource.DataSet = nil then
  begin
    MessageDlg(
      'При обращении к DbGrid, модуль Db_QBF обнаружил подключенный
      DataSource без ссылки на DataSet',
      mtWarning, [mbOK], 0);
  end
  else if not (CallingGrid.DataSource.DataSet is TTable) then
  begin
    MessageDlg(
      'При обращении к 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
      begin
        dlgQBF.Caption := qbfQueryCaption + tbl.TableName;
        Cells[1, 0] := qbfValueLabel;
        Options := Options + [goEditing];
          { Позволяем пользователю ввести значение }
        DefaultColWidth := qbfColWidth;
      end
      else
      begin
        dlgQBF.Caption := qbfSortCaption + tbl.TableName;
        Cells[1, 0] := '';
          { Ввод "пустышки" для первой, нефункциональной колонки }
        Options := Options - [goEditing]; { Убираем возможность редактирования }
        DefaultColWidth := (2 * qbfColWidth);
          { Этим трюком мы помещаем две пустых секции над одной колонкой }
      end;

      j := 0; { Фактическое число полей, показываемое пользователю }
      for i := 1 to n do
      begin
        f := CallingGrid.Fields[Pred(i)];
        if f.DataType in [ftBlob, ftBytes, ftGraphic, ftMemo, ftUnknown,
          ftVarBytes] then
          RowCount := Pred(RowCount) { Игнорируем неиндексируемые поля }
        else
        begin
          Inc(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
  begin
    n := Pred(RowCount);
    if n > 0 then
      for i := 1 to n do
      begin
        val := Cells[1, i];
          { Значение поиска, введенное пользователем (если имеется) }
        if (CallingMode = modeSort)
          or (val <> '') then
        begin
          flds := flds + sep + Cells[0, i];
          sep := ';';
          nfld := Succ(nfld);
        end;
      end;

    with CallingGrid.DataSource.DataSet as TTable do
    begin
      IndexFieldNames := flds;
      if (CallingMode = modeSort)
        or (flds = '') then
      begin
        CancelRange;
      end
      else
      begin
        SetRangeStart;
        for i := 1 to n do
        begin
          val := Cells[1, i];
          if val <> '' then
          begin
            FieldByName(Cells[0, i]).AsString := val;
          end;
        end;

        {Устанавливаем конец диапазона так, чтобы он соответствовал его началу}
        SetRangeEnd;
        for i := 1 to n do
        begin
          val := Cells[1, i];
          if val <> '' then
          begin
            FieldByName(Cells[0, i]).AsString := val;
          end;
        end;
        ApplyRange;
      end;

      Refresh;
    end; { with CallingGrid.DataSource.DataSet }
  end; { with dlgQBF.gridQBF }

  dlgQBF.Hide;
end;

end.

Проект Delphi World © Выпуск 2002 - 2004
Автор проекта: ___Nikolay