PDA

Ver la Versión Completa : Exportar Tabla a XML por medio de TclientDataSet


DANY
18-07-2008, 23:47:01
Necesito exportar tablas de una BD en uno o mas archivos y luego importarlas en otra BD de similar estructura (tablas con parametro de configuracion y otras yerbas). Expongo el asunto de manera simplificada. En la generacion del archivo, Genero un ClientDataSet lo conecto a un providers y luego a un Query. Luego hago:
ADOQuery1.Open ;

ClientDataSet1.Open ;
ClientDataSet1.SaveToFile('C:\Sistema\GruposComprobantes.xml',dfXML );
ClientDataSet1.Close ;


El asunto es que me genera solo el encabezado del archivo sin las filas con los datos. Es que tengo que recorrer todo el query e ir insertando de manera manual en el clientdataset antes de grabar el archivo?. Me parece engorroso y tiene que haber una solucion mas elegente.
Despues me queda el tema de la importacion que ya lo vere mas adelante.
Estoy encarando el tema de manera correcta??.
Gracias por su tiempo.

white_zombie
19-07-2008, 01:42:50
Hola, yo para exportar a xml desde un clientdataset uso el componente XMLTransformProvider que esta en la paleta data access como el clientdataset.

coso
19-07-2008, 06:36:21
Hola,
clientdataset1 ya tiene datos antes de llamar a savetofile? suponiendo que es un query


ClientDataSet1.Active := false;
ClientDataSet1.SQL.Text := ' select ...';
ClientDataSet1.Active := true;
ClientDataSet1.SaveToFile('C:\Sistema\GruposComprobantes.xml',dfXML);
ClientDataSet1.Close ;

DANY
20-07-2008, 02:38:07
No comprendo, el componente clientdataset no tiene propiedad SQL ni de conexion a BD, por eso el enlace a los demas componentes de BD. Algo es seguro, el clientdataset al momento de hacer savetofile no tiene registros.
Pero es que para exportarlos hay que recorrer todo un query? En esa solucion estoy trabajando en base a la gran ayuda de polirrubro y cuando termine subire las funciones genericas que lo hacen. Pero no me termina de cerrar el asunto, deberia cargarse como un dataset comun al abrir el query, por algo el enlace.
Saludos.

coso
20-07-2008, 09:27:23
si, un TDataset es tal como dices. Me referia a un cojunto de datos, un dataset, indistintamente, que puede ser una query o una tabla. El TAdoDataset no tiene la propiedad SQL pero si la propiedad CommandText, que es mas o menos lo mismo. Un TAdoDataset, por lo que veo en la ayuda, no es mas que un query que no permite deletes, insert into, etc. De todas maneras, creo que lo envias al savetofile vacio, prueba de hacer en vez de SQL.Text = '...' , .commandtext := 'select * ...' antes del savetofile. saludos

EDITO : tiene, igual que el query, las propiedades connection, connectionstring. No entiendo alla que dices "por algo el enlace", por lo que veo, el TAdoDataSet no tiene enlace a ningun otro dataset.

DANY
06-08-2008, 00:23:39
Al final lo resolvi recorriendo la tabla e insertando registro por registro en el ClientDataSet, al principio dude del rendimiento, pero logre un metodo generico que las recorre y funciona rapido y bien.
Para entender el codigo deberia explicar una serie de cosas, como ser que tengo una clase por tabla y cada campo de la BD relacionado con un campo property de la clase asociada y que todas heredan de la clase en la que expongo el metodo. Pero cualquier cosa que necesiten , les respondere.
Expongo mi codigo:

procedure TClaseTablas.ExportarArchivoXML;
var ClientDataSet : TClientDataSet ;
I, CantidadProp, Count : Integer;
PropList: PPropList ;
ValoresCampos: array of variant ;
Campos, Parametros: TStrings ;
SQL: String ;
q: TDataSet ;
begin
try
CantidadProp := GetPropList(Self, PropList);
Count := 0;
Campos := TStringList.Create ;
Parametros := TStringList.Create ;

//Genero los campos en el client data set.
ClientDataSet := TClientDataSet.Create(nil);

for I := 0 to CantidadProp -1 do
begin
if (PropList[I].PropType^.Kind = tkClass) then
Continue;

if (PropList[I].Name='Estado') or (PropList[I].Name='NombreTabla') or
(PropList[I].Name='NombreTabla') or (PropList[I].Name='NombreCampoClave')
or (PropList[I].Name='ClavePrimaria') or (PropList[I].Name='Titulo')then
Continue ; //AJJJJ Como distingo la clase base de la hija????
//y titulo de donde sale?
ClientDataSet.FieldDefs.Add(PropList[I].Name,ftString ,250,false);


End;
ClientDataSet.CreateDataSet ;
q := fDatos.AbrirQuery('Select * From '+NombreTabla ,[]);

while not q.Eof do
Begin
ClientDataSet.Append ;

for I := 0 to CantidadProp -1 do
begin
if (PropList[I].PropType^.Kind = tkClass) then
Continue;

if (PropList[I].Name='Estado') or (PropList[I].Name='NombreTabla') or
(PropList[I].Name='NombreTabla') or (PropList[I].Name='NombreCampoClave')
or (PropList[I].Name='ClavePrimaria') or (PropList[I].Name='Titulo')then
Continue ; //AJJJJ Como distingo la clase base de la hija????
//y titulo de donde sale?
ClientDataSet.FieldByName(PropList[I].Name).Value := q.FieldByName (PropList[I].Name).AsString ;

End;
q.Next ;
ClientDataSet.Post ;
End;

ClientDataSet.SaveToFile('C:\Sistema\'+NombreTabla+'.xml',dfXML );

Finally
FreeAndNil ( ClientDataSet ) ;FreeAndNil ( Campos) ; FreeAndNil ( Parametros);

End;

end;


muchas gracias al amigo poliburro quien se contacto personalmente por MSN y me ayudo a entender el asunto.
Perdon si el codigo esta confuso por que no se entiende el contexto y gracias por su tiempo.

roman
06-08-2008, 01:03:59
Yo no entiendo. Me da la impresión de que se complica de más el asunto. Al menos viendo tu pregunta original, el caso es que si el ClientDataSet realmente está conectado al ADOQuery mediante un DataSetProvider, el método SaveToFile guarda todo, el encabezado y los registros.

// Saludos