Précédent   Forum du club des développeurs et IT Pro > Autres langages > Perl > Langage
Langage Toutes vos questions sur les scripts Perl en général. Avant de poster, veuillez consulter les FAQs perl, les cours Perl, les critiques de livres et les sources Perl.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 20/11/2012, 16h50   #1
chalu133
Invité de passage
 
Homme Francois
Inscription : janvier 2012
Messages : 15
Détails du profil
Informations personnelles :
Nom : Homme Francois
Localisation : France

Informations professionnelles :
Secteur : High Tech - Électronique et micro-électronique

Informations forums :
Inscription : janvier 2012
Messages : 15
Points : 1
Points : 1
Par défaut Recupérer un champ date Excel avec perl.

bonjour,
J'utilise Spreadsheet:arseExcel pour lire un fichier Excel et récupérer certains champs.

Lorsque je lit un champ date, au lieu de récupérer la valeur au format date, je récupère un numérique.

Apparemment d'apres le CPAN il me faudrait le module DateTime::format::Excel

Connaissez-vous une astuce/méthode pour faire la conversion sans avoir à installer ce module (DateTime::format::Excel) sur mon système, car ce module à enormément de dépendances ...et je ne peux pas les installer sans l'accord des Admin Linux ...
Merci.
chalu133 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/11/2012, 19h07   #2
Lolo78
Membre Expert
 
Homme Laurent R.
Conseil - Consultant en systèmes d'information
Inscription : mai 2012
Messages : 569
Détails du profil
Informations personnelles :
Nom : Homme Laurent R.
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 : 569
Points : 1 119
Points : 1 119
Peux-être regarder ce que fait ce module pour pomper le code...

Pas fan de ce genre de solution a priori, mais, bon, parfois...
__________________
Sauf mention contraire explicite, les bouts de code que je poste en réponse à une question n'ont pas forcément été testés.
Lolo78 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2012, 09h31   #3
chalu133
Invité de passage
 
Homme Francois
Inscription : janvier 2012
Messages : 15
Détails du profil
Informations personnelles :
Nom : Homme Francois
Localisation : France

Informations professionnelles :
Secteur : High Tech - Électronique et micro-électronique

Informations forums :
Inscription : janvier 2012
Messages : 15
Points : 1
Points : 1
J'ai une idée mais je ne sais pas comment la coder :
Pour Excel, le numérique 1 correspond au 01 Janvier 1900 .
Le numérique 41250, correspond au 7 /12/2012 ( 01/01/1900 + 41239 jours)

Est-il possible en perl à partir du numérique correspondant au nombres de jours depuis le 01/01/1900 (Ex: 41250) de recalculer la date
01/01/1900 + (41250-1) = 07/12/2012 ?

Merci pour votre aide
chalu133 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2012, 09h41   #4
djibril
Responsable Perl et Outils

 
Avatar de djibril
 
Homme
Inscription : avril 2004
Messages : 13 528
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 33
Localisation : France

Informations forums :
Inscription : avril 2004
Messages : 13 528
Points : 31 709
Points : 31 709
Bonjour,

J'ai créé un fichier xls avec une seule cellule avec à l'intérieur la date 21/11/2012.

Avec le code suivant :
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
#!/usr/bin/perl
use warnings;
use strict;
use Spreadsheet::ParseExcel;
 
my $parser   = Spreadsheet::ParseExcel->new();
my $workbook = $parser->parse('date.xls');
 
if ( !defined $workbook ) {
  die $parser->error(), ".\n";
}
 
for my $worksheet ( $workbook->worksheets() ) {
 
  my ( $row_min, $row_max ) = $worksheet->row_range();
  my ( $col_min, $col_max ) = $worksheet->col_range();
 
  for my $row ( $row_min .. $row_max ) {
    for my $col ( $col_min .. $col_max ) {
 
      my $cell = $worksheet->get_cell( $row, $col );
      next unless $cell;
 
      print "Row, Col    = ($row, $col)\n";
      print "Value       = ", $cell->value(),       "\n";
      print "Unformatted = ", $cell->unformatted(), "\n";
      print "\n";
    }
  }
}
J'obtiens :
Citation:
Row, Col = (0, 0)
Value = 2012-11-21
Unformatted = 41234
Qu'elle est donc votre problème ? Si vous nous montrez pas votre code, difficile de deviner ce qui ne va pas.
__________________
Pas de questions technique par messagerie privée (lisez les règles du forum Perl) et pour les nouveaux !
djibril est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2012, 09h45   #5
Philou67430
Expert Confirmé
 
Inscription : avril 2009
Messages : 2 636
Détails du profil
Informations personnelles :
Âge : 47

Informations forums :
Inscription : avril 2009
Messages : 2 636
Points : 3 083
Points : 3 083
La date numérique retournée peut peut-être être utilisée (moyennant éventuellement une conversion numérique simple) vers une valeur numérique utilisable par localtime et strftime (module POSIX dans le Core de perl depuis la version 5).
La fonction localtime a pour date de base Epoch (0 seconde est équivalent au 1er janvier 1970).
Reste à connaitre la base pour la date Excel. Si j'en crois cet article, la date de référence serait le 1er janvier 1900, et la valeur vaudrait alors 1 (en jour).

