Delphi - восстанавливает фактическую строку в DBGrid

D6 профессор.

Раньше мы использовали DBISAM и DBISAMTable. Тот дескриптор RecNo, и это работает хорошее с модификациями (Удалите, отредактируйте, и т.д.).

Теперь мы заменили ElevateDB, которые не обрабатывают RecNo, и много раз мы используем Запросы, не Таблицы.

Запрос должен вновь открыться для наблюдения модификаций.

Но если мы Вновь открыли Запрос, нам нужно к тому, чтобы менять местоположение к последней записи. Найдите не достаточно, потому что Сетка является шоу это в другой строке. Это - очень тревожащая вещь, потому что после того, как запись модификации перемещается в другую строку, Вы трудно для следования за нею, и пользователи ненавидят это.

Мы нашли этот код:

function TBaseDBGrid.GetActRow: integer;
begin
 Result := -1 + Row;
end;


procedure TBasepDBGrid.SetActRow(aRow: integer);
var
 bm : TBookMark;
begin
 if IsDataSourceValid(DataSource) then with DataSource.DataSet do begin
  bm := GetBookmark;
  DisableControls;
  try
   MoveBy(-aRow);
   MoveBy(aRow);
   //GotoBookmark(bm);
  finally
   FreebookMark(bm);
   EnableControls;
  end;
 end;
end;

Исходным примером является использование moveby. Эта работа, хорошая с Запросами, потому что мы не видим, что Запрос, вновь открытый в фоновом режиме, визуальный контроль, не сменился положение строки.

Но когда у нас есть EDBTable или Живой/Чувствительный Запрос, MoveBy опасен для использования, потому что, если кто-то удаляет или добавляет новую строку, мы можем переместить в неправильную запись.

Затем я пытался использовать BookMark (см. комментарий). Но эта техника не работает, потому что это - шоу запись в другом положении строки...

Так вопрос: как вынудить обоих положение строки и запись в DBGrid?

Или какой DBGrid может переместить к записи/строке после базового обновленного DataSet?

Я ищу удобное для пользователя решение, я понимаю их, потому что я пытался использовать этот переход - через DBGrid и очень плохо использовать, потому что мои глаза выходят когда попытка найти исходную запись после обновления... :-(

Спасибо за Вашу каждую справку, ссылку, информацию: dd

5
задан durumdara 8 June 2010 в 08:12
поделиться

4 ответа

Поскольку MoveBy работают на вас, используйте их.

Установите закладку перед закрытием набора данных. Выполняйте свою работу, повторно откройте набор данных, а затем переместите свою запись в сетку с помощью «MoveBy's. Когда вы закончите, получите еще одну закладку и сравните ее с предыдущей с помощью DataSet.CompareBookmarks. Если результат 0 - нормально, если нет, то только тогда сделайте «GotoBookmark» для предыдущей закладки.

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


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

type
  TAccessDBGrid = class(TDBGrid);

procedure TForm1.Button1Click(Sender: TObject);
var
  BmSave, Bm: TBookmark;
  GridRow, TotalRow: Integer;
begin
  GridRow := TAccessDBGrid(DBGrid1).Row;
  TotalRow := TAccessDBGrid(DBGrid1).RowCount;
  BmSave := DBGrid1.DataSource.DataSet.GetBookmark;
  try

    // close dataset, open dataset...

    if DBGrid1.DataSource.DataSet.BookmarkValid(BmSave) then
      DBGrid1.DataSource.DataSet.GotoBookmark(BmSave);
    Dec(TotalRow);
    if GridRow < TotalRow div 2 then begin
      DBGrid1.DataSource.DataSet.MoveBy(TotalRow - GridRow);
      DBGrid1.DataSource.DataSet.MoveBy(GridRow - TotalRow);
    end else begin
      if dgTitles in DBGrid1.Options then
        Dec(GridRow);
      DBGrid1.DataSource.DataSet.MoveBy(-GridRow);
      DBGrid1.DataSource.DataSet.MoveBy(GridRow);
    end;
    Bm := DBGrid1.DataSource.DataSet.GetBookmark;
    try
      if (DBGrid1.DataSource.DataSet.BookmarkValid(Bm) and
          DBGrid1.DataSource.DataSet.BookmarkValid(BmSave)) and
          (DBGrid1.DataSource.DataSet.CompareBookmarks(Bm, BmSave) <> 0) then
        DBGrid1.DataSource.DataSet.GotoBookmark(BmSave);
    finally
      DBGrid1.DataSource.DataSet.FreeBookmark(Bm);
    end;
  finally
    DBGrid1.DataSource.DataSet.FreeBookmark(BmSave);
  end;
end;
8
ответ дан 14 December 2019 в 01:02
поделиться

Сохраните значение(я) поля(й) уникального ключа перед закрытием и повторным открытием запроса, затем Найдите запись после повторного открытия. DisableControls/EnableControls для предотвращения обновления экрана.

1
ответ дан 14 December 2019 в 01:02
поделиться

Просто простой фрагмент кода, который пришел мне в голову:

procedure DoRefresh(Dataset: TDataset);
var
  bkm: TBookmark;
begin
  Dataset.UpdateCursorPos;
  bkm := Dataset.GetBookmark;
  Dataset.DisableControls;
  try
    Dataset.Refresh;  //refresh dataset if it's open

    if Dataset.BookmarkValid(bkm) then
    begin
      Dataset.GotoBookmark(bkm);
    end;
  finally
    Dataset.EnableControls;
    Dataset.FreeBookmark(bkm);
  end;
end;
0
ответ дан 14 December 2019 в 01:02
поделиться

Позиция записи во многом зависит от порядка сортировки набора результатов, полученного из объекта Query / Table. Если вы не заказываете вообще, порядок, который вы получаете от сервера, определяется реализацией и так далее, не может гарантировать, что записи поступят в том же порядке при повторном открытии запроса , даже если никаких изменений не произошло . По крайней мере, в MSSQL и Firebird результаты приходят в разном порядке, если не используется предложение Order By .

Что касается изменения положения, я считаю, что решение TOndrej является наиболее безопасным - использование первичного ключа набора результатов для изменения положения сетки на правой записи.

0
ответ дан 14 December 2019 в 01:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: