Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Так всё-таки, что такое TBookMark?


Ega23 ©   (2005-07-08 13:14:00) 

Вот столкнулся с такой штукой:

Function QuOpen(Qu: TDataSet;sql:string='*';refr:boolean=true;mess:string='*'):integer;
//  Открытие запроса с возможностями
//  - замены текста(sql),
//  - рефреша с восстанавлением текущей позиции
//  - вывода сообщения об ошибке
// Параметры
//sql:  '*'  (default)  - не менять текст запроса
//refr: true (default) производить  рефреш данных
//mess : '*' (default) - standart mess;
//       ''            - no mess
//       '..some mess' - custom message
//result:  Ok -RecordCount; can't open -1;
var  realsqltext:string;
   BookMk: TBookmark;
begin
result:=-1;
 if GpNoConnectGlb then exit;
 BookMk:=nil;
Try
try
 qu.DisableControls;
 //заложить закладку и закрыть
  if Qu.Active then
  begin
    BookMk := Qu.GetBookmark;
    Qu.Close;
  end;
 //текст запроса
  if sql<>'*' then (Qu as TADOQuery).sql.text:=sql;
  realsqltext:=sql;
  //Уже Открыть !
  Qu.open;
except on E:exception do
      Begin
        if mess='*' then ShowMessage('Ошибка запроса')
                     else  if mess<>'' then ShowMessage(Mess);
         raise EGPException.Create(e.message+' '+mess+ ' '+realsqltext);
       End;
end;//try

  // ЕСли просят рефреша - вот он
  if refr then
   try
    if Qu.Active and (BookMk <> nil) and not (qu.Bof and qu.Eof) and
      qu.BookmarkValid(BookMk)
      then  qu.GotoBookmark(BookMk);
    except
    end;
result:=Qu.recordcount;
if result< 0 then exit;
Finally
  qu.EnableControls;
    if BookMk <> nil then qu.FreeBookmark(BookMk);
End; //try fin
end;


При использовании данной функции для обновления НД в собственном компоненте, вижу, что данные не обновляются. Точнее, не происходит событие TDataLink.activeChanged

С другой стороны, если для обновления НД сделать элементарное Close/Open - событие возникает.

Есть вопрос: в каком контексте используется TBookMark? Чей это атрибут? Непосредственно текущего набора данных, или всё-таки "вещь в себе"?


atruhin   (2005-07-08 19:17:00) [1]

>>Val ©   (08.07.05 18:01) [15]
>>угу. было 5 записей, после переоткрытия 3. закладка стояла на 4 >>номере.
Поставит на последнюю. Вообще я полностью согласен что так делать нельзя. Просто попытался прояснить по САБЖу. Хотя в некоторых случаях, например переоткрытие не меняет ни порядок, ни кол-во, а только некоторое поле, это может пройти на конкретном потомке датасета.


Val   (2005-07-08 18:01:00) [2]

угу. было 5 записей, после переоткрытия 3. закладка стояла на 4 номере.


atruhin   (2005-07-08 17:53:00) [3]

>>Digitman ©   (08.07.05 13:45) [2]
>>как только ты вызвал close, набор данных (на одну из записей >>которого закладка "ссылалась") перестал существовать и закладка >>стала попросту бессмысленной.
В общем случае не совсем верно, т.к. закладка реализуется наследником датасета, он лишь должен ее реализовать. В наследнике закладка может быть реализована как указатель, например если буфер хранится в виде списка, а может быть просто порядковым номером записи в текущем буфере, тогда валидность сохраняется и после переоткрытия.


Digitman   (2005-07-08 15:28:00) [4]

Refresh и есть "обновление открытого набора данных".

о каком еще обновлении ты ведешь речь ?


Ega23   (2005-07-08 15:21:00) [5]

рефреш и close+open - некоторым образом разные разницы

Я имел ввиду не TDataSet.Refresh, а само понятие "обновление".


Digitman   (2005-07-08 15:18:00) [6]


> чтобы при рефреше оставалась нужная позиция


рефреш и close+open - некоторым образом разные разницы


Ega23   (2005-07-08 15:15:00) [7]

