IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Delphi Discussion :

affectation String et Record


Sujet :

Langage Delphi

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    16
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 16
    Points : 7
    Points
    7
    Par défaut affectation String et Record
    Bonjour,

    Je souhaite lire un fichier texte dont les lignes peuvent correspondre à 2 structures différentes:

    Exemple:
    NO REFART 00125Designation
    OR REFART Motif refus

    Les 2 premiers char de ligne permettent d'identifier sa structure.

    J'ai déclaré :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    Type
      TStruc_no = record
            type : string[3]
            Ref : string[11]
            Qty : string[5]
            Des : string[50]
         end;
     
      TStruc_or = record
            type : string[3]
            Ref : string[11]
            Motif : string[150]
         end;
     
    Var
       ligne_no : TStruc_no;
       ligne_or : Tstruc_or;
       ligne : string;

    Dans mon code je voudrais faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    //code
      Readln(fichier,ligne);
      if (copy(ligne,1,2) = 'NO')
        then ligne_NO := ligne;
     
      if (copy(ligne,1,2) = 'OR')
        then ligne_OR := ligne;
    mais ça ne fonctionne pas.

    Idem pour :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    //code
      ligne := ligne_NO;
      wrtieln(fichier,ligne);
    Comment dois je faire ?

    Par avance merci.

    Jérôme

  2. #2
    Membre émérite
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    Mars 2006
    Messages
    1 509
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 509
    Points : 2 780
    Points
    2 780
    Billets dans le blog
    10
    Par défaut
    Tu devrais avoir plutôt les infos suivantes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    type
      TStruc_no = record
        type1 : string[3];
        Ref : string[11] ;
        Qty : string[5]  ;
        Des : string[50] ;
       end;
     
      TStruc_or = record
        type1 : string[3] ;
        Ref : string[11]  ;
        Motif : string[150] ;
      end;
     
    Var
    ligne_no : TStruc_no;
    ligne_or : Tstruc_or;
    ligne : string;
     
    begin
     
    ligne := 'AMKmlkmlkml' ;
    if (copy(ligne,1,2) = 'NO')
      then ligne_NO.type1 := copy(ligne,1,3)
     
    ....

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    16
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 16
    Points : 7
    Points
    7
    Par défaut
    Oui effectivement, je viens de corriger mes erreurs de frappe

    tu m'indiques de faire :

    ligne_NO.type1 := copy(ligne,1,3)

    Mais je voudrais éviter de faire :

    ligne_NO.type := copy(ligne,1,3);
    ligne_NO.Ref := copy(ligne,4,11);
    ligne_NO.Qty := copy(ligne,15,5);
    ....


    J'ai en réalité beaucoup de fields, donc je souhaiterais affecter la ligne à la structure.

    Est-il possible de faire un

    ligne_no := ligne; ?

    pour ensuite pouvoir exploiter les éléments de la structure.

  4. #4
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 235
    Points : 8 504
    Points
    8 504
    Par défaut
    Soit l'exemple que tu fournis est faux, soit tu as une erreur dans ton code

    car la Ref que tu montres, n'a que 7 caractères maximum et toi tu indiques 11 dans la Ref.

    Sinon, le mieux serait peut être de diviser en deux ton fonctionnement.
    et de faire 3 types au lieu de 2.

    On remarque que dans les 2 structures tu as des données communes donc pourquoi ne pas faire un type commun

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    Type Struc_Common = record
      Type : String[3];
      Ref : String[11];
    end;
     
    Type
      Struc_no = record
            Qty : string[5]
            Des : string[50]
         end;
     
      Struc_or = record
            Motif : string[150]
      end;
    Après tu n'as plus qu'a lire tes lignes en plusieurs fois

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    var
      Common : Struc_Common
      ligne_NO : Struc_no
      ligne_OR :Struc_or
    begin
      Read(fichier,Common);
      if trim(Common.Type) = 'NO' then
        Read(Fichier,Ligne_NO)
      else
        Read(Fichier,Ligne_OR);
    end;
    Bien sur c'est à tester et à adapter ^^

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    16
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 16
    Points : 7
    Points
    7
    Par défaut
    désolé, mais je ne suis pas.

    je viens de faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    Type
      Struc_Common = record
          Typ : String[3];
          Ref : String[11];
        end;
    
      Struc_no = record
            Qty : string[5];
            Des : string[50];
         end;
    
      Struc_or = record
            Motif : string[150];
         end;
    
    const
      monfichier = 'd:\ess.txt';
    var
      Form1: TForm1;
      fichier : file of Struc_Common;
      Common : Struc_Common;
      ligne_NO : Struc_no;
      ligne_OR :Struc_or;
    
    implementation
    
    {$R *.dfm}
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      assignfile(fichier, monfichier);
      reset(fichier);
      read(fichier,common);
    
      if trim(Common.Typ) = 'NO' then
        Read(Fichier,Ligne_NO)
      else
        Read(Fichier,Ligne_OR);
    
      close(fichier);
    end;
    et la compil plante comme dans mes essais précédents :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        Read(Fichier,Ligne_NO)
        Read(Fichier,Ligne_OR);
    Types incompatibles Struc_Common et Struc_No

  6. #6
    Membre émérite
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    Mars 2006
    Messages
    1 509
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 509
    Points : 2 780
    Points
    2 780
    Billets dans le blog
    10
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
      assignfile(fichier, monfichier);
      reset(fichier);
      read(fichier,common);
     
      if trim(Common.Typ) = 'NO' then
        Read(Fichier,Ligne_NO)
      else
        Read(Fichier,Ligne_OR);
     
      close(fichier);
    C'est normal que ça plante ! La structure Record que tu utilise est une suite de strings et non pas un découpage d'une seule chaine. Donc tu ne coupes pas aux copy pour découper ta chaîne. Ceci-dit moi-je ferais peut être différement. Donne moi le nombre de lignes par fichier et je te donnerai une solution

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    16
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 16
    Points : 7
    Points
    7
    Par défaut
    dans mon prog final, j'aurais 5 structures différentes avec 30 à 40 fields / structures.
    Dans mon fichier en lecture j'aurais de 1 à x lignes.

    Donc je dois bien passer par une découpe de ma chaînes.

    Merci quand même

  8. #8
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 708
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 708
    Points : 25 590
    Points
    25 590
    Par défaut
    Ah la lecture de fichier structuré, ma spécialité !

    La Découpe peut-être entièrement géré par structure, j'ai déjà mis un exemple de code à ce sujet pour les Fichiers NX (CCAM), où il y a environ 200 type de ligne différent avec une dizaine de champ en moyenne, ...

    Les Lignes sont-elles complètes ?
    Par Exemple une ligne NO fait toujours 69 de longueur (complèté par des espaces par exemple) ou est-ce des longueurs variables ?

    le problème d'utiliser des ShortString dans les structures ajoute un octet pour la longueur, de plus, il vaut mieux ajouter la directive packed pour éviter des alignements processeurs ... même si avec le ShortString cela ne devrait pas arriver

    Pour le moment, je ne donnerais pas d'exemple, mais sinon je suis pour le moment assez d'accord avec Malatar, mais il faut pour que cela fonctionne des lignes à structure fixe ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Type
      Struc_Common = packed record
          Typ : Array[1..3] of Char;
          Ref : Array[1..11] of Char;
        end;
     
      Struc_no = packed record
            Qty : Array[5] of Char;
            Des : Array[50] of Char;
     
         end;
    le Array of Char, normalement, se lit facilement comme une chaine, il est possible de faire "Typ = 'OR'" ou même le passer à une fonction "StrToInt(Qty)"

    pour l'écriture c'est un peu plus problématique mais cela se résoud

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    StringToArrayOfChar('Salut', @ligne_NO.Des[1], Length(ligne_NO.Des));
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    StringToArrayOfChar(PChar(AString), @ligne_NO.Des[1], Length(ligne_NO.Des));

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    procedure StringToArrayOfChar(const S: string; const AoC: PChar; const LengthAoC: Integer);
    var
      LengthS: Integer;
    begin
      if LengthAoC <= 0 then
        Exit;
     
      LengthS := Length(S);
      if LengthS < LengthAoC then
      begin
        ZeroMemory(Pointer(Integer(AoC) + LengthS), LengthAoC - LengthS);
        CopyMemory(AoC, @S[1], LengthS);
      end else
      begin
        StrLCopy(AoC, @S[1], LengthAoC);
      end;
    end;

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    16
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 16
    Points : 7
    Points
    7
    Par défaut
    Oui ta solution fonctionne, je viens d'essayer, mais je retombe sur la même problématique :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    Type
      TMa_Struc = packed record
          Typ : Array[1..3] of Char;
          Ref : Array[1..11] of Char;
          Qty : Array[5] of Char;
          Des : Array[50] of Char;
        end;
     
     
    Var
     fichier:textfile;
     mastring : string;
     monenreg : TMa_struc;
     
    begin
      assignfile(fichier, monfichier);  
      reset(fichier);
      read(fichier,mastring);
     
     
      // StringToArrayOfChar('Salut', @ligne_NO.Des[1], Length(ligne_NO.Des));
    Comment dois je faire pour copier "mastring" dans "monenreg" ?

  10. #10
    Membre émérite
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    Mars 2006
    Messages
    1 509
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 509
    Points : 2 780
    Points
    2 780
    Billets dans le blog
    10
    Par défaut
    Tu dois faire d'abord un read de la partie commune puis un read de la partie particuliere

  11. #11
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 708
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 708
    Points : 25 590
    Points
    25 590
    Par défaut
    Déjà tu n'utilise pas un Textfile mais file ... ensuite pour t'aider j'ai besoin que tu répondes à ces questions

    Toutes lignes sont des longueur identique, si pas de valeur, c'est complété par des espaces ? ou est-ce que chaque type de ligne à une longueur différente, et même pire est-ce chaque ligne d'un même type peuvent varier en longueur, fourni, moi un exemple REEL de lignes de ton Fichier ... en précisant les espaces par des _ (c'est ce qu'on appele souvent le "Spare")

    et comme Al, Mal, ... tu l'ont dit, une structure d'entête avec le type, puis une structure par données, où si tu es de longueur fixe, un truc de ce genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    // Type Utilisé pour faciliter le Découpage des buffers
    type
      TNXDataRecord = packed record
        TypeRecord: Array[1..3] of Char;
        Data: Array[1..NX_DATA_SIZE - NX_DATA_SIZE_TYPE] of Char;
        EndRecord: Char; // Toujours #$0A;
      end;
     
    // Type 000
    type
      TNXData_000 = packed record
        TypeRecord: Array[1..3] of Char;
        TypeEmetteur: Array[1..2] of Char;
        NumEmetteur: Array[1..14] of Char;
        ProgEmetteur: Array[1..6] of Char;
        TypeDestinataire : Array[1..2] of Char;
        NumDestinataire: Array[1..14] of Char;
        ProgDestinataire: Array[1..6] of Char;
        Application : Array[1..2] of Char;
        IDFichier: Array[1..3] of Char;
        Data: Array[1..76] of Char;
        EndRecord: Char; // Toujours #$0A;
      end;
     
    type
      TNXData_000_TIP = packed record
        TypeRecord: Array[1..3] of Char;
        TypeEmetteur: Array[1..2] of Char;
        NumEmetteur: Array[1..14] of Char;
        ProgEmetteur: Array[1..6] of Char;
        TypeDestinataire : Array[1..2] of Char;
        NumDestinataire: Array[1..14] of Char;
        ProgDestinataire: Array[1..6] of Char;
        Application : Array[1..2] of Char;
        IDFichier: Array[1..3] of Char;
        DateCreation: Array[1..6] of Char; //AAMMJJ
        InfoNOEMIE: Array[1..24] of Char;
        NumChrono: Array[1..5] of Char;
        TypeFichier: Char;
        UniteMonetaire: Char;
        Spare: Array[1..39] of Char;
        EndRecord: Char; // Toujours #$0A;
      end;
     
    ...

  12. #12
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    16
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 16
    Points : 7
    Points
    7
    Par défaut
    je dois être mauvais, je ne pige pas..

    Quand tu déclares ton fichier tu le déclare avec une structure "Struc_common" et derrière tu lis avec "ligne_NO" moi j'ai une erreur de compil :
    type incompatibles : "struc_common" et "struc_no"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
    Type Struc_Common = record
      Type : String[3];
      Ref : String[11];
    end;
     
    Type
      Struc_no = record
            Qty : string[5]
            Des : string[50]
         end;
     
      Struc_or = record
            Motif : string[150]
      end;
     
    Var
      fichier : file of Struc_Common
      Common : Struc_Common;
      ligne_NO : Struc_no;
      ligne_OR :Struc_or;
     
    begin 
      Read(fichier,Common);
      if trim(Common.Type) = 'NO' then
        Read(Fichier,Ligne_NO)
      else
        Read(Fichier,Ligne_OR);

  13. #13
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 446
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 446
    Points : 5 867
    Points
    5 867
    Par défaut
    salut

    c'est pas super compliqué ils t'on machés le boulot

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    Type
      TMa_Struc = packed record
          Typ : Array[1..3] of Char;
          Ref : Array[1..11] of Char;
          Qty : Array[5] of Char;
          Des : Array[50] of Char;
        end;
     
     
    Var
     fichier:textfile;
     mastring : string;
     monenreg : TMa_struc;
     
    begin
      assignfile(fichier, monfichier);  
      reset(fichier);
      read(fichier,mastring);
       StringToArrayOfChar(Copy(mastring, 1,3), @monenreg.Typ[1],Length(monenreg.Typ));
     
    StringToArrayOfChar(Copy(mastring, 4,15), @monenreg.Ref[1],Length(monenreg.Ref));
      ...
    @+ Phil

  14. #14
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 235
    Points : 8 504
    Points
    8 504
    Par défaut
    Citation Envoyé par jdavid
    je dois être mauvais, je ne pige pas..
    Répond au question de ShaiLeTroll. Ca permettrait de te donner une solution plus correcte.

    Sinon, normal que ca te fasse une erreur de compilation, tu as un fichier de type file of Struc_Common et toi tu veux lire dedans une structure Struc_NO.

  15. #15
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 708
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 708
    Points : 25 590
    Points
    25 590
    Par défaut
    @anapurna,
    le copy n'est pas utile dans le cas de lecture de fichier avec structure, car cela est fait simplement par le typage fort du 'array of char'
    j'ai fait StringToArrayOfChar pour l'écriture dans le record dans le cadre de l'ecriture dans le fichier et surtout pas au moment de la lecture ...

    on va utiliser un fichier non typé "fichier : file;" ainsi on peut lire n'importe quoi ! mais cela demande un peu plus de travail car ce n'est pas read mais blockread la bonne fonction, ...

    Comme, l'a précisé Malatar, mes questions ne sont pas là par hazard,
    dans le cas d'une longueur fixe pour toutes lignes tout type, on aura une lecture via une structure commune et du transtypage,
    dans le cas de longueur fixe différente pour chaque type on aura une lecture via une structure d'entête puis une lecture différiencé par type,
    dans le case de longueur variable pour chaque ligne, faudra avoir plus d'info sur le format, mais ce dernier cas me semble peu probable ...

  16. #16
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    16
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 16
    Points : 7
    Points
    7
    Par défaut
    Citation Envoyé par Malatar
    Répond au question de ShaiLeTroll. Ca permettrait de te donner une solution plus correcte.

    Sinon, normal que ca te fasse une erreur de compilation, tu as un fichier de type file of Struc_Common et toi tu veux lire dedans une structure Struc_NO.

    Désolé, mais quand j'ai répondu, je n'avais pas vu le message de ShaileTroll, donc je regarde et là peut être vais-je comprendre

  17. #17
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    16
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 16
    Points : 7
    Points
    7
    Par défaut
    Citation Envoyé par ShaiLeTroll
    Déjà tu n'utilise pas un Textfile mais file ... ensuite pour t'aider j'ai besoin que tu répondes à ces questions

    Toutes lignes sont des longueur identique, si pas de valeur, c'est complété par des espaces ? ou est-ce que chaque type de ligne à une longueur différente, et même pire est-ce chaque ligne d'un même type peuvent varier en longueur, fourni, moi un exemple REEL de lignes de ton Fichier ... en précisant les espaces par des _ (c'est ce qu'on appele souvent le "Spare")

    et comme Al, Mal, ... tu l'ont dit, une structure d'entête avec le type, puis une structure par données, où si tu es de longueur fixe, un truc de ce genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    // Type Utilisé pour faciliter le Découpage des buffers
    type
      TNXDataRecord = packed record
        TypeRecord: Array[1..3] of Char;
        Data: Array[1..NX_DATA_SIZE - NX_DATA_SIZE_TYPE] of Char;
        EndRecord: Char; // Toujours #$0A;
      end;
     
    // Type 000
    type
      TNXData_000 = packed record
        TypeRecord: Array[1..3] of Char;
        TypeEmetteur: Array[1..2] of Char;
        NumEmetteur: Array[1..14] of Char;
        ProgEmetteur: Array[1..6] of Char;
        TypeDestinataire : Array[1..2] of Char;
        NumDestinataire: Array[1..14] of Char;
        ProgDestinataire: Array[1..6] of Char;
        Application : Array[1..2] of Char;
        IDFichier: Array[1..3] of Char;
        Data: Array[1..76] of Char;
        EndRecord: Char; // Toujours #$0A;
      end;
     
    type
      TNXData_000_TIP = packed record
        TypeRecord: Array[1..3] of Char;
        TypeEmetteur: Array[1..2] of Char;
        NumEmetteur: Array[1..14] of Char;
        ProgEmetteur: Array[1..6] of Char;
        TypeDestinataire : Array[1..2] of Char;
        NumDestinataire: Array[1..14] of Char;
        ProgDestinataire: Array[1..6] of Char;
        Application : Array[1..2] of Char;
        IDFichier: Array[1..3] of Char;
        DateCreation: Array[1..6] of Char; //AAMMJJ
        InfoNOEMIE: Array[1..24] of Char;
        NumChrono: Array[1..5] of Char;
        TypeFichier: Char;
        UniteMonetaire: Char;
        Spare: Array[1..39] of Char;
        EndRecord: Char; // Toujours #$0A;
      end;
     
    ...
    En réalité, pour l'instant je fais des tests, la structure définitive qui viendra de notre maison mère Allemande n'est pas finalisée.

    Les infos pour l'instant sont :
    - chaque type aura sa propre longueur.
    - tous les enregistrements d'un même type seront de même longueur (compléter par des blancs).
    - Chaque type devrait avoir 30à 40 fields.

    Je suis donc en train de faire un exemple fictif avec dans un fichier texte et 2 enregs de type différent NO et OR et je vois comment simplement je pourrais extraire les fields pour les réinjecter dans une base DB2/400.

    voila le problème exacte



    NO_ARTICLE1___00100designation___________________________________________________________
    OR_ARTICLE2___Non reference______________________________________________________________

  18. #18
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 708
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 708
    Points : 25 590
    Points
    25 590
    Par défaut
    Parfait !!!

    Donc c'est le cas numéro 2 !
    Chaque type à une longueur fixe, avec spare si nécesairre ... bon voici donc un exemple de code, ... c'est un peu fouilli mais cela fonctionne ...

    Sinon, il ne faut pas hésiter à faire une classe pour gérer le fichier, genre un "TFileNomDeFormatReader"

    d'ailleurs, tu peux avoir des structures de Travail avec des array of char, avec des structures communes ... et des structures métiers avec des chaines (des objets seraient parfaitement appropriér) et bien sur des fonctions qui transforme l'un en l'autre et réciproquement, car pour le métier avoir la quantité sous la forme d'un entier sera plus sympa que l'avoir en array of char, qui sont à manipuler par CopyMemory pour l'écriture ... la dessus, je pourrais aider ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    type
      TStruc_Common = packed record
        Type : array[1..3] of Char;
        Ref : array[1..11] of char;
      end;
     
      TStruc_NO = packed record
        Qty : array[1..5] of Char;
        Des : array[1..50] of Char;
        Autre : array[1..20] of Char;
        Encore : array[1..20] of Char;
      end;
     
      TStruct_OR = packed record
        Motif : array[1..150] of Char;
        Mais : array[1..20] of Char;
        Pourquoi : array[1..20] of Char;
      end;
     
      TStruct_END = packed record
        Marque : array[1..2] of Char;
      end;
    Var
      fichier : file; // fichier simple
      ligne_Common : TStruct_Common;
      ligne_NO : TStruct_NO;
      ligne_OR :TStruct_OR ;
      ligne_END :TStruct_END ;
      AmtTransferred: Integer;
    begin 
      AssignFile(fichier, FileName);
      Reset(fichier, 1); // pour la lecture byte par byte ... 
     
      while not Eof(fichier) do
      begin
        // Lecture de l'Entête de Ligne contenant le Type de ligne et la référence
        BlockRead(fichier, ligne_Common, SizeOf(ligne_Common), AmtTransferred);
        if AmtTransferred <> SizeOf(ligne_Common) then
          Abort;
        ShowMessage(Ligne_NO.Ref);
        if trim(ligne_Common.Type) = 'NO' then
        begin
          BlockRead(Fichier, Ligne_NO, SizeOf(Ligne_NO), AmtTransferred);
          if AmtTransferred <> SizeOf(ligne_NO) then
            Abort;
     
          ShowMessage(Ligne_NO.Qty);
          ShowMessage(Ligne_NO.Des);
          ShowMessage(Ligne_NO.Autre);
          ShowMessage(Ligne_NO.Encore);
        end
        else
        begin
          BlockRead(Fichier, Ligne_OR, SizeOf(Ligne_OR), AmtTransferred); 
          if AmtTransferred <> SizeOf(ligne_NO) then
            Abort;
     
          ShowMessage(Ligne_NO.Motif);
          ShowMessage(Ligne_NO.Mais);
          ShowMessage(Ligne_NO.Pourquoi);
        end;
     
        // on peut supposer un CR LF à la fin de chaque ligne, il ne faut pas les oublier
        BlockRead(fichier, ligne_END, SizeOf(Ligne_END), AmtTransferred);
       if AmtTransferred <> SizeOf(ligne_END) then
            Abort;  
      end;
    end;

  19. #19
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    16
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 16
    Points : 7
    Points
    7
    Par défaut
    Ok

    Je m'étais mal exprimé, là j'ai pigé le truc, la lecture byte par byte, effectivement c'est la solution logique. Mais je n'utilise jamais, moi je suis AS/400 et BD un autre monde.

    Je vais tester, mais là je suis très confiant.

    Merci pour cette précieuse aide.


    Citation Envoyé par ShaiLeTroll
    Ah la lecture de fichier structuré, ma spécialité !
    Je confirme, c'est bien ta spécialité

    encore merci

  20. #20
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 708
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 708
    Points : 25 590
    Points
    25 590
    Par défaut
    Lol, AS/400, je l'aurais parié ! j'ai bcp utilisé de fichier provenant de MOVEX ou IGE (DL Consultant) pour les données métiers liés à l'activité textile (trieuse de vêtement dont je m'occupais du pilotage ... je manipulais les fichiers de la même façon que les buffers TCP/IP provenant de l'automate, byte par byte avec CopyMemory ou Transtypage ...)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. affecter string par char[]
    Par salihovic dans le forum Débuter
    Réponses: 8
    Dernier message: 08/05/2009, 17h15
  2. Affectation de String dans un tableau ?
    Par debie1108 dans le forum Collection et Stream
    Réponses: 8
    Dernier message: 08/11/2006, 10h19
  3. [VB.NET]SourceGrid et affectation de valeurs dans une String
    Par Bourbaky dans le forum Windows Forms
    Réponses: 1
    Dernier message: 01/03/2006, 21h41
  4. Réponses: 2
    Dernier message: 27/01/2006, 17h47
  5. affecter l' hexa d'un nombre a un string
    Par sorari dans le forum SL & STL
    Réponses: 2
    Dernier message: 12/05/2005, 15h50

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo