Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 9 sur 9
  1. #1
    Invité de passage
    Homme Profil pro Francois
    Inscrit en
    janvier 2012
    Messages
    22
    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 : 22
    Points : 4
    Points
    4

    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.

  2. #2
    Membre Expert

    Homme Profil pro Laurent R.
    Conseil - Consultant en systèmes d'information
    Inscrit en
    mai 2012
    Messages
    1 130
    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 : 1 130
    Points : 2 275
    Points
    2 275

    Par défaut

    Peux-être regarder ce que fait ce module pour pomper le code...

    Pas fan de ce genre de solution a priori, mais, bon, parfois...
    Mes articles sur ce site: La programmation fonctionnelle en Perl - Partie 1: les opérateurs de liste et La programmation fonctionnelle en Perl - Partie 2: les fonctions d'ordre supérieur
    ______

    Sauf mention contraire explicite, les bouts de code que je poste en réponse à une question n'ont pas forcément été testés.

  3. #3
    Invité de passage
    Homme Profil pro Francois
    Inscrit en
    janvier 2012
    Messages
    22
    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 : 22
    Points : 4
    Points
    4

    Par défaut

    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

  4. #4
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    avril 2004
    Messages
    16 449
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : avril 2004
    Messages : 16 449
    Points : 464 913
    Points
    464 913

    Par défaut

    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 :
    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 !

  5. #5
    Expert Confirmé

    Inscrit en
    avril 2009
    Messages
    2 942
    Détails du profil
    Informations personnelles :
    Âge : 48

    Informations forums :
    Inscription : avril 2009
    Messages : 2 942
    Points : 3 366
    Points
    3 366

    Par défaut

    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.

  6. #6
    Invité de passage
    Homme Profil pro Francois
    Inscrit en
    janvier 2012
    Messages
    22
    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 : 22
    Points : 4
    Points
    4

    Par défaut

    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.

  7. #7
    Invité de passage
    Homme Profil pro Francois
    Inscrit en
    janvier 2012
    Messages
    22
    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 : 22
    Points : 4
    Points
    4

    Par défaut

    bonjour Philou67430,
    Le problème avec ta méthode est que je n'ai pas le module Date::Calc installé sur mon système.

  8. #8
    Expert Confirmé

    Inscrit en
    avril 2009
    Messages
    2 942
    Détails du profil
    Informations personnelles :
    Âge : 48

    Informations forums :
    Inscription : avril 2009
    Messages : 2 942
    Points : 3 366
    Points
    3 366

    Par défaut

    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.

  9. #9
    Invité de passage
    Homme Profil pro Francois
    Inscrit en
    janvier 2012
    Messages
    22
    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 : 22
    Points : 4
    Points
    4

    Par défaut

    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

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •