Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 04-02-2019
DarthGomis DarthGomis is offline
Registrado
 
Registrado: feb 2019
Posts: 5
Poder: 0
DarthGomis Va por buen camino
Lectura de fichero errónea

Hola,

Estoy desarrollando una app que lea un fichero con la forma:

N:Nombre;D:0000;F:00/00/0000

Donde N: es un string, D: es un entero y F: es una fecha. (cabe destacar que el orden puede estar alterado y puede que alguna linea no esté bien escrita)

El problema reside en que el método en el cual almaceno los contenidos de la línea en una lista, al llegar al segundo ';' se revoluciona y hace cosas extrañas.

Código Delphi [-]
procedure TForm1.CreateList(fileName: string);
var
  tempLine: string;      //Line with all data
  line: TLine;           //Line with data fragmented
  cha: char;
  Data: TextFile;
  tipe: string;          //Tipe of data
  temp: string;          //temporally data to storage
  nameData: string;          //name data
  numberData: integer;       //number data
  dateData: TDateTime;
  lineData: integer;       //date data

begin
  fileList := TList.Create;
  wrongLines := 0;
  rightLines := 0;
  lineData := 1;

  AssignFile(Data, fileName);
  Reset(Data);

  while not Eof(Data) do
  begin
    while not Eoln(Data) do
    begin
      Read(Data, cha);
      //Select tipe of data
      if UpperCase(temp) = 'N:'
      then
      begin
        tipe := temp;
        temp := '';
      end
      else if UpperCase(temp) = 'D:'
      then
      begin
        tipe := temp;
        temp := '';
      end
      else if UpperCase(temp) = 'F:'
      then
      begin
        tipe := temp;
        temp := '';
      end;
      if (cha = ';') or (lineData = 3)
      then
      begin
        //ShowMessage(tipe);
        if tipe = 'N:'
        then
        begin
          try
            nameData := temp;
            temp:='';
          except
            Inc(wrongLines);
            temp:='';
            break;
          end;
        end
        else if tipe = 'D:'
        then
        begin
          try
            numberData := StrToInt(temp);
            temp:='';
          except
            Inc(wrongLines);
            temp:='';
            break;
          end;
        end
        else if tipe = 'F:'
        then
        begin
          try
            //ShowMessage(temp);
            dateData := StrToDate(temp);
            temp:='';
          except
            //ShowMessage('puto');
            Inc(wrongLines);
            temp:='';
            break;
          end;
        end
        else
        ShowMessage(IntToStr(lineData));
        Inc(lineData);
      end
      else temp := temp + cha;
      ShowMessage('Tipo: ' + tipe + #13 + 'Temp: ' + temp + #13 + 'Caracter: ' + cha
                  + #13 + 'N: ' + nameData + #13 + 'D: ' + IntToStr(numberData) + #13 +
                  'F: ' + DateToStr(dateData));
    end;
    if  not (nameData = '')
    then
    begin
      if not (numberData = 0)
      then
      begin
        if not (dateData = 0)
        then
        begin
          //ShowMessage(DateToStr(dateData));
          line := TLine.Create(nameData, numberData, dateData);
          Inc(rightLines);
          fileList.Add(line);
        end;
      end;
    end;
    nameData := '';
    numberData := 0;
    dateData := 0;
    temp := '';
    lineData := 1;
    ReadLn(Data,tempLine);
  end;
CloseFile(Data);

end;

TList es una clase creada para que me diferencie qué es cada cosa

Código Delphi [-]
TLine = class

  //Data fields of a line
  private
    n: string;      //N:
    d: integer;     //D:
    f: TDateTime;   //F:

  //Properties to read the data values
  public

    line : string;

    property NewName: string
      read n;
    property NewNumber: integer
      read d;
    property NewDate: TDateTime
      read f;

  //Constructor
  constructor  Create(const n : string;
                      const d : integer;
                      const f : TDateTime);
  end;

Sería de gran ayuda que me orientaseis un poco porque soy nuevo en delphi y no tengo mucha idea.
Responder Con Cita
  #2  
Antiguo 05-02-2019
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.265
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Hola y bienvenido al club.
Es difícil porder ayudarte sólo con el código y sin ver una muestra de datos.

Una opción que tal vez nos ayude, es que coloques un fichero de ejemplo (si es posible) o al menos una porción que simule la parte del fichero que te da problemas. De esa forma se puede ejecutar el código con los datos "problemáticos" y darte una idea para solucionarlo.

Puedes comprimir el fichero y el proyecto si lo necesitas y subirlo al mensaje. Si no te deja por permisos contacta con algún moderador/adminsitrador por privado y te ayudarán a hacerlo.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #3  
Antiguo 05-02-2019
bucanero bucanero is offline
Miembro
 
Registrado: nov 2013
Ubicación: Almería, España
Posts: 208
Poder: 11
bucanero Va camino a la fama
Thumbs up

Hola a todos,

Para realizar la separación de los distintos campos por un separador determinado, como es este caso, a mi me gusta utilizar un TStringList por su sencillez y no necesitar utilizar otros componentes, y la forma de funcionamiento es simple:

Código Delphi [-]
var
  sl: TstringList;
  datos:string;
  i: longint;
