DBGrid и перемещение по набору данных

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Ответить
SergK
новенький
Сообщения: 21
Зарегистрирован: 05.03.2011 17:24:51

DBGrid и перемещение по набору данных

Сообщение SergK »

Добрый день!
Хочу найти решение следующей проблемы:
Есть DBGrid, ну и естественно, набор данных в нем отображаемый. В некоторый момент надо программно побегать но набору данных, вернувшись к исходной записи.
При этом хотелось бы чтобы видимое положение текущей записи в гриде относительно верхней и нижней границ DBGrid'а на экране осталось прежним.
Однако оно меняется.
Для делфи был, ну сейчас наверное, есть такой компонент TDBGridEh из библиотеки EhLib
Так у этого TDBGridEh компонента были (есть) методы SaveBookmark, RestoreBookmark.
Вот между вызовами этих методов можно было бегать с возвратом не только к той же записи в наборе но и положению этой записи относительно видимых границ.
Аватара пользователя
alexs
долгожитель
Сообщения: 4069
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь
Контактная информация:

Сообщение alexs »

В RxDBGrid я решал подобную задачу, когда делал расчёт итогов. В принципе можно сделать доступными эти методы.
Можно даже сделать аналогично EhLib. Какой там интерфейс предоставляется? Есть пример?
SergK
новенький
Сообщения: 21
Зарегистрирован: 05.03.2011 17:24:51

Сообщение SergK »

Какой там интерфейс предоставляется? Есть пример?

В смысле?
Как это выглядит в программе?
примерно так:

Код: Выделить всё

MyDBGridEh.SaveBookmark;
{ здесь перемещаемся по набору данных как хотим}
 .........
MyDBGridEh.RestoreBookmark;


Методы SaveBookmark, RestoreBookmark параметров не имеют.
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

SergK
Можно использовать закладки (bookmark) непосредственно самого набора данных:

Код: Выделить всё

Var
  bm: TBookMark;
Begin
  bm:=SQLQuery.GetBookmark; //Делаем закладку
  //Бегаем по записям
  .....
  SQLQuery.GotoBookmark(bm); //Возвращаемся на закладку
End;
Аватара пользователя
alexs
долгожитель
Сообщения: 4069
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь
Контактная информация:

Сообщение alexs »

Vadim
Этот метод вызовет смещение позиции в гриде. После завершения операции курсор будет установлен в центре грида.
pupsik
энтузиаст
Сообщения: 1154
Зарегистрирован: 20.08.2014 16:20:13
Контактная информация:

Сообщение pupsik »

можно и по другому... есть нюансы.

Код: Выделить всё

var
   i, z : integer;
begin
  With dataset do
  begin
    DisableControls ;
    z := RecNo;
    First;
    while not eof do
    begin
      inc(i);
      next;
    end;
    RecNo := z;
    EnableControls;
  end;
Аватара пользователя
alexs
долгожитель
Сообщения: 4069
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь
Контактная информация:

Сообщение alexs »

pupsik
все штатные методы вызывают смещение позиции курсора в видимой части грида. Это хорошо видно на больших наборах данных. Я не нашёл штатного метода. Пришлось внутри RxDBGrid-а для этого использовать хаки.
SergK
новенький
Сообщения: 21
Зарегистрирован: 05.03.2011 17:24:51

Сообщение SergK »

