Ir al contenido


Foto

[RESUELTO] Borrar registros en un ClientDataSet


  • Por favor identifícate para responder
14 respuestas en este tema

#1 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.446 mensajes
  • LocationMéxico

Escrito 08 febrero 2010 - 12:30

Hola

Estoy trabajando com un ClientDataSet donde agrego registros 'temporales' para que al terminar de agregar los registros que requiero hacer algunos procesos definitivos.

Hasta aquí todo funciona a la perfección, el detalle que se me presenta en este momento es que necesito borrar algunos registros  (por X causa), esto lo puedo hacer asignando la propiedad Multiselect del dbgrid y presionando Ctrl+Del, sin embargo, quiero hacer esto desde Delphi.

Los registros a borrar cuentan con un campo igual, por ejemplo, todos los registros que en su campo Descripción sea igual a 'COMEDOR'.

Espero que haya sido claro :)

Salud OS
  • 0

#2 seoane

seoane

    Advanced Member

  • Administrador
  • 1.259 mensajes
  • LocationEspaña

Escrito 08 febrero 2010 - 02:44

Pues que yo sepa no se pueden ejecutar consultas SQL en un ClientDataSet, pero si podemos usar un filtro y hacer un apaño  :D

Por ejemplo, si creamos un ClientDataSet como este:


delphi
  1. var
  2.   tbPrueba: TClientDataSet; // Esta es una variable global
  3.  
  4.  
  5. // Es una simple tabla con un solo campo "Codigo" que llenamos con los valores del 1 al 1000.
  6. var
  7.   i: Integer;
  8. begin
  9.   tbPrueba:= TClientDataSet.Create(Self);
  10.   tbPrueba.FieldDefs.Add('Codigo', ftInteger, 0, FALSE);
  11.   tbPrueba.CreateDataset;
  12.   for i:= 0 to 1000 do
  13.   begin
  14.     tbPrueba.Insert;
  15.     tbPrueba.FieldValues['Codigo']:= i;
  16.     tbPrueba.Post;
  17.   end;
  18.   tbPrueba.IndexFieldNames:= 'Codigo';
  19.   dtsMain.DataSet:= tbPrueba;
  20. end;



Y queremos borrar todas los registros con el campo "Codigo" menor de 10, podemos hacer esto:


delphi
  1. begin
  2.   tbPrueba.Filter:= 'Codigo < 10';
  3.   tbPrueba.Filtered:= TRUE;
  4.   tbPrueba.First;
  5.   while not tbPrueba.Eof do
  6.     tbPrueba.Delete;
  7.   tbPrueba.Filtered:= FALSE;
  8. end;



No es muy elegante pero es lo que hay  :p .

Y si quieres aumentar el rendimiento yo primero rompería cualquier vinculo entre el ClientDataSet y un DataSource, y después del borrado lo volvería a restaurar. Algo Así:


delphi
  1. begin
  2.   // dtsMain es un DataSource
  3.   dtsMain.DataSet:= nil;
  4.   try
  5.     tbPrueba.Filter:= 'Codigo < 10';
  6.     tbPrueba.Filtered:= TRUE;
  7.     tbPrueba.First;
  8.     while not tbPrueba.Eof do
  9.       tbPrueba.Delete;
  10.     tbPrueba.Filtered:= FALSE;
  11.   finally
  12.     dtsMain.DataSet:= tbPrueba;
  13.   end;
  14. end;




  • 0

#3 eduarcol

eduarcol

    Advanced Member

  • Administrador
  • 4.483 mensajes
  • LocationVenezuela

Escrito 08 febrero 2010 - 03:18

Amigo Seoane, una pregunta, yo acostumbro a realizar esto: 

delphi
  1. tbPrueba.DisableControls;



Pero veo que tu aconsejas este:



delphi
  1. dtsMain.DataSet:= nil;



hay alguna diferencia?

  • 0

#4 Caro

Caro

    Member

  • Miembros
  • PipPip
  • 29 mensajes
  • LocationBolivia

Escrito 08 febrero 2010 - 03:43

Hola egostar, como te dice seoane no puedes hacerlo directo o utilizas Filtros como te ha indicado o también puedes recorrer la tabla e ir borrando:



