PDA

Ver la Versión Completa : Pasar registros de una DBGrid a otra Dbgrid usando multiselect


Soa Pelaez
08-03-2017, 01:45:32
Buen día.


Necesito que me ayuden, necesito pasar los datos que tengo en una dbgrid, el usuario puede ir seleccionando los registros que desea pasar y cuando el lo desee ya sea por medio de un botón o el evento scroll dichos datos seleccionados se pasarán a otra dbgrid que esta abajo y de la primera Dbgrid los datos pasados a la segunda desaparecerán.
De antemano muchas gracias.

AgustinOrtu
08-03-2017, 03:17:01
En realidad mas que pasar registros de un DBGrid a otro, lo que queres hacer es copiar registros de un DataSet a otro. El DBGrid es una circustancia mas

La propiedad TDBGrid.SelectedRows (http://docwiki.embarcadero.com/Libraries/en/Vcl.DBGrids.TDBGrid.SelectedRows) contiene una lista de TBookmarks. Un TBookmark (http://docwiki.embarcadero.com/Libraries/en/Data.DB.TBookmark) no es mas que un identificador, dentro de un TDataSet, de un registro, o si queres verlo de otra manera, es un identificador para cada fila de tu TDBGrid

La clase TDataSet posee metodos para posicionarse de un TBookmark a otro, lo cual se explica aca (http://docwiki.embarcadero.com/RADStudio/en/Marking_and_Returning_to_Records). Basicamente lo que hay que hacer es llamar al metodo GotoBookmark (http://docwiki.embarcadero.com/Libraries/en/Data.DB.TDataSet.GotoBookmark). Aca hay un ejemplo (http://docwiki.embarcadero.com/CodeExamples/en/GetBookmark_(Delphi))

La primer parte del problema ya la tendrias resuelta: recorrer las filas seleccionadas, posicionarse en cada una, y luego realizar la copia sobre el otro TDataSet

Hay una seccion en la documentacion dedicada a esto: Copying Data from Another Dataset (http://docwiki.embarcadero.com/RADStudio/en/Copying_Data_from_Another_Dataset)

Tambien podes hacer la implementacion a lo "chapucero", es decir, si conoces la estructura del otro TDataSet, lo unico que hay que hacer es crear un nuevo registro en el DataSet destino (Append (http://docwiki.embarcadero.com/Libraries/en/Data.DB.TDataSet.Append) o Insert (http://docwiki.embarcadero.com/Libraries/en/Data.DB.TDataSet.Insert) segun corresponda), setear los valores de los campos y luego invocar a Post (http://docwiki.embarcadero.com/Libraries/en/Data.DB.TDataSet.Post)

Sino conoces la estructura del DataSet de antemano, o tenes que copiar todos los campos, se puede implementar un recorrido sobre los campos (Fields (http://docwiki.embarcadero.com/Libraries/en/Data.DB.TDataSet.Fields)) de un DataSet e ir copiando el valor campo a campo. Obviamente que los campos deben estar en el mismo orden, con el mismo nombre y mismo tipo de datos

Si no me equivoco puede que algunos componentes tengan implementado un metodo que hace justamente esto. por ej, FireDAC

Por ultimo el codigo de estas unidades, si bien no hace exactamente lo que necesitas, te pueda servir como guia para armar tu solucion:

https://github.com/ortuagustin/Delphi-Utils/tree/master/Data

Por ejemplo, este:


function TFDMemTableDataSetCloner.CopyRecords(const Records: TArray<TBookmark>; Source: TDataSet; Owner: TComponent): TDataSet;
var
Copy: TFDMemTable;
I: Integer;
begin
Copy := TFDMemTable.Create(Owner);
try
Copy.CopyDataSet(Source, [coStructure, coRestart]);
Source.DisableControls;
try
for I := Low(Records) to High(Records) do
begin
Source.GotoBookmark(Records[I]);
Copy.Append;
Copy.CopyFields(Source);
Copy.Post;
end;
finally
Source.EnableControls;
end;
finally
Result := Copy;
end;
end;

Soa Pelaez
08-03-2017, 04:14:05
Necesito que me ayuden, necesito pasar los datos que tengo en una dbgrid, el usuario puede ir seleccionando los registros que desea pasar y cuando el lo desee ya sea por medio de un botón o el evento scroll dichos datos seleccionados se pasarán a otra dbgrid que esta abajo y de la primera Dbgrid los datos pasados a la segunda desaparecerán o almenos validarlos para que no se dejen repetir en caso de que el usuario vuelva a seleccionar los mismos por equivocación.
De antemano muchas gracias.

Casimiro Notevi
08-03-2017, 11:03:48
No olvides nuestra guía de estilo (http://www.clubdelphi.com/foros/guiaestilo.php), gracias :)

ecfisa
08-03-2017, 12:41:28
Hola.

Otra opción:

// SourceGrid.Options := SourceGrid.Options + [dgMultiSelect]

procedure CopyGridData( Source, Target: TDBGrid );
var
i,j: Integer;
begin
if Source.SelectedRows.Count > 0 then
begin
for i := 0 to Source.SelectedRows.Count-1 do
begin
Source.DataSource.DataSet.GotoBookmark( Pointer(Source.SelectedRows.Items[i]) );
Target.DataSource.DataSet.Append;
for j := 0 to Target.FieldCount-1 do
Target.Fields[j].Value := Source.Fields[j].Value;
Target.DataSource.DataSet.Post;
end;
end;
end;


llamada ej.:

procedure TForm1.btnCopy(Sender: TObject);
begin
CopyGridData( SourceGrid, TargetGrid );
end;


Hace un tiempo se trató una variante aquí: Drag & Drop de una selección múltiple. (http://www.clubdelphi.com/foros/showthread.php?p=465534)

Saludos :)