[Résolu][Base] Exporter une requête avec un champ Date vers Calc

Discussions et questions sur tout ce qui concerne la programmation tous langages et tous modules confondus.

Modérateur : Vilains modOOs

Règles du forum
:alerte: Balisage obligatoire dans cette section !
Aidez-nous à vous aider au mieux en balisant correctement votre question : reportez-vous sur les règles de cette section avant de poster !
Avatar de l’utilisateur
arverne73
Membre OOrganisé
Membre OOrganisé
Messages : 82
Inscription : 30 mars 2012 16:13
Localisation : Savoie, France

[Résolu][Base] Exporter une requête avec un champ Date vers Calc

Message par arverne73 »

Bonjour,
Ma configuration : base de données MySQL avec LO Base comme interface utilisateur.
Dans un fil précédent ici, avec votre aide, j'avais pu mettre au point une procédure permettant d'exporter automatiquement une requête dans un fichier Calc créé à cet effet. Cela marche bien.
Mais (et oui, il y a un 'mais'), je me suis rendu compte qu'un des champ, une date, est considéré comme une chaîne dans le fichier Calc créé ce que je ne trouve pas satisfaisant. Quitte à faire une procédure, j'aimerais qu'à la sortie, tout soit correct.
Je reproduis le corps du code :

Code : Tout sélectionner

   laBase = thisDatabaseDocument

   ' le nom de la base
   aNomBase = split(labase.title,".")
   x = uBound(aNomBase)-1
   redim preserve aNomBase( x )
   NomBase = join( aNomBase, "." )

   ' le répertoire de sauvegarde
   aURL = split( laBase.url, "/" )
   x = uBound(aURL)-1
   redim preserve aURL( x )
   URL = join( aURL, "/" )
 
    ' ouvre un nouveau classeur en mode caché
      oURL = "private:factory/scalc"
      oDoc = starDesktop.loadComponentFromURL(oURL, "_blank", 0, Args())
      oFeuille = oDoc.Sheets(0)    ' la première feuille

      ' récupère les données (rowset)
 Ntable = "maRequête" ' nom de la requête

 genereRowSet = createUnoService("com.sun.star.sdb.RowSet")
  with genereRowSet
      .commandType = 1
      .command = Ntable
      .datasourcename = laBase.url
      .filter = ""
      .applyFilter = false
   end with
      q = genereRowset
      q.execute 

   ' s'assurer que tous les enregistrements sont bien chargés
      if not q.IsRowCountFinal then
         q.afterLast
         q.beforeFirst
      end if

   ' récupère les en-têtes de colonne
      qCol = q.columns.elementNames

   ' dimensionne et récupère un dataArray du classeur
      cels = oFeuille.getcellRangebyPosition(0,0,uBound(qCol),q.rowCount)
      da = cels.getDataArray()

   ' injecte les en-têtes
      for i = 0 to uBound(qCol)
          da(0)(i) = qCol(i)
      next i

    ' injecte les données
      for i = 1 to q.rowCount
          q.next
          ligne = da(i)
          for j = 0 to uBound(qCol)
              ligne(j) = q.getString(j+1)
          next j
      next i

      ' insère le dataArray modifié + adapte largeurs de colonnes
      cels.setDataArray(da)
      for i = 0 to uBound(qCol)
    oFeuille.columns.getByIndex(i).optimalWidth = true
      next i

      ' sauvegarde et ferme
Ntable = REPLACE(Ntable, "nomBDDMySQL.","")
    oDoc.storeToUrl(URL & "/" & Ntable & ".ods", array() )

      oDoc.close(true)
Ma compréhension du code :
  • Les données de la requête sont récupérées dans un objet Rowset
  • Une première boucle avec un compteur 'i' passe en revue les lignes d’enregistrements
  • A l'intérieur de la première boucle, une 2e boucle avec un compteur 'j' passe en revue les colonnes, donc finalement, chaque cellule de la ligne
  • Et ceci sera enregistré dans le fichier Calc
Au sein de la 2e boucle, j'ai pu intercepté le champ date et j'ai essayé d'en modifié le contenu en essayant maintes fonctions notamment CDatetoISO puisque j'ai lu que les format de date dans Calc était ISO, mais aussi cDate, Datevalue, Dateserial, cDatetoUNODate : aucun effet.
J'ai aussi introduit 2 lignes de code, avant l'écriture de ces dates, pour transformer le format des cellules qui vont recevoir les dates au format #01/02/2024#, et cela marche ; en cours d'exécution, le format des cellules devient bien le bon :

Code : Tout sélectionner

'formater cellules de date
cel = oFeuille.getcellRangebyPosition(23,1,23,q.rowCount)	
cel.Numberformat = 36
Mais, à la fin, une fois les dates écrites, le format de la cellule est toujours une chaîne dans Calc (format de cellule : @).

Puis-je faire autrement ? Où je fais une erreur ?
Merci
Dernière modification par arverne73 le 05 févr. 2024 14:01, modifié 1 fois.
LibreOffice 24.2.5.2 sur Ubuntu 24.04 GNOME (version officielle). Base en frontale d'une base MySQL ; échec liaison directe => liaison JDBC.
Avatar de l’utilisateur
rollmops
PassiOOnné
PassiOOnné
Messages : 692
Inscription : 20 déc. 2017 14:45

Re: [Base] Exporter une requête avec un champ Date vers Calc

Message par rollmops »

Bonjour,

