Creo que depende de la implementación de Bookmark.
- En algunos casos guarda el nro. de registro, por lo que mantiene la posición en el Grid, pero no necesariamente el registro de la base de datos.
- En otros casos guarda algo relacionado con el registro de la base de datos, con lo que no necesariamente se posicionará en el mismo sitio en el grid.
En ambos casos si no se encuentra Bookmark dará un error (exception).
Yo suelo utilizar alguna de estas dos variantes para casos simples:
Código Delphi
[-]
procedure RefrescaTabla(Tabla : TDataSet);
var
mark : TBookmark;
begin
with Tabla do
begin
mark := GetBookmark;
try
Close;
Open;
if BookmarkValid(mark) then
GotoBookmark(mark);
finally
FreeBookmark(mark);
end;
end;
end;
Código Delphi
[-]
procedure RefrescaTabla(Tabla : TDataSet);
var
mark : TBookmark;
begin
with Tabla do
begin
mark := GetBookmark;
try
Close;
Open;
try
GotoBookmark(mark);
except
Last;
end;
finally
FreeBookmark(mark);
end;
end;
end;
Y esta variante cuando necesito mantener la posición del registro de la tabla SQL (
no la posición en el grid.)
Código Delphi
[-]
procedure Posicionar(DataSet: TDataSet; CampoId: string; Id: integer; Aproximada: boolean = False; DesdeElFinal: boolean = False); overload;
procedure Refrescar(DataSet: TDataSet; CampoId: string; Id: integer; Aproximada: boolean = False; DesdeElFinal: boolean = False); overload;
procedure Posicionar(DataSet: TDataSet; CampoId: string; Id: string; Aproximada: boolean = False; DesdeElFinal: boolean = False); overload;
procedure Refrescar(DataSet: TDataSet; CampoId: string; Id: string; Aproximada: boolean = False; DesdeElFinal: boolean = False); overload;
procedure Refrescar(DataSet: TDataSet; CampoId: string; Id: integer; Aproximada: boolean = False; DesdeElFinal: boolean = False); overload;
begin
with DataSet do
begin
DisableControls;
try
if Active then
Close;
Posicionar(DataSet, CampoId, Id, Aproximada, DesdeElFinal);
finally
EnableControls;
end;
end;
end;
procedure Posicionar(DataSet: TDataSet; CampoId: string; Id: integer; Aproximada: boolean = False; DesdeElFinal: boolean = False); overload;
begin
with DataSet do
begin
DisableControls;
try
if not Active then
Open;
if Aproximada then
begin
if DesdeElFinal then
begin
Last;
while ((not BOF) and (FieldByName(CampoId).AsInteger > id)) do
Prior;
end
else
begin
First;
while ((not EOF) and (FieldByName(CampoId).AsInteger < id)) do
Next;
end;
end
else
begin
if DesdeElFinal then
begin
Last;
while ((not BOF) and (FieldByName(CampoId).AsInteger <> id)) do
Prior;
end
else
begin
First;
while ((not EOF) and (FieldByName(CampoId).AsInteger <> id)) do
Next;
end;
end;
finally
EnableControls;
end;
end;
end;