Ура, Ура проблема решена, как замечательно ;)
Хочу сказать Vadim и pupsik спасибо, кончено, за попытки ответов, Однако, то что вы отвечали, совсем не то что я спрашивал.
Естественно, то что у наборов данных есть методы GetBookmark и GotoBookmark(<bm>); я знаю. Это в каждой книжке по делфи написано на первой странице. (ну образно).
То что предлагает pupsik практически то же самое что и Vadim, ну воспользоваться вместо цивилизованного Bookmark номером записи в наборе данных.
Но, уважаемые, прав alexs после выполнения того что Вы привели текущая запись будет торчать окурат посреди видимой части грида. Если набор данных достаточно большой, чтобы полностью помещаться в видимой части.
А я хотел, чтоб она находилась в той же строчке видимой части грида, в которой была.
Спасибо большое надо сказать Dmitry V. Bolshakov автору EhLib.
Нашел я в загашнике EhLib, посмотрел реализацию методов SaveBookmark, RestoreBookmark. На самом деле все очень просто! Тестовый пример на Lazаrus работает так, как хотелось. :D
Правда Ваша alexs, надо получить как Вы пишите к использованием "хака" доступ к protected свойству у TCustomDBGrid, предку DbGrid, и и RxDbGrid.
alexs, раз Вы все равно реализовывали сию функциональность в RxDbGrid, зачем Вы спрятали ее в private, protected методы ? Кстати, там я ее не нашел :(, увы не разглядел.
Если кому либо интересна эта тема, то могу выложить исходники после того как более-менее причешу, то - что я насмотрел у Дмитрия Большакова.
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

alexs писал(а):Этот метод вызовет смещение позиции в гриде. После завершения операции курсор будет установлен в центре грида.

В DBGrid можно на время перемещения отключить реакцию на изменения.
pupsik
энтузиаст
Сообщения: 1154
Зарегистрирован: 20.08.2014 16:20:13
Контактная информация:

Сообщение pupsik »

то что я "предлагал" очень отличается от закладок... По существу есть еще стандартный вариант "закрепить" запись. Да и реализовать простенького наследника не сложно...

Нашел я в загашнике EhLib, посмотрел реализацию методов SaveBookmark, RestoreBookmark
хм... использование кода из комерческого компонента чревато. Хотя, кто на это смотрит... Окромя совести.

п.с.
Это хорошо видно на больших наборах данных.
эээ, а как это зависит от dbgrid. По идее отрисовывается видимое, а не все.... Хотя, в лазаре, это как-то витеевато работает...
Аватара пользователя
alexs
долгожитель
Сообщения: 4069
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь
Контактная информация:

Сообщение alexs »

Vadim писал(а):В DBGrid можно на время перемещения отключить реакцию на изменения.

А что будет после включения? Навсегда его не выключищьже :-)
SergK
новенький
Сообщения: 21
Зарегистрирован: 05.03.2011 17:24:51

Сообщение SergK »

Ну, во первых: Как обещал, мой пример решения проблемы: Исходный код демонстрашки по поводу проблемы и ее решения с откомпилированным под win exe'шником можно скачать отсюда,https://yadi.sk/d/Hw6Os62cdLiTs с моего яндекс диска.
Кнопка тест1 это то что получается при "стандартных подходах" это демонстрация проблемы.
Кнопка тест2 это решение проблемы.

Vadim, Я Вам просто удивляюсь. А Вы пробовали то о чем пишете? или Вы просто не понимаете что я хочу? (теперь уже хотел)
Ну сделаете Вы DisableControls, но потом то EnableControls Вы все равно сделать должны.
Ну и где будет текущая запись в гриде? Подсказываю: посередине грида, а вовсе не в той строке в которой была.
Ну специально для такого случая я маленькое видео сделал(ссылка http://rutube.ru/video/e6a2c92aee6267cafeacc621a356dc27/) может так понятнее. Там DisableControls c EnableControls присутствуют.

pupsik
хм... использование кода из комерческого компонента чревато

Ну Вы же используете в своих программах циклы ?? А в коммерческих программах они тоже есть...
Тут из той библиотеки лишь подсмотрено какие методы и свойства каких объектов можно использовать, и как до них добраться.
Эту информацию можно было бы из разных источников, из форумов, книг. Результат был бы тем же.

По поводу Вашего RecNo, Объясните уж в чем принципиальная разница ?
Это как скажем в небольшой компании запоминать человека по имени или прозвищу.
В отношении поднятой проблемы результат при использовании RecNo или BookMark будет тем же.
Ну если хотите в моей демонстрашке сделаю кнопку тест3 c Recno.
pupsik
энтузиаст
Сообщения: 1154
Зарегистрирован: 20.08.2014 16:20:13
Контактная информация:

Сообщение pupsik »

Код: Выделить всё

 FLookedOffset := DataLink.ActiveRecord - (DataLink.RecordCount div 2) + ((DataLink.RecordCount + 1) mod 2);

FLookedOffset := Datalink.ActiveRecord - (VisibleRowCount div 2);
- вроде и похоже, но отличается.... По сути, закладка берется в "центре" сетки и после перемещаем на корректную запись. При этом курсор как бы остается на месте.

Цикл - хм... разве в процедуре используется цикл?

По поводу Вашего RecNo, Объясните уж в чем принципиальная разница ?
когда поймете где в моем коде надо применить moveby .... Хотя, когда поймете, обяснять уже не надо :wink:
Ответить