Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Spreadsheet::WriteExcel et le séparateur décimal virgule

5 réponses
Avatar
metoo
Bonjour,

Voila, je créé un script qui, en autres, importe des données CSV pour
remplir une page excel avec Spreadsheet::WriteExcel

Ca fonctionne sans problème (très vite et très bien) sauf pour
importer des nombres décimaux :-O

write() ou write_string() importe très bien les données texte, ou les
nombres décimaux ou non, mais Excel les considère ensuite comme du
texte. (logique)

write_number() importe bien les nombres comme tels,
mais s'il sont décimaux:
Argument "123,45" isn't numeric in pack [...]
Normal, car pour lui, le séparateur numérique devrait être un point
(il importe quand même la partie entière)

Je peux bien sur faire un 'tr' pour transformer le '.' en ',' avant
import, mais là c'est excel qui ne considère plus cela comme un nombre
:-(

J'ai lu la page officielle
http://search.cpan.org/~jmcnamara/Spreadsheet-WriteExcel-2.16/lib/Spreadsheet/WriteExcel.pm
j'ai "googleulisé" sans trouver. Mais j'ai du passer à côté d'une
solution évidente car je pense qu'il doit quand même y avoir du monde
à utiliser le pilotage COM d'Excel via Perl (ou alors avec un autre
module?)

Ma config:
This is perl, v5.10.0 built for MSWin32-x86-multi-thread

5 réponses

Avatar
Paul Gaborit
À (at) Fri, 19 Dec 2008 09:23:09 +0100,
metoo écrivait (wrote):
Voila, je créé un script qui, en autres, importe des données CSV pour
remplir une page excel avec Spreadsheet::WriteExcel



On importe donc depuis CSV vers Perl et on *exporte* depuis Perl vers
Excel.

Ca fonctionne sans problème (très vite et très bien) sauf pour
importer des nombres décimaux :-O

write() ou write_string() importe très bien les données texte, ou les
nombres décimaux ou non, mais Excel les considère ensuite comme du
texte. (logique)

write_number() importe bien les nombres comme tels,
mais s'il sont décimaux:
Argument "123,45" isn't numeric in pack [...]
Normal, car pour lui, le séparateur numérique devrait être un point
(il importe quand même la partie entière)



Lorsqu'on appelle 'write_number', il faut bien évidement lui passer
comme argument un nombre (décimal ou entier). Si le fichier CSV
contient des nombres ayant la virgule comme séparateur décimal, il
faut la remplacer par un point pour que Perl puisse assurer
correctement la conversion chaîne vers nombre.

Je peux bien sur faire un 'tr' pour transformer le '.' en ',' avant
import, mais là c'est excel qui ne considère plus cela comme un nombre
:-(



Je ne comprends pas du tout cette phrase. "Importer", ça va dans quel
sens pour vous ? Pourquoi transformer le '.' en ',' alors que le
problème est dans l'autre sens ?

'write_number' fonctionne très bien. Êtes-vous sûr de vos tests ?

J'ai lu la page officielle
http://search.cpan.org/~jmcnamara/Spreadsheet-WriteExcel-2.16/lib/Spreadsheet/WriteExcel.pm
j'ai "googleulisé" sans trouver. Mais j'ai du passer à côté d'une
solution évidente car je pense qu'il doit quand même y avoir du monde
à utiliser le pilotage COM d'Excel via Perl (ou alors avec un autre
module?)



Attention : Spreadsheet::WriteExcel *n'utilise* *pas* la couche
DCOM/COM/OLE de Windows. C'est d'ailleurs l'un de ses intérêts : on
peut l'utiliser sur n'importe quelle plateforme. Et ça marche très
bien (pour les besoins que vous exprimez ici).

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>
Avatar
metoo
Fri, 19 Dec 2008 12:09:00 +0100, Paul Gaborit
>>


À (at) Fri, 19 Dec 2008 09:23:09 +0100,
metoo écrivait (wrote):
Voila, je créé un script qui, en autres, importe des données CSV pour
remplir une page excel avec Spreadsheet::WriteExcel





Je ne comprends pas du tout cette phrase. "Importer", ça va dans quel
sens pour vous ? Pourquoi transformer le '.' en ',' alors que le
problème est dans l'autre sens ?



(Je choisi mal mes termes, désolé)

'write_number' fonctionne très bien. Êtes-vous sûr de vos tests ?



