скрыть

скрыть

  Форум  

Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Google  
 

Модуль, позволяющий в 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.






Copyright © 2004-2016 "Delphi Sources". Delphi World FAQ




Группа ВКонтакте   Ссылка на Twitter   Группа на Facebook