delphi
  1.     ClientDataSet.First;
  2.     while not ClientDataSet.EOF do
  3.     begin
  4.       if ClientDataSet.FieldByName('campo').AsString='COMEDOR' then
  5.         ClientDataSet.Delete;
  6.       ClientDataSet.next;
  7.     end



El ClientDataSet tiene la propiedad CommandText para hacer consultas solo te permite los Select cuando lo tienes relacionado con otro DataSet y su Provider, modificación a al BD con insert, delete, update no se puede, debes hacerlo como si estuvieses trabajando con los componentes Table.

Saluditos
  • 0

#5 Caro

Caro

    Member

  • Miembros
  • PipPip
  • 29 mensajes
  • LocationBolivia

Escrito 08 febrero 2010 - 03:50

Amigo Seoane, una pregunta, yo acostumbro a realizar esto: 

delphi
  1. tbPrueba.DisableControls;



Pero veo que tu aconsejas este:



delphi
  1. dtsMain.DataSet:= nil;



hay alguna diferencia?


Si hay diferencía, asignándole a nil estamos quitando la relación entre el DataSet y el DataSource en cuestión osea que los componentes que estaban mostrando los datos (dbgrids, dbedit....), ya no van a mostrar nada, quedan en blanco y al asignarlo nuevamente volvemos a ver los datos, mientras con DisableControl no sucede eso, solo añadir de utilizar Bokmarks acompañado de DisableControl.

Saluditos
  • 0

#6 seoane

seoane

    Advanced Member

  • Administrador
  • 1.259 mensajes
  • LocationEspaña

Escrito 08 febrero 2010 - 04:05

hay alguna diferencia?


Pues la respuesta es muy parecida a la del ultimo hilo en que me lo preguntaste. Allí te conteste que no usaba DisableControls por desconocimiento, pero en este caso no lo use porque ya me había olvidado :p

Soy novato en esto de las bases de datos, rejillas, etc ... así que perdonarme si meto la pata  :$
  • 0

#7 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.446 mensajes
  • LocationMéxico

Escrito 08 febrero 2010 - 06:18

Hola,

Muchas gracias por responder, yo había hecho eso mismo que me comentan y que es recorrer el dataset y borrar el registro que coincida con el argumento dado, el detalle (que no problema) es que yo hago algunos calculos en el evento AfterDelete, entonces aquí viene el primer detalle feo, ese evento recorre el dataset y 'rompe' de alguna forma el while not eof del dataset, hice una chapuza que funciona, pero me parece que es muy lento el proceso y se nota mucho como va borrando registro por registro.

Por eso pense en utilizar la propiedad Multiselect del DBGrid, seleccionar todos los registros que coincidan con el argumento dado y hacer un delete que es lo que hace el Ctrl+Del en el dbgrid y borra todo lo seleccionado.

Seguiré intentando algunas ideas que tengo a ver si puedo lograr mi Caprichito :)

Salud OS

PD; un gusto verte amiguita Caro, felicidades por el nombramiento en Club Delphi. :)
  • 0

#8 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.446 mensajes
  • LocationMéxico

Escrito 08 febrero 2010 - 07:07

Hola

Pues ya encontré la solución a mi caprichito :D :D :D



delphi
  1. procedure Tform1.Button1Click(Sender: TObject);
  2. begin
  3.   DBGrid1.DataSource.DataSet.DisableControls;
  4.   DBGrid1.DataSource.DataSet.First;
  5.   while not DBGrid1.DataSource.DataSet.Eof do
  6.   begin
  7.     if DBGrid1.DataSource.DataSet['MARCA'] = 'ALTIMA 2003' then
  8.         DBGrid1.SelectedRows.CurrentRowSelected := True;
  9.     DBGrid1.DataSource.DataSet.Next;
  10.   end;
  11.   DBGrid1.DataSource.DataSet.EnableControls;
  12.   DBGrid1.SelectedRows.Delete;
  13. end;



Doy por [RESUELTO] este hilo, sin embargo, quedo abierto a otras posibilidades :)

Salud OS
  • 0

#9 eduarcol

eduarcol

    Advanced Member

  • Administrador
  • 4.483 mensajes
  • LocationVenezuela

Escrito 09 febrero 2010 - 07:12


hay alguna diferencia?


Pues la respuesta es muy parecida a la del ultimo hilo en que me lo preguntaste. Allí te conteste que no usaba DisableControls por desconocimiento, pero en este caso no lo use porque ya me había olvidado :p

