Ver Mensaje Individual
  #3  
Antiguo 05-02-2019
bucanero bucanero is offline
Miembro
 
Registrado: nov 2013
Ubicación: Almería, España
Posts: 208
Reputación: 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