Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Copiar el contenido de un DBGrid en el Portapapeles (https://www.clubdelphi.com/foros/showthread.php?t=71563)

GerTorresM 28-12-2010 02:43:59

Copiar el contenido de un DBGrid en el Portapapeles
 
Hola a tod@s


La situación que tengo hoy es la siguiente:

quiero copiar el contenido de un DBGrid en el portapapeles, agradezco de antemano la colaboración



Cordialmente



gertorresm
colombia

ecfisa 28-12-2010 04:00:34

Hola GerTorresM.

Creo que podrías hacer así:
Código Delphi [-]
type
  TDBGridEx = class(TDBGrid); 
  TForm1 = class(TForm)
    ...
    DBGrid1: TDBGrid;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
  public
    procedure DBGridToClipBoard(DBGrd: TDBGridEx);
  end;
...
implementation 

uses ClipBrd;
...
{ Pasar contenido de los campos al portapapeles }
procedure TForm1.DBGridToClipBoard(DBGrd: TDBGridEx);
var
  i,j: Integer;
  BM: TBookmarkStr;
  s: string;
begin
  DBGrd.DataSource.DataSet.DisableControls;  // evita parpadeo en la grilla
  try
    BM:= DBGrd.DataSource.DataSet.Bookmark;  // guardar posición
    DBGrd.DataSource.DataSet.MoveBy(1 - DBGrd.Row); // ir a 1era fila
    s:= '';
    for i:= 1 to DBGrd.RowCount - 1 do  // nro filas mostradas
    begin
      for j:= 0 to DBGrd.FieldCount - 1 do   // campos
      begin
        s:= s + DBGrd.Fields[j].AsString;
        if i < DBGrd.RowCount  then s:= s + '-'; // separador de campos (el que gustes)
      end;
      s:= s + #10#13;                  //CRLF
      DBGrd.DataSource.DataSet.Next;   // siguiente fila
    end;
    ClipBoard.SetTextBuf(PChar(s));  // a portapapeles
    DBGrd.DataSource.DataSet.Bookmark:= BM; // restaurar posición
  finally
    DBGrd.DataSource.DataSet.EnableControls;
  end;
end;
...

Ejemplo de uso:
Código Delphi [-]
{ a portapapeles }
procedure TForm1.Button1Click(Sender: TObject);
begin
  DBGridToClipboard(TDBGridEx(DBGrid1));
end;

{ mostrar }
procedure TForm1.Button2Click(Sender: TObject);
begin
  ShowMessage(ClipBoard.AsText);
end;


Saludos.

GerTorresM 28-12-2010 11:55:08

aún no me funciona
 
Hola ecfisa:

Te agradezco el tiempo de tu respuesta, tome tu ejemplo y le hice algunas modificaciones con las cuales el código quedo de la siguiente forma

Código Delphi [-]
procedure CopiarDBGridPortaPales (pBDGrid : TDBGrid);
var
  i_local,j_local: Integer;
  BookMark_local: TBookmarkStr;
  s_local: string;
begin
  pBDGrid.DataSource.DataSet.DisableControls;  // evita parpadeo en la grilla
  try
    BookMark_local:= pBDGrid.DataSource.DataSet.Bookmark;  // guardar posición
    pBDGrid.DataSource.DataSet.first; // ir a 1era fila
    s_local:= '';
    for i_local:= 1 to pBDGrid.Datasource.dataset.RecordCount - 1 do  // nro filas mostradas
    begin
      for j_local:= 0 to pBDGrid.FieldCount - 1 do   // campos
      begin
        s_local:= s_local + pBDGrid.Fields[j_local].AsString;
        if i_local < pBDGrid.datasource.dataset.recordCount then s_local:= s_local + #10;
      end;
      s_local:= s_local + #13;                  //CRLF
      pBDGrid.DataSource.DataSet.Next;   // siguiente fila
    end;
    ClipBoard.SetTextBuf(PChar(s_local));  // a portapapeles
    pBDGrid.DataSource.DataSet.Bookmark:= BookMark_local; // restaurar posición
  finally
    pBDGrid.DataSource.DataSet.EnableControls;
  end;
end;

bien en orden de ideas ya esta copiando los datos del DBGrid en el Portapales, el formato en el que lo esta haciendo no es correcto, ya que lo que necesito es que al pegar los datos del portapapeles los pegue con forma de columnas (que al pegarlo en excel se vea como en la grilla) lo cual no he logrado; en mis pruebas cambie el separador que en tu ejemplo estaba con '-' por un tab #10, pero lo que obtengo al pegar los datos son los de una una misma fila uno debajo del otro.

Agradezco de antemano cualquier aporte que me ayude a encontrar la solución que deseo.


atentamente



gertorresm
Colombia.

GerTorresM 28-12-2010 12:15:33

Problema Solucionado
 
Hola a tod@s

Muchas a Ecfisa que me dio el código para poder plantear la solución; la parte final del problema radicada en el un código ascii incorrecto, y para el caso revise la tabla ascii y me di cuenta que estaba confundiendo el código que corresponde al tab del #9 con # 10, al corregir esto se ha solucionado el problema, dejo el código que quedo ya probado, por si alguien desea utilizarlo.

Código Delphi [-]
procedure CopiarDBGridPortaPales (pBDGrid : TDBGrid);
var
  i_local,j_local: Integer;
  BookMark_local: TBookmarkStr;
  s_local: string;
begin
  pBDGrid.DataSource.DataSet.DisableControls;  // evita parpadeo en la grilla
  try
    BookMark_local:= pBDGrid.DataSource.DataSet.Bookmark;  // guardar posición
    pBDGrid.DataSource.DataSet.first; // ir a 1era fila
    s_local:= '';
    for i_local:= 1 to pBDGrid.Datasource.dataset.RecordCount - 1 do  // nro filas mostradas
    begin
      for j_local:= 0 to pBDGrid.FieldCount - 1 do   // campos
      begin
        s_local:= s_local + pBDGrid.Fields[j_local].AsString;
        if i_local < pBDGrid.datasource.dataset.recordCount then s_local:= s_local + #9;
      end;
      s_local:= s_local + #10#13;                  //CRLF
      pBDGrid.DataSource.DataSet.Next;   // siguiente fila
    end;
    ClipBoard.SetTextBuf(PChar(s_local));  // a portapapeles
    pBDGrid.DataSource.DataSet.Bookmark:= BookMark_local; // restaurar posición
  finally
    pBDGrid.DataSource.DataSet.EnableControls;
  end;
end;


gertorresm
Colombia

BlueSteel 28-12-2010 14:55:20

Cita:

Empezado por GerTorresM (Mensaje 385963)
Hola a tod@s

Muchas a Ecfisa que me dio el código para poder plantear la solución; la parte final del problema radicada en el un código ascii incorrecto, y para el caso revise la tabla ascii y me di cuenta que estaba confundiendo el código que corresponde al tab del #9 con # 10, al corregir esto se ha solucionado el problema, dejo el código que quedo ya probado, por si alguien desea utilizarlo.

Código Delphi [-]procedure CopiarDBGridPortaPales (pBDGrid : TDBGrid); var i_local,j_local: Integer; BookMark_local: TBookmarkStr; s_local: string; begin pBDGrid.DataSource.DataSet.DisableControls; // evita parpadeo en la grilla try BookMark_local:= pBDGrid.DataSource.DataSet.Bookmark; // guardar posición pBDGrid.DataSource.DataSet.first; // ir a 1era fila s_local:= ''; for i_local:= 1 to pBDGrid.Datasource.dataset.RecordCount - 1 do // nro filas mostradas begin for j_local:= 0 to pBDGrid.FieldCount - 1 do // campos begin s_local:= s_local + pBDGrid.Fields[j_local].AsString; if i_local < pBDGrid.datasource.dataset.recordCount then s_local:= s_local + #9; end; s_local:= s_local + #10#13; //CRLF pBDGrid.DataSource.DataSet.Next; // siguiente fila end; ClipBoard.SetTextBuf(PChar(s_local)); // a portapapeles pBDGrid.DataSource.DataSet.Bookmark:= BookMark_local; // restaurar posición finally pBDGrid.DataSource.DataSet.EnableControls; end; end;



gertorresm
Colombia

Que buen codigo.. me apunto para tenerlo de referencia...

Salu2:p:D

ecfisa 28-12-2010 15:38:42

Hola GerTorresM.

Cuando dijiste:
Cita:

quiero copiar el contenido de un DBGrid en el portapapeles, agradezco de antemano la colaboración
Supuse que eran los Datos que el DBGrid mostraba en pantalla en ese momento, de ahí que desprotegí a la clase TDBgrid para obtener
la propiedad Row. Pero veo por tu código que es todo el contenido del DataSet...

En ese caso creo que es más simple hacerlo así:
Código Delphi [-]
procedure TForm1.DBGridToClipboard(ADataSet: TDataSet);
var
  BM: TBookmarkStr;
  i: Integer;
  s: string;
begin
  ADataSet.DisableControls;
  try
    BM:= ADataSet.Bookmark;
    ADataSet.First;
    s:= '';
    while not ADataSet.Eof do
    begin
      for i:= 0 to ADataSet.FieldCount-1 do
      begin
        s:= s + ADataSet.Fields[i].AsString;
        if i < ADataSet.RecordCount then
          s:= s + #9; // separador elegido
      end;
      s:= s + #10#13;
      ADataSet.Next;
    end;
    ClipBoard.SetTextBuf(PChar(s));
  finally
    ADataSet.Bookmark:= BM;
    ADataSet.EnableControls;
  end;
end;

Y llamar al procedimiento así:
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
begin
  DBGridToClipboard(DBGrid1.DataSource.DataSet);
end;

Demás está decir que si el DataSet está muy cargado sería bueno que preevieras la posibilidad de desbordes de memoria...

Saludos.

ecfisa 28-12-2010 18:35:16

Hola.

Corrijo:

Donde dice:
Código Delphi [-]
 if i < ADataSet.RecordCount then
          s:= s + #9; // separador elegido

Quice decir:
Código Delphi [-]
 if i < AdataSet.FieldCount then
            s:= s + #9; // separador elegido

Vayan mis disculpas... :o

Saludos.


La franja horaria es GMT +2. Ahora son las 21:26:30.

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