Dump columns from TADOQuery to TClientDataSet

En éste artículo os dejo el código fuente de un fichero encontrado en SQL.RU donde hay una pequeña librería muy útil para el volcado de columnas de un componente a otro. En mi caso lo que quería era volcar las columnas de un TADOQuery a un TClientDataSet y además añadir una columna virtual a éste último para realizar diversas operaciones sobre ésta. El problema de volcar las columnas de un componente a otro dinámicamente, es que la tarea de convertir un TField a uno de sus hijos TStringField, TIntegerField, puede llegar a ser complicada. Pues bien, la librería que aquí os adjunto llamada FieldInfo (que además encontraréis aquí, parece un poco complicado de encontrar, pero está en el final de la página y hay que darle a un símbolo + que hay en la última respuesta del foro) dispone de varios métodos llamados GetAllFieldsInfo i SetAllFieldsInfo, donde le pasamos la query de dónde queremos obtener los datos y luego nos guarda la información en una TList. Luego volcamos ésta TList en un clientDataSet y que además modificaremos para realizar nuestras intenciones.
  • Cómo funciona la librería?
Primero tenemos que conectar nuestra qry y abrirla, luego haremos el volcado:


if qry.Active then
qry.Close;
qry.SQL.Text := 'SELECT * FROM Table1';
qry.Open;


Una vez tenemos los datos en la qry, queremos volcar toda éstas columnas en un ClientDataSet, añadirle una nueva columna para otro propósito y volcar todos los datos de la qry dentro del ClientDataSet haciendo un recorrido de los datos.

Volcado de columnas:

procedure DumpAllFields();
var
ListFields: TList;
NewField: TIntegerField;
begin
if ClientDataSet.Active then
ClientDataSet.Close;
ds1.Fields.Clear;
ClientDataSet.DisableControls;
try
qryTest.First;
ListFields := TList.Create;
//Dump all the qry fields into ListFields
GetAllFieldsInfo(ListFields, qry);

//Adding a new Field into ListFields
NewField := TIntegerField.Create(ClientDataSet);
NewField.Name := 'new';
NewField.FieldName := 'new';
NewField.FieldKind := fkData;
NewField.DisplayLabel := 'new';
NewField.DataSet := ClientDataSet;
GetFieldInfo(ListFields, NewField);
FreeAndNil(NewField);

//Dump all the columns from ListFields to ClientDataSet
SetAllFieldsInfo(ListFields, ClientDataSet);

ClientDataSet.CreateDataSet;
qry.First;
ClientDataSet.First;
finally
ClientDataSet.EnableControls;
FreeAndNil(ListFields);
end;
end;


Luego tenemos que volcar la información de la qry al ClientDataSet:


procedure LoadInformation();
var
i, j: integer;
FieldName: string;
begin
ClientDataSet.DisableControls;
try
qry.First;
i := 1;
while not qry.Eof do
begin
ClientDataSet.Append;
for j := 0 to qry.Fields.Count - 1 do
begin
FieldName := qry.Fields.Fields[j].FieldName;
ClientDataSet.FieldByName(FieldName).ReadOnly := false;
ClientDataSet.FieldByName(FieldName).Value := qry.Fields.Fields[j].Value;
end;
ClientDataSet.FieldByName('new').AsInteger := i;
ClientDataSet.Post;
qry.Next;
Inc(i);
end;
ClientDataSet.First;
finally
ClientDataSet.EnableControls;
end;
end;


El ClientDataSet está conectado a un TDataSource y éste a un componente Grid, de ésta manera podemos ver todos los datos del ClientDataSet.

El resultado quedaría de la siguiente manera:


Comments

Popular Posts