Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Как научить VCL делать Refresh для запросов правильно

Delphi , Компоненты и Классы , TTable и TQuery

Как научить VCL делать Refresh для запросов правильно

Автор: Nomadic

Если вы чехол с компьютера снимаете чаще, чем платье с вашей подруги, то вы уже давно научный сотрудник.

Старо как мир, и нет ничего военного:


procedure RefreshQuery(Query: TQuery; F: boolean);
var
  B: TBookMark;
begin
  with Query do
    if Query.Active then
    begin
      B := GetBookMark;
      try
        Close;
        Unprepare;
        {Если не поставить этого, то если используется select
        SP, то иногда последующая операция вешает сервер.
        Кто скажет почему?!}
        Active := True;
        if F then
        begin
          try
            GotoBookMark(B)
          except
            on EDatabaseError do
              First;
          end
        end
        else
          First;
      finally
        FreeBookmark(B);
      end;
    end;
end;

Уфф! Кажется, лyчше yже не сделать. :)

dbtables можно опционально пpопатчить (см. в конце), чтобы иметь такой вот pyлезный Detail query.

Update for dbtables.pas

New interface function DoRefreshQuery can Refresh TQuery component in master-detail scheme and alone.

TQuery.RefreshParams should be updated


function GetFieldNamesStr(DataSet: TDataSet): string;
var
  I: Integer;
begin
  Result := '';
  with DataSet do
    for I := 0 to FieldCount - 1 do
    begin
      Result := Result + Fields[I].FieldName + ';';
    end;
end;

procedure DoRefreshQuery(Query: TQuery; KeyFields: string; BookMarkSearch:
  Boolean);
var
  Fields: TList;
  KeyValues: Variant;
  KeyNames: string;
  Bmk: TBookmark;
  I: Integer;
  BookmarkFound: Boolean;
  CanLocate: Boolean;
begin
  Fields := TList.Create;
  if KeyFields = '' then
    KeyFields := GetFieldNamesStr(Query);
  try
    Query.GetFieldList(Fields, KeyFields);
    for I := Fields.Count - 1 downto 0 do
      with TField(Fields[I]) do
        if Calculated or Lookup then
          Fields.Delete(I);
    CanLocate := Fields.Count > 0;
    if CanLocate then
    begin
      if Fields.Count = 1 then
        KeyValues := TField(Fields[0]).Value
      else
      begin
        KeyValues := VarArrayCreate([0, Fields.Count - 1], varVariant);
        KeyValues[0] := TField(Fields[0]).Value;
      end;
      KeyNames := TField(Fields[0]).FieldName;
      for I := 1 to Fields.Count - 1 do
      begin
        KeyNames := KeyNames + ';' + TField(Fields[I]).FieldName;
        KeyValues[I] := TField(Fields[I]).Value;
      end;
    end;
  finally
    Fields.Free;
  end;
  with Query do
  begin
    Bmk := nil;
    DisableControls;
    try
      BookmarkFound := False;
      if BookMarkSearch then
        Bmk := GetBookmark;
      Close;
      Open;
      if Assigned(Bmk) then
      try
        GotoBookMark(Bmk);
        BookmarkFound := True;
      except
      end;
      if not BookmarkFound and CanLocate then
        Locate(KeyNames, KeyValues, []);
    finally
      EnableControls;
      Screen.Cursor := crDefault;
      FreeBookmark(Bmk);
    end;
  end;
end;

procedure TQuery.RefreshParams;
var
  DataSet: TDataSet;
begin
  DisableControls;
  try
    if FDataLink.DataSource <> nil then
    begin
      DataSet := FDataLink.DataSource.DataSet;
      if DataSet <> nil then
        if DataSet.Active and (DataSet.State <> dsSetKey) then
          DoRefreshQuery(Self, GetFieldNamesStr(Self), False);
    end;
  finally
    EnableControls;
  end;
end;

Here's the translation of the content into Russian:

Компонент VCL Delphi для обновления запросов!

Процедура RefreshQuery предназначена для обновления компонента TQuery, который может использоваться в схеме мастер-деталь. Цель - обеспечить правильное обновление запроса при изменении underlying данных.

Вот разбивка кода:

  1. Метод GetBookMark получает текущий маркер для запроса.
  2. Если запрос активен, то он закрывается и дезактивируется перед повторной открытией с помощью Active := True.
  3. Если F истинно, то оно пытается вернуться к маркеру; если нет, то оно устанавливает первый запись как новый маркер.
  4. Наконец, оно освобождает маркер.

Процедура DoRefreshQuery - более полная реализация обновления запроса. Она принимает три параметра:

  • Query: компонент TQuery для обновления.
  • KeyFields: строка, содержащая имена полей, используемых для поиска ключа.
  • BookMarkSearch: булевое значение, указывающее, нужно ли искать маркер перед обновлением.

Вот, что она делает:

  1. Создает список полей из запроса и проверяет, есть ли среди них вычисляемые или просматриваемые; если да, то удаляет их из списка.
  2. Если параметр KeyFields пуст, то он устанавливается в результат вызова GetFieldNamesStr для запроса.
  3. Она пытается получить список полей для запроса с помощью GetFieldList.
  4. Если количество полей больше 0, то она:
    • Создает массив variant для значений ключа
    • Заполняет массив значениями из полей в списке ключевых полей
    • Устанавливает CanLocate в true, если есть хотя бы одно поле в списке ключевых полей.
  5. Она отключает контроли, закрывает и открывает запрос заново, а затем:
    • Если маркер найден, то она пытается вернуться к нему; если нет, то она ищет его с помощью ключевых полей.
  6. Наконец, она включает контроли снова.

Процедура TQuery.RefreshParams вызывается при изменении источника данных или активации данных. Она проверяет, является ли данные активными и находится ли в состоянии, отличном от dsSetKey, а затем вызывает DoRefreshQuery.

В целом, этот код должен помочь обновлять компоненты TQuery правильно при изменении underlying данных.

В вашем комментарии "Уфф! Кажется, лyчше yже не сделать. :)" - я думаю, вы просто выражаете радость и облегчение, что наконец-то написали работающий процедуру обновления запроса!

В статье описывается способ научить VCL делать Refresh для запросов правильно, используя процедуры RefreshQuery и DoRefreshQuery.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




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


:: Главная :: TTable и TQuery ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2024-12-26 14:21:52/0.003662109375/0