Reste à calculer le nombre de secondes entre ces deux dates de référence. On constate que ce calcul, en valeur entière, dépasse la capacité des entiers, et n'est pas possible :
Code :
perl -MPOSIX=mktime -E 'print mktime(0,0,0,1, 0, 70) - mktime(0,0,0,1,0,0)'
On peut donc calcul le nombre de jour avec ce module Date::Calc :
Code :
1
2
$ perl -MDate::Calc=Delta_Days -E 'say Delta_Days(1900, 1, 1, 1970, 1, 1);'
25567
On peut donc convertir une date Excel en date compatible localtime ainsi :

Code :
$date_localtime = ($date_excel - 25567) * 86400
En utilisant locatime et POSIX::strftime, tu pourras reconstituer une date du style "10/01/2012" :

Code :
1
2
use POSIX qw(strftime);
print strftime("%D", localtime($date_localtime));
__________________
Plus j'apprends, et plus je mesure mon ignorance (philou67430)
Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
Using strict and warnings is good for you.
Philou67430 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2012, 11h23   #6
chalu133
Invité de passage
 
Homme Francois
Inscription : janvier 2012
Messages : 15
Détails du profil
Informations personnelles :
Nom : Homme Francois
Localisation : France

Informations professionnelles :
Secteur : High Tech - Électronique et micro-électronique

Informations forums :
Inscription : janvier 2012
Messages : 15
Points : 1
Points : 1
bonjour Djibril,

J'ai testé votre script.
La façon dont vous lisez le fichier Excel ne fonctionne pas sur mon systeme !
"Can't locate object methode parse via package Spreadsheet:arseExcel"
Peut être un problème de version ? .

voici un extraction de mon code avec la methode utilisée pour lire l'Excel.
Je recherche une cellule contenant "Delivery" et je récupère la date 2 row en dessous
---------------------------------------------------------------------
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
#!/sftw/perl/5.8.6/bin/perl -I /sftw/perl/pmp-r5.8.6.3.0/lib/ -w
#
# 
 
use strict;
use Spreadsheet::ParseExcel;
#
# Array
my @DeliveryDate;
 
# Scalar
 
 
 
#
####
# Declaration variable for XLS file
#
#
die "You must provide a filename to $0 to be parsed as an Excel file" unless @ARGV;
#
# Read Excel
#
my $ParserExcel = Spreadsheet::ParseExcel->new();
my $workbook=$ParserExcel->Parse("$ARGV[0]");
 
#
#
#
# 
 
 
 
my $madate;
foreach my $worksheet (@{$workbook->{Worksheet}} ) {
#	print "$worksheet->{Name}\n";
	if ($worksheet->{Name} eq "Product") {
		for my $row (0 ..70) {
			for my $tmpcol (0 .. 30) {
				if (defined  $worksheet->{Cells}[$row][$tmpcol]->{Val}) {
					if ($worksheet->{Cells}[$row][$tmpcol]->{Val} =~/.*Delivery.*/) {
						my $DeliveryDate_col_Id=$tmpcol;
						$madate=$worksheet->{Cells}[$row+2][$DeliveryDate_col_Id]->{Val};
					}
	    			}
			}
		}
	}
}
print "Ma date ".$madate."\n";
---------------------------------------------------------------------
Le print Ma date ".$madate."\n"; renvoie un numérique et pas une date.
chalu133 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2012, 12h26   #7
chalu133
Invité de passage
 
Homme Francois
Inscription : janvier 2012
Messages : 15
Détails du profil
Informations personnelles :
Nom : Homme Francois
Localisation : France

Informations professionnelles :
Secteur : High Tech - Électronique et micro-électronique

Informations forums :
Inscription : janvier 2012
Messages : 15
Points : 1
Points : 1
bonjour Philou67430,
Le problème avec ta méthode est que je n'ai pas le module Date::Calc installé sur mon système.
chalu133 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2012, 14h01   #8
Philou67430
Expert Confirmé
 
Inscription : avril 2009
Messages : 2 636
Détails du profil
Informations personnelles :
Âge : 47

Informations forums :
Inscription : avril 2009
Messages : 2 636
Points : 3 083
Points : 3 083
Tu n'as pas besoin du module Date::Calc, puisque je t'ai donné le résultat de la différence entre Epoch et l'origine des temps Microsoft. Tu n'as qu'à utiliser cette valeur comme constante pré-calculée (en le documentant dans le source).
__________________
Plus j'apprends, et plus je mesure mon ignorance (philou67430)
Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
Using strict and warnings is good for you.
Philou67430 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2012, 15h38   #9
chalu133
Invité de passage
 
Homme Francois
Inscription : janvier 2012
Messages : 15
Détails du profil
Informations personnelles :
Nom : Homme Francois
Localisation : France

Informations professionnelles :
Secteur : High Tech - Électronique et micro-électronique

Informations forums :
Inscription : janvier 2012
Messages : 15
Points : 1
Points : 1
Et oui suis-je bête ..... !
Je reconverti bien le numerique en format date mais en utilisant comme constant 25569 (le jour 0 pour Excel est le 31/12/1899 en fait)
Merci pour ton aide précieuse
chalu133 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 13h41.


 
 
 
 
Partenaires

Hébergement Web