Синхронизация DBGrid с Данными: Автоматическое Обновление Позиции Просмотра
Вопрос пользователя заключается в том, как синхронизировать позицию просмотра в DBGrid с данными, которые обновляются в подлежащем набору данных, особенно в случае использования ElevateDB и запросов, а не таблиц. Проблема заключается в том, что после обновления данных, позиция активной записи может измениться, и пользователю становится сложно отслеживать нужную запись.
Проблема
Используя ранее DBISAM и DBISAMTable, разработчики успешно работали с модификациями данных, включая удаление и редактирование. Однако после перехода на ElevateDB, который не поддерживает RecNo, и использования запросов вместо таблиц, возникла необходимость переоткрывать запросы для отображения изменений. Это приводит к тому, что пользователю необходимо заново позиционировать просмотр на последнюю запись. Простой вызов Locate не решает проблему, так как DBGrid отображает запись в другом ряду, что вызывает неудобства в использовании.
Решение
Пользователь нашел код, который использует MoveBy для перемещения к нужной записи. Этот метод работает хорошо с запросами, так как внешне кажется, что запрос не переоткрывается, и визуальный контроль не изменяет позицию ряда. Однако, при использовании EDBTable или "живых" запросов, MoveBy может быть опасным, так как при удалении или добавлении записей, позиция может оказаться неверной.
Один из пользователей предложил хранить значения уникальных ключевых полей перед закрытием и переоткрытием запроса, а затем использовать Locate для поиска записи после переоткрытия. Также было предложено отключать обновление экрана с помощью DisableControls/EnableControls.
Подтвержденное Решение
Пользователю было рекомендовано использовать MoveBy, так как они работали для него. Предложено было получить "Bookmark" перед закрытием набора данных, выполнить необходимые действия, переоткрыть набор данных, а затем перепозиционировать запись в DBGrid с помощью MoveBy. После завершения работы следует получить новый "Bookmark" и сравнить его с предыдущим с помощью DataSet.CompareBookmarks. Если результаты сравнения не совпадают, следует вызвать GotoBookmark для предыдущего "Bookmark".
Таким образом, пока другие пользователи не удаляли/добавляли записи, DBGrid не будет "прыгать", и если это произошло, вы все равно окажетесь на той же записи.
Пример Кода
Вот пример кода, который позволяет перепозиционировать выбранную запись в правильное место даже после удалений/добавлений записей в наборе данных:
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
// Закрытие набора данных, открытие набора данных...
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;
Заключение
Позиция записи в результате запроса сильно зависит от порядка сортировки результирующего набора. Если не использовать Order By, порядок записей может изменяться при каждом переоткрытии запроса, даже если изменения не производились. Наиболее безопасный способ перепозиционирования - использование первичного ключа результирующего набора для перемещения DBGrid на нужную запись.
Вопрос пользователя касается синхронизации позиции просмотра в `DBGrid` с данными после их обновления, особенно в контексте использования `ElevateDB` и запросов, и поиска эффективного способа автоматического обновления позиции просмотра.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.