Je viens de refaire un essai minimaliste
-------------------------------------------------------
use Spreadsheet::WriteExcel;
my $workbook = Spreadsheet::WriteExcel->new("test.xls");
$worksheet = $workbook->add_worksheet();

my $Champ1 = 'aaa';
my $Champ2 = '123,45';

$worksheet->write_string(0, 0, $Champ1);
$worksheet->write_number(0, 1, $Champ2);

$workbook->close();

system ('test.xls');
-------------------------------------------------------
J'obtiens en A1: aaa et en B1: 123
(et non pas en B1: 123,45)

Maintenant, si pour le deuxième je met
$worksheet->write(0, 1, $Champ2);
ou
$worksheet->write_string(0, 1, $Champ2);

J'ai bien 123,45 mais c'est considéré par excel comme du texte
(pareil à l'affichage mais pas pareil pour ensuite faire des formules)

J'ai peut-être oublié un truc évident ?
Avatar
Paul Gaborit
À (at) Fri, 19 Dec 2008 14:40:08 +0100,
metoo écrivait (wrote):
Fri, 19 Dec 2008 12:09:00 +0100, Paul Gaborit
>>
'write_number' fonctionne très bien. Êtes-vous sûr de vos tests ?



Je viens de refaire un essai minimaliste
-------------------------------------------------------
use Spreadsheet::WriteExcel;
my $workbook = Spreadsheet::WriteExcel->new("test.xls");
$worksheet = $workbook->add_worksheet();

my $Champ1 = 'aaa';
my $Champ2 = '123,45';

$worksheet->write_string(0, 0, $Champ1);
$worksheet->write_number(0, 1, $Champ2);

$workbook->close();

system ('test.xls');
-------------------------------------------------------
J'obtiens en A1: aaa et en B1: 123
(et non pas en B1: 123,45)



Mais aussi un 'warning' de perl car "123,45" n'est pas un nombre !

Remplacez la ligne :

my $Champ2 = '123,45';

Par :

my $Champ2 = '123.45';

Ou par :

my $Champ2 = '123,45';
$Champ2 = s/,/./;

Et tout fonctionnera très bien.

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>
Avatar
metoo
Fri, 19 Dec 2008 14:47:57 +0100, Paul Gaborit
>>


À (at) Fri, 19 Dec 2008 14:40:08 +0100,
metoo écrivait (wrote):
Fri, 19 Dec 2008 12:09:00 +0100, Paul Gaborit
>>
'write_number' fonctionne très bien. Êtes-vous sûr de vos tests ?



Je viens de refaire un essai minimaliste
-------------------------------------------------------
use Spreadsheet::WriteExcel;
my $workbook = Spreadsheet::WriteExcel->new("test.xls");
$worksheet = $workbook->add_worksheet();

my $Champ1 = 'aaa';
my $Champ2 = '123,45';

$worksheet->write_string(0, 0, $Champ1);
$worksheet->write_number(0, 1, $Champ2);

$workbook->close();

system ('test.xls');
-------------------------------------------------------
J'obtiens en A1: aaa et en B1: 123
(et non pas en B1: 123,45)





Mais aussi un 'warning' de perl car "123,45" n'est pas un nombre !

Remplacez la ligne :

my $Champ2 = '123,45';

Par :

my $Champ2 = '123.45';

Ou par :

my $Champ2 = '123,45';
$Champ2 = s/,/./;

Et tout fonctionnera très bien.




Effectivement, cela fonctionne.
J'avais fais ce exemple mini car initialement je récupère mes données
d'un fichier CSV où les décimaux sont exprimés avec une ','
Donc je vais mettre un s/// juste après l'import des lignes CSV et
avant l'envoi vers xl.
(J'avais bêtement pensé que le séparateur décimal devait être le même
dans la variable et dans xl)
Merci ;-)
Avatar
Paul Gaborit
À (at) Fri, 19 Dec 2008 15:11:15 +0100,
metoo écrivait (wrote):
(J'avais bêtement pensé que le séparateur décimal devait être le même
dans la variable et dans xl)



En fait, en interne, Excel stocke les nombres en binaire. Ce n'est que
lors de l'affichage qu'il choisit le format correct 9et donc le
séparateur décimal) soit par défaut en fonction de la langue du
système soit en fonction du format choisi pour la cellule.

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>