begin
  // lista de campos en formato string, separados por un delimitador (
  datos := 'N:Nombre;D:0000;F:00/00/0000';
  try
    sl := TStringList.Create;
    sl.StrictDelimiter := True;
    sl.Delimiter := ';';   // delimitador de campos

    sl.DelimitedText := datos; // <-- aqui se pasan los datos
    for i := 0 to sl.count - 1 do
      MessageDlg(sl.strings[i], mtInformation, [mbOK], 0);
  finally
    // se libera el objeto
    sl.Free;
  end;

Y en tu caso en concreto prueba el siguiente código:
Código Delphi [-]
type
  // estructura de datos que se va a recuperar
  TDataRec = record
    nameData: string;          //name data
    numberData: integer;       //number data
    dateData: TDateTime;

    procedure clear;                                 //inicializa los valores
    function loadFromStrings(SL: TStrings): Boolean; //lee los valores desde una lista de strings
    function IsValidData: Boolean;                   //comprueba si los valores son validos
  end;

implementation

{ TDataRec }
procedure TDataRec.clear;
begin
  // se inicializan los datos
  nameData := '';
  numberData := 0;
  dateData := 0;
end;

function TDataRec.IsValidData: Boolean;
begin
  // aqui se realizan las comprobaciones de los datos
  Result := (nameData <> '') and
            (numberData <> 0) and
            (dateData <> 0);
end;

function TDataRec.loadFromStrings(SL: TStrings): Boolean;
var
  tipe, DataStr: string;          //Tipe of data
  APosicion, i: integer;
begin
  Result := False;
  try
    clear;
    // se recorren el numero de campos leidos
    for i := 0 to SL.Count - 1 do begin
      APosicion := Pos(':', SL.strings[i]);
      if APosicion > 0 then begin

        tipe := UpperCase(Copy(SL.strings[i], 1, APosicion));
        DataStr := Copy(SL.strings[i], APosicion + 1, Length(SL.strings[i]));

        //Select tipe of data
        if tipe = 'N:' then
          nameData := DataStr
        else if tipe = 'D:' then
          numberData := StrToInt(DataStr)
        else if tipe = 'F:' then
          dateData := StrToDate(DataStr);
      end;
    end;
    Result := IsValidData;
  except
    on E: Exception do
      MessageDlg(E.message, mtError, [mbOK], 0);
  end;
end;

y aquí el proceso del fichero:
Código Delphi [-]
procedure TForm2.Button1Click(Sender: TObject);
begin
  with OpenDialog1 do
    if execute then
    try
      memo1.lines.BeginUpdate;
      ProcessFile(FileName);
    finally
      memo1.lines.EndUpdate;
    end;
end;

function TForm2.ProcessData(const DataRec: TDataRec): boolean;
begin
  Result := false;

  /// Aqui procesas cada uno de los datos ya una vez leidos 
  with DataRec do begin
    // yo solo muestro los datos en un memo, para verificar que son correctos 
    memo1.Lines.Add(Format('N:' + #9 + '%s ' + #9 + 'D:%d ' + #9 + 'F:' + #9 + '%s', [nameData, numberData, formatdatetime('dd/mm/yyyy', dateData)]));

//    line := TLine.Create(nameData, numberData, dateData);
//    fileList.Add(line);

  end;
  Result := true;
end;

procedure TForm2.ProcessFile(const AFileName: string);
var
  TxtF: TextFile;
begin
  try
    AssignFile(TxtF, AFileName);
    Reset(TxtF);
    ParseFile(TxtF);
  finally
    CloseFile(TxtF);
  end;
end;

procedure TForm2.ParseFile(var TxtF: TextFile);
var
  tempLine: string;
  sl: TstringLIst;
  DataRec: TDataRec;
  rightLines, wrongLines, lineData: integer;       //date data
begin
  wrongLines := 0;
  rightLines := 0;
  lineData := 0;
  try
    //se crea un StringList configurado para serparar los elementos por un delimitador
    // en este caso el ";"
    sl := TStringList.Create;
    sl.StrictDelimiter := True;
    sl.Delimiter := ';';

    while not Eof(TxtF) do begin
      Readln(TxtF, tempLine);
      sl.DelimitedText := tempLine;
      inc(lineData);
      if DataRec.loadFromStrings(sl) and ProcessData(DataRec) then
        Inc(rightLines)
      else
        Inc(wrongLines);
    end;
  finally
    // se libera el objeto
    sl.Free;
  end;
end;

De esta forma aunque los campos te vengan en distinto orden los debes de poder leer sin problemas y en la validación de los datos ya puedes comprobar si te son útiles o no

Un saludo
Responder Con Cita
  #4  
Antiguo 05-02-2019
DarthGomis DarthGomis is offline
Registrado
 
Registrado: feb 2019
Posts: 5
Poder: 0
DarthGomis Va por buen camino
Muchisimas graciaas, me ha servido de mucha ayuda

Un saludo
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Lectura errónea de la versión de mi aplicación Manuel Varios 3 22-09-2011 14:31:38
Llamada erronea Alexandro Humor 1 16-04-2009 19:42:37
Cómo saber si un fichero esta marcado de sólo lectura ? David Varios 2 13-08-2008 16:20:19
Lectura fichero escribe a registro Guillermo80 Varios 3 23-02-2008 22:56:03
Lectura de fichero clipper Isabel_AS Varios 8 10-04-2007 14:39:32


La franja horaria es GMT +2. Ahora son las 17:58:26.


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
Copyright 1996-2007 Club Delphi