Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Conexión con bases de datos (https://www.clubdelphi.com/foros/forumdisplay.php?f=2)
-   -   Error al llenar tabla desde archivo txt (https://www.clubdelphi.com/foros/showthread.php?t=37349)

bohemioloco 10-11-2006 02:26:37

Error al llenar tabla desde archivo txt
 
Saludos
En un anterior hilo pregunte si era posible llenar una tabla (socios) con datos de un archivo txt y Neftali me respondio:

Cita:

Empezado por Neftali
(1) Sí.
(2) Básicamente se trata de ir leyendo la información del Archivo de texto (previamente cargado en un TStrings, por ejemplo) y luego ir haciendo Insert/Update (vía TTable o TQuery) en la tabla.

Siguiendo su consejo (el cual agradezco mucho) y algunas cosas que investigué por mi cuenta utilicé un Tmemo donde cargo el contenido del archivo txt para ir leyendo la información y un Tquery para hacer el llenado de la tabla (porque me pareció el metodo más facil para mi que soy totalmente nuevo en delphi :) )

Resumiendo me salió el siguiente código


Código Delphi [-]
procedure TfrmNumeroUno.iM1Click(Sender: TObject);
var y,d,a,ci,num,nom,cat:string;i,j,x,k:integer;
v: array [1..4] of string;
begin
query1.Close;
Query1.ExecSql;
frmNumeroUno.Memo1.Lines.Clear;
frmNumeroUno.OpenDialog1.Title:='Exportacion de Socios'; //ABRE DIALOGO Y BUSCA EL ARCHIVO
frmNumeroUno.OpenDialog1.DefaultExt:='.txt';
frmNumeroUno.OpenDialog1.InitialDir:='C:\windows\escritorio\BD';
frmNumeroUno.OpenDialog1.Execute;
frmNumeroUno.Memo1.Lines.Clear;
frmNumeroUno.Memo1.Lines.LoadFromFile(frmNumeroUno.OpenDialog1.FileName); //cuenta las lineas del archivo de texto
y:='';
for i:=0 to frmNumeroUno.Memo1.Lines.Count do //desde 1 hasta elnumero de lineas del texto
begin
           x:=1;
           d:='';
           for k:=1 to 4 do //desde uno hasta numero de campos
           begin
                 v[k]:=''; //vector de valores
           end;
 
          y:=frmNumeroUno.Memo1.Lines.Strings[i]; 
 
          for j:=1 to length(y) do 
          begin
                 if y[j]<>'|' then
                 begin
                        d:=d+y[j];
                 end
                 else
                begin
                       v[x]:=d;
                       inc(x);
                       a:=d;
                       d:='';
               end;
           end; 
 
          ci:=v[1]; //dato del primer campo
          num:=v[2]; //dato del segundo campo
          nom:=v[3]; // dato del tercer campo
          cat:=v[4]; // dato del cuarto campo
          //Aqui tiene que cargar los datos en la tabla//
         frmNumeroUno.Query2.SQL.Clear;
         frmNumeroUno.Query2.SQL.Add('insert into socios (ci,Ncta,Nombres,Calf) values('+ci+','+num+','+nom+','+cat+')');
         Query2.Close;
         frmNumeroUno.Query2.Active:=true;
         Query2.ExecSql;
end 
end;
El problema es que en tiempo de ejecución me sale el siguiente error

"Project miproyecto.exe raised exception class EDBEngineError whyt message Invalid use of keyword"

o sea me da error al encontrar un espacio en blanco dentro del texto.

¿Que me falta?:confused: ¿que me sobra?:confused: ¿Que hice mal? Alguien me puede aconsejar

Les agradezco de antemano su ayuda

marcoszorrilla 10-11-2006 07:03:53

Yo simplificaría todo, no tengo tiempo para leer el código, pero si un registro es una línea de tu fichero de texto y los campos, tienen un separador o son de longitud fíja.

Leería mediante un bucle las líneas, por cada línea leida, utilizado la función Copy si los campos son de longitud fija iría rellenando los campos de la BD y me ahorraría el paso intermedio de cargarlo en un memo.

Un Saludo.

Neftali [Germán.Estévez] 10-11-2006 10:11:46

Cita:

Empezado por bohemioloco
...Neftali me respondio...

Lo lógico en estos casos es seguir con el hilo original; Ahora en este hilo falta la información que diste en el otro.

Cita:

Empezado por bohemioloco
...utilicé un Tmemo donde cargo el contenido del archivo txt

En realidad, la propiedad LInes del TMemo, no deja de ser un TStrings. ;)

Cita:

Empezado por bohemioloco
El problema es que en tiempo de ejecución me sale el siguiente error:
"Project miproyecto.exe raised exception class EDBEngineError whyt message Invalid use of keyword"

Deberías ejecutar tu proyecto paso a paso y decirnos en qué línea da el error (aunque supongo cual es, no está de más estar seguro).

Otra cosa que estaría bien es saber cómo son las líneas del fichero de texto. ¿Puedes poner dos o tres? Para ver la estructura que tienes, los separadores,...

La idea del código es la correcta, recorrer las líneas e ir insertando en la tabla:
* Debes tener en cuenta, que los "cortes" de la línea en trozos sean correctos.
* Recuerda también que al realizar un Insert, los campos de tipo texto van entre comillas (Revisa la función QuetedStr);
* Ten en cuenta que algun campo al realizar los "cortes" puede ser vacío, al insertar ese campo debes cambiarlo por un NULL, sino en la sentencia aparecerán dos comas ( , ) seguidas y te dará error.
* Para buscar el sepoarador entre campos y "cortar" usa las funciones Pos Y Copy.

mane 10-11-2006 16:28:32

Y si lo haces así...

Supongamos estas variables
ft : textfile;
lin : string;

y un fichero donde está la información, un código de 5 letras y una descripción, separados por una coma (o lo que sea)

Código:

  assignfile(ft,DirectoryEdit1.text+'\Anotacion.txt');
  {$I-}
    Reset(Ft);
  {$I+}
  if IOResult <> 0 then
  begin
    Showmessage('No se encuentra el fichero de anotaciones.');
    Exit;
  end;
  while not eof(ft) do
  begin
    Readln(ft,lin);
    Table1.Append;
    Table1.Fieldbyname('Codigo').asstring:=copy(lin,1,5);
    Table1.Fieldbyname('Fecha').asdatetime:=now;
    Table1.Fieldbyname('Descripcion').asstring:=copy(lin,7,80);
    Table1.Post;
  end;
  Closefile(ft);


bohemioloco 10-11-2006 20:05:58

Detallando un poco mas
 
1 Archivos Adjunto(s)
Gracias a todos por sus sugerencias, y sobre todo por su paciencia:) .
Les detallo un poco mas el problema.

- Los campos son de longitud variable (es decir.. los datos no tienen el mismo largo) por eso voy leyendo el fichero caracter por caracter.

- La linea donde aparece el error es :


Código Delphi [-]Query2.ExecSql;


Archivo Adjunto 517- Una muestra de los datos

Gracias de nuevo por su ayuda.. y por seguir ayudandome :p

fjcg02 10-11-2006 23:23:32

Hola,
personalmente en un proyecto utilicé un odbc para acceder a ficheros de texto con formatos tipo registros.
Una vez creado el odbc, al que sólo hay que indicar el directorio, cada fichero de texto se trata como una tabla/query. Es una pasada la facilidad con la que se puede manejar este tipo de información, y creo que te puede venir de maravilla. Una vez el usuario te haya seleccionado el fichero, modificas los datos del dataset y los tratas como si leyeras una tabla normal.

Echale un vistazo porque creo que merece la pena.

Un saludo

mane 12-11-2006 11:19:50

No le veo problema a la estructura de tu fichero txt.

Código:

var l1,l2,l3,l4 : string;
    procedure extrae(cad:string;var t1,t2,t3,t4:string);
    var q : integer;
    begin
      t1:='';t2:='';t3:='';t4:='';
      q:=1;
      while copy(cad,q,1)<>'|' do
      begin
        t1:=t1+copy(cad,q,1);
        inc(q);
      end;
      inc(q);
      while copy(cad,q,1)<>'|' do
      begin
        t2:=t2+copy(cad,q,1);
        inc(q);
      end;
      while copy(cad,q,1)<>'|' do
      begin
        t3:=t3+copy(cad,q,1);
        inc(q);
      end;
      inc(q);
      t4:=copy(cad,q,3);  // el resto
    end;
 
 assignfile(ft,DirectoryEdit1.text+'\Anotacion.txt');
  {$I-}
    Reset(Ft);
  {$I+}
  if IOResult <> 0 then
  begin
    Showmessage('No se encuentra el fichero de anotaciones.');
    Exit;
  end;
  while not eof(ft) do
  begin
    Readln(ft,lin);
    extrae(lin,l1,l2,l3,l4);
    Table1.Append;
    Table1.Fieldbyname('Codigo').asinteger:=strtoint(l1);
    Table1.Fieldbyname('Numero').asstring:=l2;
    Table1.Fieldbyname('Nombre').asstring:=l3;
    Table1.Fieldbyname('Tipo').asstring:=l4;
    Table1.Post;
  end;
  Closefile(ft);


fjcg02 12-11-2006 22:50:58

1 Archivos Adjunto(s)
Insisto, mira un poco lo que te digo en el mensaje anterior.
En el formulario que te adjunto, las tablas que ves en él son realmente ficheros de texto. Incluso se puede hacer maestro-detalle.
Si quieres no visualizas los registros y los utilizas a tu antojo

Un saludo

dardo 13-11-2006 12:33:00

Prueba a cambiar la línea del SQL por esta:

frmNumeroUno.Query2.SQL.Add('insert into socios (ci,Ncta,Nombres,Calf) values('+QuotedStr(ci)+','+QuotedStr(num)+','+QuotedStr(nom)+','+QuotedStr(cat)+')');

Teniendo en cuenta que todos los campos son string.
Si hubiera algún numérico no le pongas el QuotedStr()

bohemioloco 13-11-2006 13:49:54

Gracias a todos
 
Al fin lo solucioné..... mejor dicho.. lo solucionaron ustedes :)

Use la sugerencia:

Cita:

Empezado por dardo
Prueba a cambiar la línea del SQL por esta:

frmNumeroUno.Query2.SQL.Add('insert into socios (ci,Ncta,Nombres,Calf) values('+QuotedStr(ci)+','+QuotedStr(num)+','+QuotedStr(nom)+','+QuotedStr(cat)+')');

aunque anteriormente recibi esta
Cita:

Empezado por Neftali
Recuerda también que al realizar un Insert, los campos de tipo texto van entre comillas (Revisa la función QuetedStr);

pero, como buen primerizo :) no me ubiqué.... en mi descargo dire que esta es mi primera vez en Delphi (y en entorno visual) ya que siempre programé en en lenguajes de script, por eso es que utilicé las herramientas que mas me recordaban a lo que anteriormente hice.

A todos los que dieron sugerencias muchas gracias, les aseguro que las estoy revisando para aprender un poco mas y utilizarlas en futuros programas(muy pronto por cierto).. asi que seguro que pronto sabran de mi de nuevo... :)

De nuevo gracias a todos

A los moderadores: no se si esto es spam... si es asi mil disculpas


La franja horaria es GMT +2. Ahora son las 23:54:10.

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