Soy novato en esto de las bases de datos, rejillas, etc ... así que perdonarme si meto la pata  :$


jajaja en serio ya te lo había preguntado :s jajajaja, que mala memoria... :o  ups, disculpa.
  • 0

#10 seoane

seoane

    Advanced Member

  • Administrador
  • 1.259 mensajes
  • LocationEspaña

Escrito 09 febrero 2010 - 07:21

Si el problema es el evento AfterDelete, no hay problema  :D


delphi
  1. var
  2.   Temp: TDataSetNotifyEvent;
  3. begin
  4.   Temp:= ClientDataSet1.AfterDelete;
  5.   ClientDataSet1.AfterDelete:= nil;
  6.   try
  7.     // Aqui recorres el dataset borrando, con el metodo que prefieras
  8.   finally
  9.     ClientDataSet1.AfterDelete:= Temp;
  10.     // Y aqui lo llamamos por si necesitas recalcular
  11.     ClientDataSet1.AfterDelete(ClientDataSet1)
  12.   end;
  13. end;


  • 0

#11 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.446 mensajes
  • LocationMéxico

Escrito 09 febrero 2010 - 10:04

Si el problema es el evento AfterDelete, no hay problema  :D


Por eso amo a Delphi, todo se puede y lo que no se inventa, esa es otra forma de ver el asunto amigo seoane, pero fijate que con la alternativa de borrar los registros seleccionados se ejecuta solo una vez el evento AfterDelete que es lo que yo me aferré a hacer :D :D :D

De cualquier forma es interesante el asunto de ejecutar un evento X al gusto o necesidad en tiempo de ejecución (y), siempre es bueno tener alternativas disponibles ;)

Salud OS
  • 0

#12 seoane

seoane

    Advanced Member

  • Administrador
  • 1.259 mensajes
  • LocationEspaña

Escrito 09 febrero 2010 - 01:56

... pero fijate que con la alternativa de borrar los registros seleccionados se ejecuta solo una vez el evento ...


:undecided: No estoy seguro de eso. Si te fijas en el código del "Delete" del DBGrid, lo único que hace, si hay seleccionados varios registros, es recorrer las lista de Bookmarks donde están guardados esos registros y borrarlos usando el método "Delete" del DataSet.

Lo que yo creo es que ejecuta el método AfterDelete tantas veces como registros tengas seleccionados, pero como no recorre el Dataset registro a registro, sino que se dirige directamente a cada registro usando los Bookmarks, da igual que en el método AfterDelete te andes moviendo por los registros del DataSet

PD: Mira que me gustas darle vueltas a las cosas  :D
  • 0

#13 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.446 mensajes
  • LocationMéxico

Escrito 09 febrero 2010 - 01:59


... pero fijate que con la alternativa de borrar los registros seleccionados se ejecuta solo una vez el evento ...


:undecided: No estoy seguro de eso. Si te fijas en el código del "Delete" del DBGrid, lo único que hace, si hay seleccionados varios registros, es recorrer las lista de Bookmarks donde están guardados esos registros y borrarlos usando el método "Delete" del DataSet.

Lo que yo creo es que ejecuta el método AfterDelete tantas veces como registros tengas seleccionados, pero como no recorre el Dataset registro a registro, sino que se dirige directamente a cada registro usando los Bookmarks, da igual que en el método AfterDelete te andes moviendo por los registros del DataSet

PD: Mira que me gustas darle vueltas a las cosas  :D


Ah caray, vas a hacer que haga un debug a mi código para verificar lo que dices, no es que dude de tus palabras pero pues quiero estar seguro :p :D :D :D

Salud OS
  • 0

#14 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.446 mensajes
  • LocationMéxico

Escrito 09 febrero 2010 - 07:51

Pues he hecho un "trace" de mi aplicación y debo decir que está usted en lo correcto amigo seoane, efectivamente, ejecuta el evento AfterDelete por cada uno de los registros borrados.

Honor a quien honor merece :)

Salud OS
  • 0

#15 seoane

seoane

    Advanced Member

  • Administrador
  • 1.259 mensajes
  • LocationEspaña

Escrito 10 febrero 2010 - 05:36

:D Pues me he quedado mas tranquilo.
  • 0




IP.Board spam blocked by CleanTalk.