Vous faites un getDataArray, il est donc logique que tout soit traité comme chaîne.
Utilisez Xray pour voir comment traiter chaque colonne de la requête.
OpenOffice 4.1.15 - Windows 10
Avatar de l’utilisateur
arverne73
Membre OOrganisé
Membre OOrganisé
Messages : 82
Inscription : 30 mars 2012 16:13
Localisation : Savoie, France

Re: [Base] Exporter une requête avec un champ Date vers Calc

Message par arverne73 »

Bonjour et merci pour la proposition.
Je n'ai aucune pratique de xRay, outil reconnu mais que je n'ai pas réussi à utiliser jusqu'à présent.
En tout cas, effectivement, la fonction GetDataArray fournit un résultat string ou Double.
J'ai mis en place xRay qui me dit effectivement que mon résultat est string… je le savais.

Comme je l'expliquais, j'intercepte ce résultat sous forme de string et je supposais que je pouvais alors le formater en date avant qu'il ne soit écrit dans la cellule Calc et c'est là que j'échoue.
LibreOffice 24.2.5.2 sur Ubuntu 24.04 GNOME (version officielle). Base en frontale d'une base MySQL ; échec liaison directe => liaison JDBC.
Avatar de l’utilisateur
Dude
IdOOle de la suite
IdOOle de la suite
Messages : 25602
Inscription : 03 mars 2006 07:45
Localisation : 127.0.0.1

Re: [Base] Exporter une requête avec un champ Date vers Calc

Message par Dude »

Salut,
arverne73 a écrit : 03 févr. 2024 10:19 j'intercepte ce résultat sous forme de string et je supposais que je pouvais alors le formater en date
Tu convertis la chaîne avec CDate et tu formates la cellule via NumberFormat.
Voir ce récent fil : viewtopic.php?t=68304
Avatar de l’utilisateur
arverne73
Membre OOrganisé
Membre OOrganisé
Messages : 82
Inscription : 30 mars 2012 16:13
Localisation : Savoie, France

Re: [Base] Exporter une requête avec un champ Date vers Calc

Message par arverne73 »

Bonjour et merci !
Cdate a marché mais en sachant qu'en fait c'est un peu moins simple.

J'avais déjà tenté cDate en intervenant dans la lecture du Rowset quand la date était obtenue et ça ne marchait pas ! J'ai finalement réussi mais en intervenant a posteriori.

Donc, ce que j'ai dû faire, c'est intervenir sur la cellule avec numberformat et cDate, mais après la commande

Code : Tout sélectionner

cels.setDataArray(da)
cels étant la plage de la feuille Calc où les données sont écrites et da l'array des données.
Donc les lignes que j'ai ajouté après la ligne précédente sont :

Code : Tout sélectionner

'Boucle à ajouter pour transformer contenu cellule en Date
For i = 1 to q.rowCount
cel = oFeuille.getCellByPosition (23, i) 'la cellule à modifier, colonne 23 (=X) pour moi
cel.Numberformat = 36 'format date chez moi
cel.value=cdate(cel.string) 'conversion en date 
Next i
Cela m'a permis aussi de découvrir que pour écrire une date, il faut utiliser .value comme paramètre de la cellule (non documenté dans les manuels a priori).

Enfin, j'ai vu pas mal de discussions pour savoir quel numberformat employé suivant les versions, système, etc. J'ai trouvé ce très bon fil que j'ai très légèrement modifié selon le fichier joint (fonctionne sur mon système Linux) : il suffit d'ouvrir le fichier et de lancer la macro associée pour voir tous les formats.
Codes_numberformat.odt
A toutes fins utiles.
Vous ne pouvez pas consulter les pièces jointes insérées à ce message.
LibreOffice 24.2.5.2 sur Ubuntu 24.04 GNOME (version officielle). Base en frontale d'une base MySQL ; échec liaison directe => liaison JDBC.
Avatar de l’utilisateur
rollmops
PassiOOnné
PassiOOnné
Messages : 692
Inscription : 20 déc. 2017 14:45

Re: [Résolu][Base] Exporter une requête avec un champ Date vers Calc

Message par rollmops »

Pourquoi ne pas convertir le champ Date en nombre via DATEVAL ?
OpenOffice 4.1.15 - Windows 10
Avatar de l’utilisateur
arverne73
Membre OOrganisé
Membre OOrganisé
Messages : 82
Inscription : 30 mars 2012 16:13
Localisation : Savoie, France

Re: [Résolu][Base] Exporter une requête avec un champ Date vers Calc

Message par arverne73 »

Comme je le disais au début, j'ai essayé quasiment toutes les fonctions que j'ai trouvé ! Si la modification est appliquée au cours de la boucle qui récupère les données, le contenu de la cellule sera toujours considéré comme tu texte une fois les données enregistrées.
Et pour la modification a posteriori, j'ai essayé différentes fonctions : étonnamment, si j'utilisais la fonction Dateval dans le fichier Calc pour transformer la valeur chaîne en une date, cela marchait (mais il fallait intervenir manuellement dans le fichier). Et si j'utilisais Datevalue dans le code avant d'écrire la donnée dans la cellule, le résultat était faux, les jours et les mois corrects mais l'année était toujours 2024 !
Donc Cdate était la bonne réponse.
Je ne cerne pas très bien la différence entre ces fonctions.
LibreOffice 24.2.5.2 sur Ubuntu 24.04 GNOME (version officielle). Base en frontale d'une base MySQL ; échec liaison directe => liaison JDBC.