Et tu as essayé le code que je t'ai proposé?
Normalement, il devrait faire ce que tu veux (à part l'en-tête, mais ça on peut l'ajouter après si le reste fonctionne comme tu le désires.
Version imprimable
Et tu as essayé le code que je t'ai proposé?
Normalement, il devrait faire ce que tu veux (à part l'en-tête, mais ça on peut l'ajouter après si le reste fonctionne comme tu le désires.
Salut
J'ai essayé oui et j'ai ceci comme erreur :
Que je ne comprends pas, il est déjà utilisé plus haut, pourquoi faut-il le déclarer de nouveau ?Code:
1
2
3 Global symbol "%header_value" requires explicit package name (did you forget to declare "my %header_value"?) at Script_SVC_Test_Excel_OK.pl line 201. Global symbol "%header_value" requires explicit package name (did you forget to declare "my %header_value"?) at Script_SVC_Test_Excel_OK.pl line 204. Execution of Script_SVC_Test_Excel_OK.pl aborted due to compilation errors.
L'en-tête ça je sais comment faire, ici c'est surtout récupérer exactement les données que je souhaite et les placer où je souhaite dans l'Excel
Bonjour,
poste le code exact qui te donne cette erreur. Il doit y avoir un petit problème de portée de variable, certainement rien de méchant.
C'est la partie de code que tu m'as donnés :)
Je te joint le script (avec un exemple de fichier de données) en prévision, sait-on jamais :)Code:
1
2
3
4
5
6
7
8
9 my $row = 0; # démarre avec une autre valeur si tu ne veux pas commencer sur la première ligne for my $key (keys %header_value) { my $col = 0; # idem, initialise $col à une autre valeur si tu veux les valeurs sur des colonnes plus à droite for my $label (qw / item name capacity free_capacity / ) { $worksheet->write("X11", $row, $col, $header_value{$key}{$label} ); $col++; } $row++; }
Oui, c'est bien un problème de portée des variables. Le hachage %header_value n'est pas connu là où tu l'utilises.
Déplace cette déclaration:
en-dehors de la fonction fill_hash, ou plus précisément avant. Par exemple juste après la ligne:Code:
1
2 my %header_value;
Comme ça, le hachage sera connu dans tout le programme.Code:
1
2 use feature 'say';
Salut,
Les données ont bien l'air de s'insérer dans le fichier Excel.
Sauf que évidemment, j'ai déjà un ensemble de données dans mon Excel, du coup ça écrase une partie.
J'ai donc essayé ceci :
En pensant que ça commencerait donc à la cellule K1, mais je n'ai qu'un "5" qui apparait ...Code:$worksheet->write("K1",$row, $col, $header_value{$key}{$label} );
As-tu une idée ?
Bonjour,
Je l'avais pourtant dit explicitement dans le commentaire (ligne 9 du code de mon post # 39 du 05/06/2018 à 11h19).
Si tu veux commencer à la colonne 'K', initialise la valeur de $col à 10 (par exemple) dans la boucle du bout de code que je t'ai suggéré:
Code:
1
2
3
4
5
6
7
8
9
10
11 # ... for my $key (keys %header_value) { my $col = 10; # idem, initialise $col à une autre valeur si tu veux les valeurs sur des colonnes plus à droite for my $label (qw / item name capacity free_capacity / ) { $worksheet->write( $row, $col, $header_value{$key}{$label} ); $col++; } $row++; } # ...
Salut,
Merci de ton retour.
Je l'ai fais mais je n'obtiens pas toutes les données ... Je n'en obtiens que 6 alors que je dosi en avoir beaucoup plus. As-tu une idée ?
NBB4_DMZ_STW44 75.27TB 58.87TB
NBB4_CORP_NRLSAS_STW43 25.46TB 18.36TB
NBB4_CORP_NRLSAS_STW42 36.33TB 31.15TB
MigrationPool_8192 0 0
NBB4_DMZ_DS8K8 59.93TB 29.26TB
NBB4_CORP_STW43 193.92TB 71.96TB
Si ça fonctionne pour six lignes ou rangées, c'est que la logique et la syntaxe sont probablement bonnes pour l'insertion dans la feuille Excel.
Donc, s'il te manque des données, je pencherais pour des données non conformes à l'attendu. Peux-tu donner l'affichage de %header_value avec Data::Dumper?
Hello
Voici le résultat deCode:print Dumper \%header_value;
Merci d'avance!Code:
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128 $VAR1 = { '1' => { 'name' => 'MigrationPool_8192', 'free_capacity' => '0', 'capacity' => '0' }, '6' => { 'free_capacity' => '79.08TB', 'name' => 'NBB2_CORP_STW23', 'capacity' => '193.92TB' }, '4' => { 'name' => 'NBB2_CORP_NRLSAS_STW22', 'free_capacity' => '31.15TB', 'capacity' => '36.33TB' }, '5' => { 'capacity' => '25.46TB', 'name' => 'NBB2_CORP_NRLSAS_STW23', 'free_capacity' => '18.36TB' }, '0' => { 'capacity' => '124.98TB', 'free_capacity' => '4.61TB', 'name' => 'NBB2_CORP_DS8K8' }, '2' => { 'capacity' => '87.77TB', 'name' => 'NBB2_CORP_STW22', 'free_capacity' => '22.00TB' } }; $VAR1 = { '1' => { 'capacity' => '0', 'free_capacity' => '0', 'name' => 'MigrationPool_8192' }, '6' => { 'capacity' => '193.92TB', 'name' => 'NBB4_CORP_STW43', 'free_capacity' => '71.96TB' }, '4' => { 'capacity' => '36.33TB', 'free_capacity' => '31.15TB', 'name' => 'NBB4_CORP_NRLSAS_STW42' }, '5' => { 'capacity' => '25.46TB', 'name' => 'NBB4_CORP_NRLSAS_STW43', 'free_capacity' => '18.36TB' }, '0' => { 'free_capacity' => '592.00GB', 'name' => 'NBB4_CORP_DS8K8', 'capacity' => '124.98TB' }, '2' => { 'free_capacity' => '23.31TB', 'name' => 'NBB4_CORP_STW42', 'capacity' => '87.77TB' } }; $VAR1 = { '1' => { 'free_capacity' => '0', 'name' => 'MigrationPool_8192', 'capacity' => '0' }, '6' => { 'capacity' => '193.92TB', 'name' => 'NBB4_CORP_STW43', 'free_capacity' => '71.96TB' }, '4' => { 'capacity' => '36.33TB', 'free_capacity' => '31.15TB', 'name' => 'NBB4_CORP_NRLSAS_STW42' }, '5' => { 'capacity' => '25.46TB', 'name' => 'NBB4_CORP_NRLSAS_STW43', 'free_capacity' => '18.36TB' }, '0' => { 'free_capacity' => '28.63TB', 'name' => 'NBB2_DMZ_DS8K8', 'capacity' => '59.93TB' }, '2' => { 'capacity' => '75.27TB', 'name' => 'NBB2_DMZ_STW24', 'free_capacity' => '59.51TB' } }; $VAR1 = { '1' => { 'capacity' => '0', 'name' => 'MigrationPool_8192', 'free_capacity' => '0' }, '6' => { 'capacity' => '193.92TB', 'name' => 'NBB4_CORP_STW43', 'free_capacity' => '71.96TB' }, '4' => { 'capacity' => '36.33TB', 'free_capacity' => '31.15TB', 'name' => 'NBB4_CORP_NRLSAS_STW42' }, '5' => { 'capacity' => '25.46TB', 'name' => 'NBB4_CORP_NRLSAS_STW43', 'free_capacity' => '18.36TB' }, '0' => { 'name' => 'NBB4_DMZ_DS8K8', 'free_capacity' => '29.26TB', 'capacity' => '59.93TB' }, '2' => { 'capacity' => '75.27TB', 'free_capacity' => '58.87TB', 'name' => 'NBB4_DMZ_STW44' } };
Ah zut, je voulais repasser hier soir pour regarder plus en détail, et j'ai oublié.
Je ne comprends pas pourquoi ton hachage est segmenté en quatre parties (quatre fois $VAR1). Manifestement, tu ne récupères dans la feuille Excel que l'une de ces quatre sections. Mais je n'ai pas vu dans ton code où se fait cette segmentation, ni à quoi elle est censée correspondre.
Pourrais-tu poster le code actuel dans lequel ce hachage est alimenté?
Salut Lolo,
Pas de soucis ! Si j'arrive à finaliser cette dernière chose avant jeudi soir c'est parfait, car après je pars en vacances pour 2 semaines !
Il ne donne pas 4 VAR car j'ai 4 fichiers traités ?
Voici le bout du code :
Dans le doute je te remet le script complet.Code:
1
2
3
4
5
6
7
8 while (my $line = <$FH>) { # première boucle pour lire le premier groupe de lignes last if $line =~ /^id:name:IO_group_id:/; # sort de cette boucle et passe à la suivante pour la suite des données next if $line =~/id:name:status:mdisk_count:/; # saute la ligne d'entête next if $line =~ /^\s*$/; # saute d'éventuelles lignes vides my ($id, $name, $capacity, $free) = (split /:/, $line)[0, 1, 5, 7]; next unless defined $free; $header_value{$id} = { name => $name, capacity => $capacity, free_capacity => $free}; # stockage des valeurs qui t'intéressent dans un hash }
Merci d'avance !
Donc, si je comprends bien, le dump que tu as posté représente le contenu du hash à quatre moment différents dans ton programme?
Et, toujours si je comprends bien, à chaque fois que tu lis un des quatre fichiers, tu écrases les données provenant de l'ancien fichier avec celle du nouveau fichier (car les clefs du hash sont les mêmes, des chiffres de 1 à 6). Du coup, à la fin, tu n'as plus que les valeurs du dernier fichier.
Si c'est cela, soit il faut ajouter un niveau supplémentaire au hachage (un par fichier), soit il faut alimenter le fichier Excel au fur et à mesure que tu lis un fichier.
C'est le résultat du Dumper comme tu me l'as demandé.
Je dois avouer que je n'ai pas trop idée de comment faire ceci.
Le plus simple serai de faire un hachage de hachage non?
A quoi cela ressemblerai-t'il dans mon script ?
Je n'aurai pas pensé que ça se passerai comme cela, je pensais, que, comme la première façon dont je traite certaines données, ça garde tout et que je puis ensuite les insérer ...
Je suis embêté, j'aurai voulu terminer ce dernier morceau avant de partir en vacances (demain après-midi) mais je pense pas que j'aurai le temps de chercher + tester en boucle :( Mais bon, on verra demain matin si j'arrive à trouver comment faire;
Bonjour,
pour éviter que les données d'un fichier n'écrasent celles d'un autre fichier, on peut ajouter un niveau supplémentaire au hachage:
Et ajuster en conséquence la lecture du hachage avec quelque chose comme cela (je n'ai pas testé, car je n'ai pas de données en entrée, et le risque d'une erreur est non négligeable):Code:
1
2
3
4
5
6
7
8
9 while (my $line = <$FH>) { # première boucle pour lire le premier groupe de lignes last if $line =~ /^id:name:IO_group_id:/; # sort de cette boucle et passe à la suivante pour la suite des données next if $line =~/id:name:status:mdisk_count:/; # saute la ligne d'entête next if $line =~ /^\s*$/; # saute d'éventuelles lignes vides my ($id, $name, $capacity, $free) = (split /:/, $line)[0, 1, 5, 7]; next unless defined $free; $header_value{"$FH"}{$id} = { name => $name, capacity => $capacity, free_capacity => $free}; # stockage des valeurs qui t'intéressent dans un hash }
Mais il serait sans doute plus simple de changer la structure de données d'un hachage de hachages vers un tableau de hachages (pour "empiler" les données au lieu de les écraser) en changeant l'initialisation au début:Code:
1
2
3
4
5
6
7
8
9
10
11
12 my $row = 1; for my $hash_ref (values %header_value) { for my $key (keys %$hash_ref) { my $col = 9; # idem, initialise $col à une autre valeur si tu veux les valeurs sur des colonnes plus à droite for my $label (qw / item name capacity free_capacity / ) { $worksheet->write($row, $col, $hash_ref->{$key}{$label} ); $col++; } $row++; } }
et en modifiant comme suit la boucle d'alimentation de cette structure de données:Code:
1
2 my @header_value;
Ensuite, modifie la boucle d'alimentation de la feuille Excel comme suit (pas testé non plus, pour la même raison):Code:
1
2
3
4
5
6
7
8 while (my $line = <$FH>) { # première boucle pour lire le premier groupe de lignes last if $line =~ /^id:name:IO_group_id:/; # sort de cette boucle et passe à la suivante pour la suite des données next if $line =~/id:name:status:mdisk_count:/; # saute la ligne d'entête next if $line =~ /^\s*$/; # saute d'éventuelles lignes vides my ($id, $name, $capacity, $free) = (split /:/, $line)[0, 1, 5, 7]; next unless defined $free; push @header_value, { name => $name, capacity => $capacity, free_capacity => $free}; # stockage des valeurs qui t'intéressent dans un tableau de hachages }
Note que ton code serait nettement plus lisible si tu indentais correctement: l'ensemble du code de la fonction fill_hash devrait être décalé d'une tabulation vers la droite.Code:
1
2
3
4
5
6
7
8
9
10 my $row = 1; # démarre avec une autre valeur si tu ne veux pas commencer sur la première ligne for my $line (@header_value) { my $col = 9; # idem, initialise $col à une autre valeur si tu veux les valeurs sur des colonnes plus à droite for my $label (qw / item name capacity free_capacity / ) { $worksheet->write($row, $col, $line->{$key}{$label} ); $col++; } $row++; }
Hello
Merci énormement pour ton retour !
J'ai décidé d'utiliser la deuxième option et j'ai cette erreur :
Il suffit de déclarer "my $key" ?Code:
1
2
3
4
5
6
7
8
9 my $row = 1; # démarre avec une autre valeur si tu ne veux pas commencer sur la première ligne for my $line (@header_value) { my $col = 9; # idem, initialise $col à une autre valeur si tu veux les valeurs sur des colonnes plus à droite for my $label (qw / item name capacity free_capacity / ) { $worksheet->write($row, $col, $line->{$key}{$label} ); $col++; } $row++; }
EDIT : J'ai essayé et cela ne fonctionne pas ... En la déclarant bêtement j'ai ceci en boucle comme erreur :
Use of uninitialized value $key in hash element at Script_SVC_Test_Excel_After New Hash.pl line 209.
Et évidemment, aucune info dans l'Excel
Edit :
J'ai utilisé la première option et la par contre, ça fonctionne sans soucis !
Oups, j'ai oublié de nettoyer cette partie de la ligne de code. En fait, il n'y a simplement plus lieu d'utiliser $key.
Ce devrait être:
Il me semble qu'il faut aussi supprimer item de la liste des valeurs attribuées à $label, car cela, si je n'ai pas loupé quelque chose, ne correspond plus à rien dans ta structure de données:Code:
1
2
3
4
5
6
7
8
9
10 my $row = 1; # démarre avec une autre valeur si tu ne veux pas commencer sur la première ligne for my $line (@header_value) { my $col = 9; # idem, initialise $col à une autre valeur si tu veux les valeurs sur des colonnes plus à droite for my $label (qw / item name capacity free_capacity / ) { $worksheet->write($row, $col, $line->{$label} ); $col++; } $row++; }
Code:
1
2 for my $label (qw / name capacity free_capacity / ) {
Hello !
Merci beaucoup je vais tester !
Néanmoins avec la première manière ça fonctionne très bien, un grand merci !
Ne sait-on, penses-tu que ça soit possible de trier l'insertion des données par ordre alphabétique ? J'ai essayé avec l'option "sort" mais sans succès.
Ce n'est pas important, un petit détail :)
Encore merci pour toute ton aide!
Bonsoir,
oui, bien sûr, on peut trier les données.
C'est un peu plus facile à faire avec la seconde solution (tableau de hachages) parce qu'un tableau garde l'ordre que tu lui donnes (autrement dit, tu crées un ordre permanent quand tu tries un tableau), alors qu'avec un hachage de hachages, c'est un peu plus compliqué parce qu'un hachage est par définition une collection non ordonnée, mais cela ne veut pas dire que l'on ne puisse pas les trier au moment par exemple de les insérer dans la feuille Excel.
Tu veux trier sur quel champ? J'imagine, puisque tu parles d'ordre alphabétique, que tu veux tries sur le champ name. Est-ce correct?
Avec la seconde solution (tableau de hachages), il devrait suffire d'ajouter une instruction de tri du tableau avant de l'exploiter pour alimenter la feuille de calcul:
et ensuite d'utiliser @sorted_header_value pour alimenter la feuille Excel.Code:
1
2 my @sorted_header_value = sort { $a->{name} cmp $b->{name} } @header_value;
Tu trouveras des explications assez détaillées sur la fonction sort dans les chapitres consacrés au tri de ce tutoriel: https://laurent-rosenfeld.developpez...s-listes/#L2-2 et https://laurent-rosenfeld.developpez...urs-listes/#L3.