Ir al contenido



Foto

Importar un CSV con FIREDAC

delphi csv firedac xe8

  • Por favor identifícate para responder
1 respuesta en este tema

#1 Amadis

Amadis

    Member

  • Miembros
  • PipPip
  • 12 mensajes

Escrito 09 octubre 2018 - 02:17

Estimados colegas les dejo aquí una forma de como importar un CSV.

 

En este ejemplo se utiliza el componente TFDBATCHMOVE, incorporado creo que en la versión XE7.

 

Y se supone que con apenas 5 lineas de codigo pueda importar un CSV, asignando el reader y writer correspondiente.

 

En versiones anteriores que incluyan Firedac, se puede hacer con el componente TFDDataMove (discontinuado en XE7 e incluido hasta XE8 por compatibildad).

 

 
En el proyecto demo que voy a describir utilicé un Formulario (Form1 – principal.pas), algunos Tlabel sin importancia, 2 Tedit, (uno para ruta del csv y otro para el separador), un TOpendialog, u Tbutton para ejecutar el Opendialog de búsqueda de archivo., Un Tbitbutton (Kind:= BkClose).
Un datasource y Dbgrid para visualizar el contenido, y lo indispensable de FireDAC que son TFDGUIxWaitCursor, TFDMemTable y TFDBatchMove
 
En mis intentos trate de colocar en tiempo de diseño componentes TextReader y DataSetWriter pero no tuve suerte. Luego encontré el ejemplo que venia en la carpeta SAMPLES y en base a eso di forma a este codigo. Donde estos Reader y Writer se crean en tiempo de ejecución desde el mismo Batchmove y luego se le da unos prámetros para formato de la tabla.
 
El trabajo se realiza con los dos últimos, primero creamos el FDMemTable1 y luego el  FDBatchmove, y asigmanamos los Reader y Writer
 
Y luego debemos especificar la estructura de los archivos que vamos a abrir, esto podemos hacerlo en tiempo de diseño, y dejar establecidos los parámetros pero funcionará correctamente sólo con archivos de la misma estructura.
 
Como necesito abrir archivos donde se desconoce de antemano (al momento de programar) cuál será la estructura, lo hacemos en Tiempo de Ejecución, lo cual implica sólo unas pocas líneas de código extra, donde definimos el Separador, que a veces suele variar, los campos de la tabla a importar e indicamos si la primera linea tiene los nombres de campo.
 
Aquí debajo está el código del botón que ejecuta el Opendialog y luego se encarga del proceso de carga.
 

delphi
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3. i: integer;
  4. begin
  5.  
  6. opendialog1.InitialDir := GetCurrentDir;
  7. if opendialog1.Execute
  8. then
  9. begin
  10.  
  11. fdmemtable1.free; // destruimos componentes para eliminar datos default y cargados anteriormente
  12. FDBatchMove1.Free; // idem anterior
  13. fdmemtable1 := TFDMemTable.create(Form1); // creamos
  14. FDBatchMove1:= TFDBatchMove.Create(Form1);
  15. dataSource1.DataSet := fdmemtable1; // vinculamos la tabla al datasource
  16. //Create text reader and set FDBatchMode as owner. Then
  17. // FDBatchMove will automatically manage the reader instance.
  18. with TFDBatchMoveTextReader.Create(FDBatchMove1)
  19. do begin
  20. // Set text data file name
  21. FileName := opendialog1.FileName;
  22. // Setup file format
  23. DataDef.Separator := edsepara.Text[1]; // ** indicamos separador de campos en este caso ';'
  24. DataDef.Delimiter := #0; //** opcional, para campos sin QUOTED VALUES "valor" que es la opción default del componente
  25. Datadef.RecordFormat := rfCustom; //**
  26. for i := 0 to Datadef.Fields.Count-1 // ** para evitar problemas con campos FLOAT paso todos los campos a String.
  27. do Datadef.Fields[i].DataType := atString; // ** De no hacerlo he tenido errores [FireDAC][Comp][DM]-607. Bad text value [17,5] format for mapping item [->B]. '10,24' is not a valid integer value.
  28.  
  29. for i := 0 to Datadef.Fields.Count-1 // debemos antes agregar los campos el FDMentable sino obtenemos un error de que no puede crear el dataset.
  30. do fdmemtable1.FieldDefs.Add(Datadef.Fields[i].FieldName,ftString, 20, False);
  31. DataDef.WithFieldNames := True; // setear si tiene los nombres de campo en primera linea
  32. end;
  33.  
  34. // Create dataset writer and set FDBatchMode as owner. Then
  35. // FDBatchMove will automatically manage the writer instance.
  36. with TFDBatchMoveDataSetWriter.Create(FDBatchMove1) do begin
  37. // Set destination dataset
  38. DataSet := FDMemtable1;
  39. // Do not set Optimise to True, if dataset is attached to UI
  40. Optimise := False;
  41. end;
  42. // Analyze source text file structure
  43. FDBatchMove1.GuessFormat;
  44. FDBatchMove1.Analyze := ([ taDelimSep,taHeader,taFields]); // este comando crea la estructura de datos según adivina leyendo los primeros registros
  45. FDBatchMove1.AnalyzeSample := 50; // El default es 10, con esto profundizamos el analisis para adivinar estructura de tabla y campos
  46.  
  47. FDBatchMove1.Execute; // y Eureka! Tenemos los datos en la tabla y visibles en el Dbgrid
  48. end;
  49.  
  50. end;

Espero les sirva de ayuda o guia para algun proyecto

 


  • 1

#2 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 13.817 mensajes
  • LocationMéxico

Escrito 09 octubre 2018 - 02:22

Gracias por compartir. Interesante el tema. (y)

 

Saludos


  • 0





Etiquetado también con una o más de estas palabras: delphi, csv, firedac, xe8