Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Recuperar BookMark despues de cerrar dataset... (https://www.clubdelphi.com/foros/showthread.php?t=72069)

verito_83mdq 26-01-2011 15:56:16

Recuperar BookMark despues de cerrar dataset...
 
Hola Como andan todos?? Acá tengo una complicación la cual estuve buscando acá en el foro pero no encuentro un caso similar.

El problema es el siguiente tengo un dbGrig conectado al datasource y este al ZQuery, hago la búsqueda y despues le asigno una marca
Código Delphi [-]
PrevRecord := Buscarform.ClientesDBGrid.DataSource.DataSet.GetBookmark;

despues abro un form donde listo los datos y en este form puedo modificar los datos, para hacer esto tengo que cerrar el Query Clientes y abrirlo con la sentencia Update. El problema es que al cerrar el query pierdo la marca arrojandome este error:''cannot perform this operation on a closed dataset''
lo cual es logico si yo antes la cerre.

Estuve tratando de buscarle una solución pero con todo tenia problema.
Espero que me puedan dar una mano. Desde ya muchas gracias.

Chris 26-01-2011 17:42:19

El problema es que no se sabe en que momento tomas el Bookmark. Con el ínfimo código que has puesto es muy difícil de saberlo. Así que cualquier intento de ayudar será como golpe de ciego.

Saludos,
Chris

ecfisa 26-01-2011 18:08:00

Hola.

Como dice Chris, creo que el problema esta donde tomás el Bookmark, el alcance de la variable donde se almacena o si es modificada en algún punto, ya que el echo de cerrar la consulta no afecta a la variable TBookmarkStr.

Te pongo un ejemplo simple por si te sirve de ayuda:
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
var
  BM: TBookmarkStr;
begin
  // Mostrar algunos datos...
  IBQuery1.SQL.Clear;
  IBQuery1.SQL.Add('SELECT * FROM COUNTRY');
  IBQuery1.Open;
  IBQuery1.MoveBy(4);      // Desplazarse 4 registros
  // Antes de modificar, guardar la posición actual del DataSet
  BM:= DBGrid1.DataSource.DataSet.Bookmark; 
  IBQuery1.Close;
  // Modificar algo...
  IBQuery1.SQL.Clear;
  IBQuery1.SQL.Add('UPDATE COUNTRY');
  IBQuery1.SQL.Add('SET CURRENCY = :MONEDA');
  IBQuery1.SQL.Add('WHERE COUNTRY = :PAIS');
  IBQuery1.ParamByName('PAIS').AsString:= 'Japan';
  IBQuery1.ParamByName('MONEDA').AsString:= 'Yin';
  IBQuery1.ExecSQL;
  IBQuery1.Close;
  // Mostrar datos
  IBQuery1.SQL.Text:= 'SELECT * FROM COUNTRY';
  IBQuery1.Open;
  // Mover a posición almacenada en BM
  DBGrid1.DataSource.DataSet.Bookmark := BM; 
end;

Un saludo.

verito_83mdq 26-01-2011 18:16:41

Hola Chris! Gracias por contestar!! Bueno ahora pongo el código y explico, hay código que esta fuera de contexto pero igual pongo los procedimientos completos.


1-Busco Cliente, Selecciono cliente en el dbGrig y pongo ver datos.



Código Delphi [-]
 procedure TBuscarForm.DatosClienteBitBtnClick(Sender: TObject); 
begin 
 
 
              flag:=False; 
              PrevRecord := Buscarform.ClientesDBGrid.DataSource.DataSet.GetBookmark; 
              r:=QueryDataModule.ClienteZQuery.FieldByName('ID_Cliente').Value; 
 
              with QueryDataModule.ObservacionClienteZQuery do 
               begin 
                 If active then close; 
                 SQL.Clear; 
                 SQL.Add('Select * from observacion_cliente where observacion_cliente.ID_Cliente='+r+''); 
                 Open; 
               end; 
 
               //Prioridad Nula 
 
               if QueryDataModule.ObservacionClienteZQuery.FieldByName('ID_Prioridad').IsNull  then 
                 begin 
                  if flag=false then 
                    begin 
                     BuscarForm.Visible:=False; 
                     flag:=true; 
                     ListarDatoClienteForm:=TListarDatoClienteForm.Create(Application); 
                    end; 
                 end; 
 
 
 
 
 
 
                //Prioridad Baja 
                if QueryDataModule.ObservacionClienteZQuery.FieldByName('ID_Prioridad').Value =1 then 
                 begin 
                  if flag=false then 
                    begin 
                     BuscarForm.Visible:=False; 
                     flag:=true; 
                     ListarDatoClienteForm:=TListarDatoClienteForm.Create(Application); 
                    end; 
                 end; 
 
 
 
 
 
 
               //Prioridad Normal 
               if QueryDataModule.ObservacionClienteZQuery.FieldByName('ID_Prioridad').Value =2 then 
                 begin 
                   if flag=false then 
                     begin 
                       showmessage('Usted deberia leer las observaciones'); 
                       BuscarForm.Visible:=False; 
                       flag:=true; 
                       ListarDatoClienteForm:=TListarDatoClienteForm.Create(Application); 
                     end; 
                 end; 
 
 
 
                //Prioridad Alta 
                if QueryDataModule.ObservacionClienteZQuery.FieldByName('ID_Prioridad').Value =3 then 
                    begin 
                      if flag=false then 
                        begin 
                         BuscarForm.Visible:=False; 
                         flag:=true; 
                         ListarObservacionesForm:=TListarObservacionesForm.Create(Application); 
                         if flag=false then 
                         ListarDatoClienteForm:=TListarDatoClienteForm.Create(Application); 
                        end; 
                     end; 
 
 
 
end;





2-En el Form Create asigno los Edit.



Código Delphi [-]
procedure TListarDatoClienteForm.FormCreate(Sender: TObject); 
begin 
 
 
              ActualizarActivadoPngSpeedButton.Visible:=False; 
 
 
 
 
 
              //Datos Cliente 
 
              ApellidoEdit.Text:=QueryDataModule.ClienteZQuery.FieldByName('Apellido').AsAnsiString; 
              NombreEdit.Text:=QueryDataModule.ClienteZQuery.FieldByName('Nombre').AsAnsiString; 
              DNIEdit.Text:=QueryDataModule.ClienteZQuery.FieldByName('DNI').AsAnsiString; 
              ListarFechaNacimientoDateTimePicker.Date:=QueryDataModule.ClienteZQuery.FieldByName('Fecha_Nacimient  o').AsDateTime; 
              DireccionEdit.Text:=QueryDataModule.ClienteZQuery.FieldByName('Direccion').AsAnsiString; 
              TelefonoEdit.Text:=QueryDataModule.ClienteZQuery.FieldByName('Telefono').AsAnsiString; 
              ConyugeCheckBox.Checked:=QueryDataModule.ClienteZQuery.FieldByName('Conyuge').Value; 
              ObservacionesCheckBox.Checked:=QueryDataModule.ClienteZQuery.FieldByName('Observaciones_Check').Valu  e; 
              CelularEdit.Text:=QueryDataModule.ClienteZQuery.FieldByName('Celular').AsAnsiString; 
              E_MailEdit.Text:=QueryDataModule.ClienteZQuery.FieldByName('E_Mail').AsAnsiString; 
              OcupacionDBLookupComboBox.KeyValue:=QueryDataModule.ClienteZQuery.FieldByName('ID_Ocupacion').Value; 
              ProveedorMailDBLookupComboBox.KeyValue:=QueryDataModule.ClienteZQuery.FieldByName('ID_Proveedor_Mail  ').Value; 
               
 
 
 
               //Fecha Ingreso al Sistema 
 
 
              IngresoSistemaDiaLabel.Caption := FormatDateTime('dddd yyyy/mm/dd', QueryDataModule.ClienteZQuery.FieldByName('Fecha_Ingreso_Sistema').AsDateTime); 
              IngresoSistemaHoraLabel.Caption:= FormatDateTime('hh:nn:ss', QueryDataModule.ClienteZQuery.FieldByName('Fecha_Ingreso_Sistema').AsDateTime); 
 
 
 
              //Datos en color rojo o verde, segun el estado. 
              if QueryDataModule.ClienteZQuery.FieldByName('Baja').Value=1 then 
                  begin 
                      showmessage('Atencion Cliente Rescindido'); 
                      Self.Font.Color:=clred; 
                      ListarFechaNacimientoDateTimePicker.Font.Color:=clred; 
                  end 
 
 
              else 
                  begin 
                      Self.Caption:='Cliente Activo'; 
                      Self.Font.Color:=clgreen; 
                      ListarFechaNacimientoDateTimePicker.Font.Color:=clgreen; 
                  end; 
 
end;







3-Cuando se modifica un TEdit se habilita el boton Actulizar.







Código Delphi [-]
procedure TListarDatoClienteForm.ActualizarActivadoPngSpeedButtonClick( 
  Sender: TObject); 
begin 
 
 
           with QueryDataModule.ClienteZQuery do 
               begin 
                 If active then close; 
                   SQL.Clear; 
                   SQL.Add('Update cliente set '); 
                   SQL.Add('Apellido='''+ApellidoEdit.Text+''', '); 
                   SQL.Add('Nombre='''+NombreEdit.Text+''', '); 
                   SQL.Add('DNI='''+DNIEdit.Text+''', '); 
                   SQL.Add('Fecha_Nacimiento=:FechaNacimiento,'); 
                   ParamByName('FechaNacimiento').Value:=ListarFechaNacimientoDateTimePicker.DateTime; 
                   SQL.Add('ID_Ocupacion=:Ocupacion,'); 
                   ParamByName('Ocupacion').Value:=OcupacionDBLookupComboBox.KeyValue; 
                   SQL.Add('ID_Proveedor_Mail=:Proveedor,'); 
                   ParamByName('Proveedor').Value:=ProveedorMailDBLookupComboBox.KeyValue; 
                   //SQL.Add('ID_Ciudad='''+NombreEdit.Text+''', '); 
                   SQL.Add('Direccion='''+DireccionEdit.Text+''', '); 
                   SQL.Add('Telefono='''+TelefonoEdit.Text+''', '); 
                   SQL.Add('Celular='''+CelularEdit.Text+''', '); 
                   SQL.Add('E_Mail='''+E_MailEdit.Text+''' '); 
                   SQL.Add('Where cliente.ID_Cliente='+r+''); 
                   ExecSQL; 
               end; 
 
 
 
 
 
 
end;



4-Una vez que Actualice hago click en el boton volver, para retornar al DBGrig y en este momento es cuando me da ese error.





Código SQL [-]
 procedure TListarDatoClienteForm.AnteriorPngSpeedButtonClick( 
  Sender: TObject); 
begin 
 
 
                BuscarForm.Visible:=True; 
                //BuscarForm.BuscarPngSpeedButtonClick(Sender); 
 
                BuscarForm.ClientesDBGrid.DataSource.DataSet.GotoBookmark(PrevRecord); 
                release; 
                 
 
end;


Bueno esos son los pasos, espero que sirva ahora. Gracia Chriss y ecfisa!!!!!

verito_83mdq 26-01-2011 18:23:09

jajaja no se pueden quejar, querían código ahí tienen!!!:D

La variable PrevRecord la tengo declarada como variable global pero de tipo PrevRecord: TBookmark;
y veo que ecfisa la declaro de tipo TBookmarkStr , sera eso? que es el Str que tiene adicional? string?
Saludos!!

ecfisa 26-01-2011 18:27:52

Cita:

Empezado por verito_83mdq (Mensaje 388933)
jajaja no se pueden quejar, querían código ahí tienen!!!:D

Ufff!!!! Dame tres días para revisarlo y te contesto... :D:D:D

Un saludo.

ecfisa 26-01-2011 18:35:41

Cita:

Empezado por verito_83mdq (Mensaje 388933)
La variable PrevRecord la tengo declarada como variable global pero de tipo PrevRecord: TBookmark;
y veo que ecfisa la declaro de tipo TBookmarkStr , sera eso? que es el Str que tiene adicional? string?
Saludos!!

Hacen lo mismo pero TBookmarkStr es más simple de usar:
TBookmark:
Código Delphi [-]
var
  BM: TBookmark;
begin
  BM:= DataSet.Bookmark;
  try
    DataSet.MoveBy(10);
  finally
    DataSet.GotoBookmark(BM);
    DataSet.FreeBookmark(BM);  // liberar memoria
  end;
end;

TBookmarkStr:
Código Delphi [-]
var
  BM: TBookmarkStr;
begin
  BM:= DataSet.Bookmark;
  try
    DataSet.MoveBy(10);
  finally
    DataSet.Bookmark:= BM;  //Delphi libera la memoria de forma automática
  end;
end;

Aparte de que es más eficiente asignar valor a una propiedad, que llamar al procedimiento GotoBookmark.

Un saludo.

Chris 26-01-2011 20:31:38

BuscarForm.ClientesDBGrid.DataSource.DataSet es lo mismo que QueryDataModule.ClienteZQuery? Si son lo mismo entonces puede ser que el problema sea que no estes volviendo abrir QueryDataModule.ClienteZQuery con la consulta para presentar los datos.

Saludos,
Chris

verito_83mdq 26-01-2011 21:08:30

Hola Chriss, gracias a todos!!! Si es lo mismo, osea el DBGrid trabaja con el mismo Query (ClienteZQuery). Como seria eso de volver a abrir?
Te referís a que tengo que hacer un Select previo a la sentencia de Bookmark?

Muchas gracias!!!!

Chris 26-01-2011 21:30:20

Cita:

Empezado por verito_83mdq (Mensaje 388948)
Te referís a que tengo que hacer un Select previo a la sentencia de Bookmark?

Exactamente amigo!

verito_83mdq 27-01-2011 00:03:18

Bueno estoy tratando de resolverlo, gracias a Chris y a ecfisa me quedo mas claro, el ejemplo que puso ecfisa es muy bueno y ayuda bastante.

Por ahora les digo Gracias a los dos! ;)

Saludos!!!


La franja horaria es GMT +2. Ahora son las 01:40:41.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi