![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Так всё-таки, что такое 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]заложить закладку и закрыть. отлично. и что поимеем?