2 Digitman ©   (08.07.05 14:11) [7]
Project -> Options -> Compiler -> Use Debug DCU's = Yes

Спасибо, очень помогло.
Действительно, функция, описанная в [0] работает некорректно.
Как её переделать - это отдельный вопрос (чтобы при рефреше оставалась нужная позиция), кое-какие идеи уже появились.


Digitman   (2005-07-08 14:22:00) [8]


> А если не текст, а сам НД на сервере изменился?


тем более на закладку полагаться нельзя !


> Для финальной сборки, как я понимаю, эту опцию потом надо
> будет снять?


крайне желательно


Ega23   (2005-07-08 14:15:00) [9]

Project -> Options -> Compiler -> Use Debug DCU's = Yes

Спасибо. Для финальной сборки, как я понимаю, эту опцию потом надо будет снять? Или неважно?

до тех пор пока текст сиквел-запроса между смежными close-open не изменился, букмарк м.б. и будет при этом оставаться валидным, но полагаться на это нельзя

А если не текст, а сам НД на сервере изменился? Допустим, я Insert в эту таблицу сделал?


Digitman   (2005-07-08 14:11:00) [10]


> Да, но с сохранением bookmark'а


до тех пор пока текст сиквел-запроса между смежными close-open не изменился, букмарк м.б. и будет при этом оставаться валидным, но полагаться на это нельзя

если интересно, исследуй упр.структуру, скрывающуюся за букмарк-указателем для конкретного наследника TDataSet


> как мне это сделать?


Project -> Options -> Compiler -> Use Debug DCU's = Yes


Ega23   (2005-07-08 14:04:00) [11]

в [0] тобой точно так же используются те же Close-Open

Да, но с сохранением bookmark'а.


function TDataSet.GetBookmark: TBookmark;
begin
 if BookmarkAvailable then
 begin
   GetMem(Result, FBookmarkSize);
   GetBookmarkData(ActiveBuffer, Result);
 end else
   Result := nil;
end;

procedure TCustomADODataSet.GetBookmarkData(Buffer: PChar; Data: Pointer);
begin
 Initialize(POleVariant(Data)^);
 POleVariant(Data)^ := PRecInfo(Buffer).Bookmark;
end;


Получается, что при наличии букмарка, мой экземпляр TDataLink моего компонента не ловит событие TDataLink.ActiveChanged

Вопрос: а если я захочу пройтись отладчиком по внутренним методам TADOQuery, то как мне это сделать? Сейчас я по F7 туда не проваливаюсь, да и если точку останова ставлю, то всё равно к ней не прихожу. Может, чё-то в настройках Delphi надо поставить?


Digitman   (2005-07-08 13:57:00) [12]


> Ega23 ©   (08.07.05 13:52) [4]


в [0] тобой точно так же используются те же Close-Open

??


Ega23   (2005-07-08 13:52:00) [13]

2 Digitman ©   (08.07.05 13:45) [2]
как только ты вызвал close, набор данных (на одну из записей которого закладка "ссылалась") перестал существовать и закладка стала попросту бессмысленной.

Не совсем так получается.
Простой пример: ADOQery, запрос на Select, DataSource, DBGrid.
Открываем запрос. Встаём в гриде на, скажем, третью запись. Переоткрываем запрос с помощью функции (см. [0]). курсор остался на третьей записи.
Переоткрываем запрос с помощью Close - Open. Курсор встал на первую запись.
Значит всё-таки букмарки не совсем "убиваются"?


Desdechado   (2005-07-08 13:48:00) [14]

по сабжу - это адрес, по которому расположена запись открытого датасета
после закрытия/переоткрытия по тому адресу будет хз что


Digitman   (2005-07-08 13:45:00) [15]


> что такое TBookMark?


TBookmark identifies a record in a datasetfor later navigation

как только ты вызвал close, набор данных (на одну из записей которого закладка "ссылалась") перестал существовать и закладка стала попросту бессмысленной.


Val   (2005-07-08 13:32:00) [16]

заложить закладку и закрыть. отлично. и что поимеем?


Наверх

Титульная страница Поиск, карта сайта Написать письмо