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

Programmation et administration système Perl Discussion :

Problème de While imbriqués


Sujet :

Programmation et administration système Perl

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2012
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2012
    Messages : 18
    Par défaut Problème de While imbriqués
    Bonjour,

    je débute en Perl et j'ai quelque problème avec deux While imbriqués.

    Le contexte:
    - Un fichier "Client" qui contient tout un tas de données dont un numéro d'agence qui sert de clef de recherche pour un second fichier "Agence"
    - Un fichier "Agence" qui contient l'adresse de l'agence qui doit être récupérée via le numéro d'agence du premier fichier

    Le résultat est une agrégation des données des 2 fichiers dans un fichier "Résultat".

    J'ai tapé ce code mais je ne comprends pas pourquoi, une fois la première exécution terminée, le programme ne continue pas à boucler sur les autres lignes.

    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
     
    #!C:\Perl64\bin\
     
      use strict;
      use warnings;
      use Text::CSV;
      use Text::CSV::Encoded;
     
    #$csv = Text::CSV::Encoded->new ({ encoding  => "utf8" });
     
    #Ouverture du fichier Client en Lecture
      my $FicCli = "C:/Users/A454222/Documents/__Dev Perl/Extrait_FluxMailing_FL17_2.csv";
      my $Client_Csv = Text::CSV->new ({
          binary    => 1, # Allow special character. Always set this
          auto_diag => 1, # Report irregularities immediately
          sep_char => ";"
          });
      open(Cli_Csv, "<", $FicCli) or die $!;
     
    #Ouverture du fichier Agence en Lecture
      my $FicAgence = "C:/Users/A454222/Documents/__Dev Perl/Extrait_FluxGuichetPriPro_FL17.csv";
      my $Agence_Csv = Text::CSV->new ({
          binary    => 1, # Allow special character. Always set this
          auto_diag => 1, # Report irregularities immediately
          sep_char => ";"
          });
      open(Age_Csv, "<", $FicAgence) or die $!;
     
    #Ouverture du fichier Result en Ecriture
      my $FicResult = "C:/Users/A454222/Documents/__Dev Perl/Result.txt";
      open(FicRes, ">", $FicResult) or die $!;
     
      my $count = 0 ;
    while (<Cli_Csv> ) {
        next if ($. == 1);
        if ($Client_Csv->parse($_)) {
            my @columns = $Client_Csv->fields();
    		my $CliCodeAgence = $columns[2];
    		$count++;
    		while (<Age_Csv>) {
    			next if ($. == 1);
    			if ($Agence_Csv->parse($_)) {
    				my @colAgence = $Agence_Csv->fields();
    				my $AgeCodeAgence = $colAgence[1];
    				if ($AgeCodeAgence == $CliCodeAgence) {
    					print (FicRes "30003",";",";",$columns[19],";","FR",";",$columns[2],";",sprintf("%015u",$count),";"," ",";"," ",";"," ",";"," ",";","                   ",";",$columns[14],";",$columns[15],";",$columns[16],";",$columns[17],";",$columns[18],";",$columns[19]," ",$columns[20],";",$colAgence[1],";",$colAgence[3],";",$colAgence[6],";",$colAgence[7],";",$colAgence[8]," ",$colAgence[9],";",$colAgence[10],"\n");
    				}
    			} else {
    				my $err2 = $Agence_Csv->error_input;
    				print "Failed to parse line: $err2";
    			}
    		}
        } else {
            my $err = $Client_Csv->error_input;
            print "Failed to parse line: $err";
        }
    }
     
    close FicCli ;
    close FicAgence ;
    Ci-dessous les 3 fichiers (les 2 fichiers csv (Extrait_FluxMailing_FL17_2.csv et Extrait_FluxGuichetPriPro_FL17.csv) ont été renommés en .txt pour pouvoir être uploadés.

    Result.txtExtrait_FluxGuichetPriPro_FL17.txtExtrait_FluxMailing_FL17_2.txt

    Pourriez-vous, svp, m'indiquer là où je me trompe ?

    Merci par avance de votre aide.

  2. #2
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2012
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2012
    Messages : 18
    Par défaut
    bon, j'ai trouvé en cherchant un peu ...

    après la seconde boucle While, il suffit de rajouter un "seek(Age_Csv,0,0)" et ça fonctionne parfaitement.

  3. #3
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Billets dans le blog
    1
    Par défaut
    Bon, tu as trouvé toi-même la solution, mais je remarque que ce code, avec ces deux boucles while imbriquées, est inefficace, car il relit le fichier des agences pour chaque entrée du fichier des clients.

    Il serait bien plus efficace de commencer par lire le fichier des agences (une seule fois) et de stocker son contenu dans un hachage (avec l'identifiant de l'agence comme clef du hachage). Ensuite, il suffit de lire le fichier des clients et de faire une recherche de l'agence dans le hachage.

    Bien sûr, ça n'a pas trop d'importance si tes fichiers ne contiennent que quelques dizaines de lignes, mais ça fera une différence considérable si tes fichiers sont plus gros. Pour de gros fichiers, ça peut aller des milliers de fois plus vite.

  4. #4
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2012
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2012
    Messages : 18
    Par défaut
    Bonsoir,

    tout d'abord, merci d'avoir bien voulu prendre le temps de me répondre et de me conseiller.

    J'avais cherché par moi-même d'autres solutions à mon script car 3m30s pour faire le fichier me semblait vraiment trop long.

    Du coup, je m'étais tourné vers les tables de hachage et je vois que c'était ce que tu me conseillais !

    Mais ... je n'arrive pas à récupérer les données les données passées la première fois dans le hash !

    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
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
     
    #!C:\Perl64\bin\
     
      use strict;
      use warnings;
      use DBI;
      use Text::CSV;
      use List::Util "first";
     
      #Ouverture du fichier Client en Lecture
      my $FicCli = "C:/Users/A454222/Documents/__Dev Perl/Test sort/FluxMailing_FL17_2.csv";
      my $Client_Csv = Text::CSV->new ({
          binary    => 1, # Allow special character. Always set this
          auto_diag => 1, # Report irregularities immediately
    	  allow_loose_quotes => 1,
          sep_char => ";"
          });
      open(Cli_Csv, "<", $FicCli) or die $!;
     
      #Ouverture du fichier Agence en Lecture
      my $FicAgence = "C:/Users/A454222/Documents/__Dev Perl/Test sort/File to sort/FluxGuichetPriPro_FL17.csv";
      my $Agence_Csv = Text::CSV->new ({
          binary    => 1, # Allow special character. Always set this
    	  allow_loose_quotes => 1,
          auto_diag => 1, # Report irregularities immediately
          sep_char => ";"
          });
      open(Age_Csv, "<", $FicAgence) or die $!;
     
      #Ouverture du fichier Agence Trié en Ecriture
      my $FicSorted = "C:/Users/A454222/Documents/__Dev Perl/Test sort/File_Sorted.csv";
      open(FicSort, ">", $FicSorted) or die $!;
     
      #Ouverture du fichier Result en Ecriture
      my $FicResult = "C:/Users/A454222/Documents/__Dev Perl/Test sort/Result_Full.txt";
      open(FicRes, ">", $FicResult) or die $!;
     
      ##########################################################
      ################# Debut de la Partie Tri #################
      ##########################################################
      #Creation de la DataBase pour le Tri du fichier Agence
      my $dbh = DBI->connect('dbi:CSV:', undef, undef, {
        RaiseError => 1,
        f_ext => '.csv',
    	f_dir => "File to sort",
    	f_dir_search => "File sorted",
    	csv_sep_char => ";",
        csv_tables => { FluxGuichetPriPro_FL17 => { col_names => [qw' Code_DEC Code_Agence Code_DR Nom_Agence Type_Agence Cplt_Intitule_Adresse Rue Lieu_Dit Code_Postal Ville Num_Tel_Signataire Civilite Prenom Nom '] } },
    });
     
      #Creation de la requete SQL pour le Tri sur le Champ Code_Agence
      my $sth = $dbh->prepare(q{
        SELECT * FROM FluxGuichetPriPro_FL17 ORDER BY Code_Agence
    });
     
      #Execution de la requête
      $sth->execute;
     
      my %Hash;
      my $CodeAgenceCli = 0;
      my $count = 0;
      #Ecriture du Tableau trié dans le fichier File_Sorted.csv
      while ( my @row = $sth->fetchrow_array ) {
        my $LineSorted = join(';' => @row);
    	print(FicSort $LineSorted,"\n");
    	$CodeAgenceCli = $row[1] ;
    	%Hash = ($CodeAgenceCli => $LineSorted);
    	#print (FicRes "Borne Deb = ", $Hash{$CodeAgenceCli},"\n");
    }
     
      close FicSort;
      $sth->finish;
      $dbh->disconnect;
     
      while (<Cli_Csv> ) {
        next if ($. == 1);
        if ($Client_Csv->parse($_)) {
      	  my @ColCliMailing = $Client_Csv->fields();
      	  $CodeAgenceCli = $ColCliMailing[2]; #Recupere le Code_Agence de la Ligne Courante
    	  $count++;
    	  my @colAgence = split(/;/,$Hash{$CodeAgenceCli});
    	  my $NumTel_Prem = substr($colAgence[10],-10,2);
    	  my $NumTel_Sec = substr($colAgence[10],-8,2);
    	  my $NumTel_Ter = substr($colAgence[10],-6,2);
    	  my $NumTel_Tet = substr($colAgence[10],-4,2);
    	  my $NumTel_Quint = substr($colAgence[10],-2,2);
    	  my $NumTelFormate = join (".",$NumTel_Prem,$NumTel_Sec,$NumTel_Ter,$NumTel_Tet,$NumTel_Quint) ;
          my $NumTelFormateFull = join (" ","TEL. :",$NumTelFormate);
     
          #print (FicRes CodeBanque;CodeSG3N;CodePostal;FR/ETR;Code Guichet;Numéro de compte;Annexe1;Annexe2;Annexe3;Annexe4;Id adresse (gestion PND);DestLignAdr1;DestLignAdr2;DestLignAdr3;DestLignAdr4;DestLignAdr5;DestLignAdr6;Nom_Agence;Cplt_Intitule_Adresse;Rue;Lieu_Dit;Code_Postal Ville;Num_Tel_Signataire;Var1;Var2;Var3;Var4;Var5;Var6;Var7;Var8;Var9;Var10;)
          print (FicRes "30003",";",";",$ColCliMailing[19],";","FR",";",$ColCliMailing[2],";",sprintf("%016u",$count),";"," ",";"," ",";"," ",";"," ",";","                   ",";",$ColCliMailing[14],";",$ColCliMailing[15],";",$ColCliMailing[16],";",$ColCliMailing[17],";",$ColCliMailing[18],";",$ColCliMailing[19]," ",$ColCliMailing[20],";",$colAgence[3],";",$colAgence[5],";",$colAgence[6],";",$colAgence[7],";",$colAgence[8]," ",$colAgence[9],";",$NumTelFormateFull,";",$colAgence[1],";",$ColCliMailing[7],";",$ColCliMailing[8],";",";",";",";",";",";",";","\n");
     
        }
      }
    Lorsque je fais un "print" du "CodeAgenceCli " dans le 2nd While, le récupère bien les code agence du fichier client. Mais si je fais un print du "$Hash{$CodeAgenceCli}, ça ne me retourne rien.

    Est-ce que les tables sont hachage sont contextualisées ? Pb de string dans l'un et de numérique dans l'autre ? Je ne comprends pas pourquoi le second appel ne renvoie rien ...

    Les fichiers utilisés sont les mêmes que dans le premier message.

    Si quelqu'un voulait bien éclairer ma lanterne, ce serait sympa.

    Merci par avance de votre aide.

  5. #5
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    dans ta boucle de lecture des codes agence, essaie de remplacer:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    %Hash = ($CodeAgenceCli => $LineSorted);
    par:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    %Hash{$CodeAgenceCli} = $LineSorted;

  6. #6
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2012
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2012
    Messages : 18
    Par défaut
    Bonjour,

    merci de ta réponse.

    Je viens de tester et je script plante avec ce message

    Can't modify key/value hash slice in list assignment at (..)\Test_Hash.pl line 79, near "$LineSorted;"
    La ligne 79 étant celle qui contient
    %Hash{$CodeAgenceCli} = $LineSorted;
    Je continue de chercher de mon coté mais toutes les idées sont les bienvenues

Discussions similaires

  1. [MySQL] Problème avec while(mysql_fetch_assoc()) imbriqués
    Par Sylvaindd dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 30/03/2013, 19h44
  2. [MySQL] Problème while imbriqués
    Par MrSoul dans le forum PHP & Base de données
    Réponses: 11
    Dernier message: 18/10/2012, 03h17
  3. [HTML]problème de tableaux imbriqués
    Par tyrann dans le forum Balisage (X)HTML et validation W3C
    Réponses: 8
    Dernier message: 24/03/2006, 15h29
  4. Problèmes de if imbriqués
    Par hawaks dans le forum Langage
    Réponses: 6
    Dernier message: 16/12/2005, 13h17
  5. [Tableaux] problème avec while
    Par zimotep dans le forum Langage
    Réponses: 3
    Dernier message: 11/09/2005, 10h30

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