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)
-   -   Importar un txt (https://www.clubdelphi.com/foros/showthread.php?t=65519)

jafera 21-12-2009 18:19:07

Importar un txt
 
Buenas de nuevo a todos.

Voy a proponer un problema de parvulitos pero me lleva de cabeza.
En una aplicación genero un fichero txt sin ningun problema, este fichero lo quiero utilizar para crear una tabla nueva juntando dos ficheros iguales, pero con datos diferentes (txt en cuestión) creados con dos máquinas distintas.
Necesita saber como lo hago para importar este fichero desde delphi y como lo hago para poner un campo ID que sea el ultimo más 1.
El fichero txt ya tiene un ID que no me sirve ya que tendría dos veces el ID 1, dos veces el ID 2 etc.

Gracias

Josep

juanlaplata 21-12-2009 18:58:57

Importar ...
Código Delphi [-]
var
arch: TStringList;
i:integer;
var_1, var_2 , var_3 :string;
...
begin

 arch:= TStringList.Create;
arch.LoadFromFile( 'Path_Archivo.txt' );

for  i:=0  to arch.Count-1 do
   begin
   temp:= arch.Strings[i];
   var_1:= strToInt(copy(temp,1,2));   // la posicion y longitud del dato1
   var_2:= strToInt(copy(temp,4,10)); // la posicion y longitud del dato2
   var_3:= strToInt(copy(temp,15,5)); // la posicion y longitud del dato3

    // posiciones y longitud las sabras de antemano,
    // puede ser tambien que los datos esten separados por algun caracter especial
    // para lo cual deberias buscar dentro del renglon como dividir

   {hacer una cosulta para rescatar el ultimo id usado
    query:
    SELECT Max(Tabla.Id) +1  AS MaxId
    FROM Tabla;
    Dependiendo del motor y Base q uses sabras como hacerla
    Luego..}
   
   nuevo_id := resultado_query ;

    // aqui hacer el insert a la nueva tabla

   end;                  
...
arch.Free;
end ;
Cualquier duda, consulta, y entramos en detalles

jafera 21-12-2009 20:32:34

Perdonad, se me ha ido la pinza con la base, uso Firebird 1.5 con Delphi 6

Voy a probar la respuesta.

Gracias

Josep

jafera 24-12-2009 01:56:21

Buena a todos, ya he conseguido hacer lo que queria, pongo el codigo a continuación.

Código Delphi [-]
 
procedure TF_Importa.BitBtn1Click(Sender: TObject);
var
F:TIBInputDelimitedFile;
i:integer;
begin
        F_Confirmacio := TF_Confirmacio.Create(self);
        F_Confirmacio.Label1.Caption:= 'Importem arxiu';
        try
        If F_Confirmacio.ShowModal = mrok then
        begin
                F_ModulDades.Act_Girona_Hist.Close;
                F_ModulDades.Act_Girona_Hist.Open;
                F_ModulDades.Act_Girona_Hist.Last;
                i:=F_ModulDades.Act_Girona_HistID.Value+1;
                F_ModulDades.Act_Girona_Hist.Append;
                F_ModulDades.Act_Girona_HistID.Value:=i;
                F_Importa.IBSQLImporta.SQL.Text := 'Insert into RE0006AGT values(:ID, :ID_REBUT, :ID_ARBITRE, :NOM, :DATA, :TITOL, :CODI_CLUB, :CANON, :PASSADA)';
                F := TIBInputDelimitedFile.Create;
                try
                        F.ColDelimiter:=';';
                        If OpenDialog1.Execute then
                        begin
                                F.Filename:=OpenDialog1.FileName;
                        end;
                        F_Importa.IBSQLImporta.BatchInput(F);
                finally
                        F.Free;
                end;
                Posa_S.ExecSQL;
        end;
        finally
                F_Confirmacio.Free;
        end;
        Showmessage('Procés finalitzat');
end;

Solo tengo una duda, como controlo si los registros ya existen antes de insertarlos a la tabla?. Ahora no me controla nada y se me duplican los datos, lo cual no me interesa.

De nuevo gracias a todos.

Josep

Caral 24-12-2009 02:05:59

Hola
Veo que tienes un campo ID, esto por lo general es único, no se repite.
Yo lo que hago es hacer una consulta previa a este campo y lo comparo con el que se incluirá, si son iguales entonces no se grabara el registro.
Saludos

jafera 24-12-2009 02:12:50

Gracias Caral, yo pensaba algo así pero no se como codificarlo o mejor dicho donde ejecuta esta consulta.

Josep

Caral 24-12-2009 02:23:41

Hola
Lo que haces es una inserción con un botón, en ese mismo momento se hace la comparación:
Coloca un query nuevo en el form, lo enlazas a la tabla.
Supongo que tendras un edit o dbedit donde escribes el ID, entonces lo haces asi:

Código Delphi [-]
procedure TF_Importa.BitBtn1Click(Sender: TObject);
var
F:TIBInputDelimitedFile;
i:integer;
begin
     // aqui empieza la comparacion
    If dit1.Text <> '' then    // si el edit esta lleno entonces:
   Begin
     TuQuery.Active:= false;
     TuQuery.SQL.Text:= 'Select ID from TuTabla Where ID = :cod ';
     TuQuery.Parameters.ParamByName('cod').Value := Edit1.Text;  // esto depende del componente que uses
     TuQuery.Active := true;
     IF TuQueryID.AsString = Edit1.Text then  //puede ser tambien value
     begin
     MessageDlg('ID ya existe, favor seleccionar otro',mtError,[mbOK],0);
     Edit1.Text:= '';
     end
     else
        F_Confirmacio := TF_Confirmacio.Create(self);
        F_Confirmacio.Label1.Caption:= 'Importem arxiu';
        try
        If F_Confirmacio.ShowModal = mrok then
        begin
                F_ModulDades.Act_Girona_Hist.Close;
                F_ModulDades.Act_Girona_Hist.Open;
                F_ModulDades.Act_Girona_Hist.Last;
                i:=F_ModulDades.Act_Girona_HistID.Value+1;
                F_ModulDades.Act_Girona_Hist.Append;
                F_ModulDades.Act_Girona_HistID.Value:=i;
                F_Importa.IBSQLImporta.SQL.Text := 'Insert into RE0006AGT values(:ID, :ID_REBUT, :ID_ARBITRE, :NOM, ATA, :TITOL, :CODI_CLUB, :CANON, :PASSADA)';
                F := TIBInputDelimitedFile.Create;
                try
                        F.ColDelimiter:=';';
                        If OpenDialog1.Execute then
                        begin
                                F.Filename:=OpenDialog1.FileName;
                        end;
                        F_Importa.IBSQLImporta.BatchInput(F);
                finally
                        F.Free;
                end;
                Posa_S.ExecSQL;
        end;
        finally
                F_Confirmacio.Free;
        end;
        Showmessage('Procés finalitzat');
end;
Si el ID ya existe no guardara nada y dara el foco al edit, de lo contrario lo grabara.
Saludos

jafera 24-12-2009 10:16:31

Gracias de nuevo por tus consejos Caral.
Te cuento, en mi form solo tengo un boton para ejecutar la importacion y uno para salir, un opem dialog y una consulta para pasar un campo a un valor una vez finalizada la importacion, en este form yo no veo nada de informaciónni edit ni nada de nada y no puedo usar el ID porque este campo se genera automaticamente ya que el arvchivo de importacion, el txt, puede proceder de dos maquinas distintas con lo cual este ID se repite y yo lo que hago es crear uno nuevo para cada linea.
Yo pensaba en la utilizacion de algun tpo de array con los campos ID_CURSA, ID_ARBITRE ya que esta combinacion si que es irrepetible en los ficheros que yo genere, aunque si se puede repetir en el fichero que me envie mi compañero para hacer el total.
Otro posibilidad seria usar tres campos, ID_CURSA, ID_ARBITE, DATA ya que un mismo comisario no puede estar en dos carreras el mismo día, no se estoy un poco perdido.

Saludos

Josep

Caral 24-12-2009 13:52:29

Hola
No entiendo en realidad cual es la función del archivo de texto que te envían, para que?, que contiene?.
Entiendo que usas Firebird como BD, también creo entender que generas un ID nuevo cada vez que introduces los datos que recibes de los archivos txt.
La verdad no entiendo:
1- por que del uso de los TXT.
2- por que no usar directamente la BD.
3- cual es el problema de crear un nuevo ID o numero irrepetible en la BD.
4- cual es el problema de capturar el numero del archivo txt y sumarle 1 o añadirle algo mas.
Creo que estoy algo perdido con lo que te sucede, no logro entender cual es el problema.
Saludos

jafera 24-12-2009 20:35:20

Voy a ver si pongo un poco de luz al asunto.

El tema es que trabajamos con dos ordenadores distantes entre si, sin conexion fisica y la unica manera que se me ocurre de unir la informacin de dos tablas, una de cada ordenador es con un fichero txt.

Os adjunto un ejemplo de los ficheros que genero y el resultado que tendría que obtener.

El resutado es un txt de la tabla, este txt no lo necesito, es solo ejemplo.

A ver si así se ve claro.

Josep

Archivo Adjunto 1582

Archivo Adjunto 1583

Archivo Adjunto 1584

Caral 25-12-2009 16:55:22

Hola
Me imagino que el archivo TXT lo envían de ordenador a ordenador via Email ??.
Si es ese el caso quiere decir que aun que no estén en red o en la misma ubicación los dos ordenadores tienen acceso a internet.
Si tienen acceso a internet te aconsejaría que olvides el asunto de los archivos txt y conectes el programa a la bd directamente, como dije, vía internet.
Firebird se conecta fácilmente vía internet es muy fiable y fácil de configurar.
En el foro hay mucha información de como hacerlo, veras que te quitas muchos dolores de cabeza y trabajo de encima ya que no se tendrá que estar dijitando la información que recibes, quedara grabada directamente.
De todos modos, si insistieras en seguir con los archivos txt te aconsejo que no se generen de la forma que lo haces, me parece que deberían de configurarse como un archivo INI y que el programa capture la información sin hacer nada.
Una vez capturada la información me parece que lo lógico seria crear un campo adicional en la tabla para que este sea el irrepetible.
Espero ayudarte un poco aunque no esperes mucho de este novato.
Saludos


La franja horaria es GMT +2. Ahora son las 06:54:14.

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