Macro pour insérer une image - Calc 24.2.5.2

Bonjour à tous et toutes,
J’ai récemment récupéré un fichier Calc pour automatiser la création de courriers à mon travail, dont une des macros sert à insérer des images.
Cependant, je fais face à un certain nombre d’erreurs que je n’arrive pas à comprendre et encore moins à corriger, même si j’ai réussi à bidouiller et réparer une autre macro (ce Calc étant mes premiers pas dans le monde des macros Libreoffice, voire même des macros de tableurs tout court).

J’avais déjà fait quelques modifications la semaine dernière avant un long week-end, car les erreurs “Variable d’objet non définie” apparaissaient à chaque utilisation de “oGraph.X” (que ce soit avec GraphicURL, Anchor ou dans la définition de oSize), sans résultat probant.

Ce matin, voyant que ça ne servait à rien et ne me souvenant plus très bien des modifications que j’avais apporté, j’ai repris le code “sain” de la macro (que je vous met en-dessous). Et à mon grand étonnement, je ne retrouve pas les erreurs de la semaine dernière sur les “oGraph”, mais il semble que le module “com.sun.star.drawing.GraphicObjectShape” qui fonctionnait très bien la semaine dernière décide de me mettre des bâtons dans les roues.

Quand j’exécute la macro à partir de mon document, elle me retourne une erreur “Variable d’objet non définie” à cette ligne : oGraph = oDoc.createInstance(“com.sun.star.drawing.GraphicObjectShape”).
Il me semble pourtant que tous les termes sont définis, mais ne m’y connaissant pas je me tourne vers vous afin d’avoir vos avis et conseils. (nb : j’ai déjà tenté de remplacé les “.” pour “:” ou “::” sans résoudre le problème, ça n’a fait que déplacer l’erreur sur la syntaxe de la commande).
edit : J’ai réussi à résoudre ce problème, il manquait simplement la ligne “oDoc = thiscomponent”. Cependant, je me retrouve avec une nouvelle erreur, qui concerne la ligne “oPage.add(oGraph)”, et dont le message d’erreur indique :
"Erreur d’exécution BASIC. Une exception s’est produite : Type: com.sun.star.lang.IllegalArgumentException
Message: at C:/cygwin64/home/buildslave/source/libo-core/svx/source/unodraw/unoshap2.cxx:1407." que je ne comprends pas du tout le chemin d’accès ne menant à rien, n’ayant pas cygwin64 d’installé sur mon poste. Est-ce que quelqu’un pourrait éclairer ma lanterne ?

J’aimerai aussi avoir vos retours sur ce qui peut bloquer les fonctions (?) “oGraph” (toujours avec le message d’erreur “Variable d’objet non définie”) qui m’ont hanté la semaine dernière et qui, je pense, reviendront une fois le “com.sun.star…” réparé.

Je vous remercie d’avance pour votre aide.

Le code complet de la macro (tel que récupéré d’une version saine) :

REM Macro qui insère une image
Sub InsereImage(Feuille as object,Cell as string,CellChemin as string,Taille as Double) 'InsereImage(oDoc.CurrentController.ActiveSheet,"V4","A9",0.8) : Insère dans la feuille Feuille une image en cellule V4, où le chemin de l'image est écrit en cellule A9, avec une taille de 1 (la taille est à faire varier entre 0 et 10)
    
       Dim sURL As String
       Dim oPage As Object
       Dim oFeuille As Object
       Dim oGraph As Object
       Dim oDoc As Object
       Dim c As Object

       oFeuille = Feuille
       sUrl = ConvertToUrl (Chemin)

       oPage = oFeuille.getDrawPage()
       oGraph = oDoc.createInstance("com.sun.star.drawing.GraphicObjectShape")
       oGraph.GraphicURL = sUrl
       
       oPage.add(oGraph)
       'c = oFeuille.getCellByPosition(Co -1, Li - 1)
       c = oFeuille.getCellRangeByName(Cell)
       oGraph.Anchor = c

       Dim oSize As New com.sun.star.awt.Size
       Dim LargeurCellule, HauteurCellule As Long
       Dim k As Double
       Dim k1,k2,kb As Double
         
       LargeurCellule = 10000 'c.Size.Width
       HauteurCellule = 10000 'c.Size.Height

       oSize = oGraph.Graphic.getSize
       With oSize
          'k1 = LargeurCellule/.Width   
         ' k2 = HauteurCellule/.Height
          k = Taille
          'kb= 20
          
          'If k1 < k2 Then
            ' k = k1
         ' Else
           '  k = k2
          'End If
             .Width = .Width*k  'largeur
             .Height = .Height*k   'Hauteur
       End With
       oGraph.setsize(oSize)

End sub

Bonjour et bienvenue Lucien,

à première vue, si oDoc est déclaré, il n’est pas défini :wink:

CellChemin c’est aussi n’importe quoi.

pour éviter les devinettes en cascade, tester des Sub dont tous les paramètres sont clairement définis.
et éviter aussi des lignes de 250 caractères :wink:

Bonjour Jfn,

Merci pour votre réponse,
Si j’ai bien compris “Dim oDoc as Object” ne sert qu’à déclarer la fonction et de préciser son type (string, long, object, …), et il me manquait la ligne “oDoc = thiscomponent” afin de définir la variable.
Désolé si ça paraît être le b.a.-ba, c’est vraiment la première fois que j’aborde les macros, et à part quelques connaissances qui remontent au lycée, je n’ai plus touché à du code depuis une dizaine d’année.

Bonjour Fpy,

En effet, je parle de bidouille car j’essaye de faire fonctionner un Calc et avec mon niveau et connaissances ce que je fais s’apparente plus à un bricolage avec un bout de scotch et deux élastiques qu’à une véritable compréhension du fonctionnement des macros et de leur code. J’ai récupéré le document tel quel, avec toutes ses macros déjà implémentées, et le Calc devait être la seule partie du projet censée marcher du premier coup (en tout cas, rien ne laissait à penser que j’allais devoir me confronter aux macros). Du coup je me retrouve à bidouiller les macros, non pour les écrire, mais pour réussir à les faire fonctionner sans erreurs.
Pouvez-vous expliquer en quoi CellChemin est du n’importe quoi ?
Pour les tests des Sub dont tous les paramètres sont définis, je vous rejoins ce serait l’idéal, malheureusement n’ayant ni les compétences, ni les connaissances, et encore moins le temps pour les acquérir, je suis forcé à tâtonner dans le noir à chaque problème et à éplucher les forums pour essayer de trouver une solution, ce qui est loin d’être parfait.

pas très rassurant :face_with_thermometer:

pour répondre à la question originale, cette macro insère une image (depuis un fichier .png)

Sub InsereImage()
    Dim oGraph As Object

    oGraph = thisComponent.createInstance("com.sun.star.drawing.GraphicObjectShape")
    oGraph.GraphicURL =  ConvertToUrl( "/someDir/d1/d2/someFile.png")
    
    thisComponent.CurrentController.ActiveSheet.getDrawPage().add(oGraph)

    Dim oSize
    Dim oPos
	oSize = oGraph.Size
    oSize.Height = 3000
    oSize.Width = 5000
    oGraph.setsize(oSize)

    oPos = oGraph.position
    oPos.x = 2000
    oPos.y = 2000
    oGraph.position = oPos
End sub

image

Malheureusement les choses sont ce qu’elles sont, la programmation et les macros sont bien trop éloignées de mon travail pour me permettre de m’y consacrer sans risquer d’embêter ou de retarder le reste de mon service.

Concernant la macro que vous présentez, je reste bloqué au même problème que celui que je cite dans l’edit de mon message originel.
Libreoffice me surligne la ligne contenant la fonction add.(oGraph) dans les deux codes et me sort le même message d’erreur :

Erreur d’exécution BASIC.
Une exception s’est produite :
Type: com.sun.star.lang.IllegalArgumentException
Message: at C:/cygwin64/home/buildslave/source/libo-core/svx/source/unodraw/unoshap2.cxx:1407.

Je ne comprends pas d’où provient l’erreur, le logiciel Cygwin n’étant pas installé sur mon poste, le chemin d’accès indiqué ne devrait pas exister. J’ai réussi à trouver trace du fichier unoshap2.cxx sur ce site mais je le comprends encore moins que le code des macros.
J’imagine que le module invoqué dans le message d’erreur est celui-ci, et que son absence empêche tout bon fonctionnement d’une des fonctions invoquées.

 1400             : //----------------------------------------------------------------------
    1401           1 : void SvxShapePolyPolygonBezier::SetPolygon(const basegfx::B2DPolyPolygon& rNew) throw()
    1402             : {
    1403           1 :     ::SolarMutexGuard aGuard;
    1404             : 
    1405           1 :     if(mpObj.is())
    1406           1 :         static_cast<SdrPathObj*>(mpObj.get())->SetPathPoly(rNew);
    1407           1 : }

Dois-je donc obligatoirement installer ce logiciel, ou existe-t-il une autre solution pour passer outre ?
Je ne trouve aucune trace d’un message d’erreur similaire sur d’autres forum qui traitent de l’insertion d’image sur libreoffice ou open office.

par curiosité, gardez une trace de ce temps.
et par définition, c’est de l’acquisition de compétence : Le Bourgeois gentilhomme — Wikipédia :wink:

donc reprendre les bases :

  1. Ask/Guide - How to use the Ask site - The Document Foundation Wiki #More_details
  2. copie d’écran du code de la macro avec la popup d’erreur.
    ça ressemble à un nom de fichier .png inexistant !? :face_with_thermometer:

la partie pertinente c’est IllegalArgumentException

le reste réfère à la machine qui a construit votre version de LibreOffice.
pour les détails (très très) technique ->: Building LibreOffice on Windows with Cygwin and MSVC: Tips and Tricks - The Document Foundation Wiki
mais totalement hors sujet ici.

Bonjour Fpy,

pour le 1., voici les détail de la version de libreoffice que j’utilise (et ma base windows est : windows 11 entreprise 23H2)
image

pour le 2. :

En effet, quand j’ai repris le code que vous avez fourni dans l’un de vos précédent message, je me suis rendu compte en revenant de réunion que j’avais mal recopié le nom de mon image test et qu’il manquait un accent. Une fois la coquille repérée et corrigée, l’image s’affiche convenablement.
J’en retiens donc que dans le code de base, l’erreur vient donc du fait que le chemin d’accès aux images ne semble pas être défini, et que la macro n’arrive pas à les atteindre. Le twist étant que la macro est censée récupérer les images destinées au destinataire du courrier dans le fichier contenant les images de toutes les lettres à générer.
J’ai essayé de renseigner le chemin d’accès au dossier d’images dans le code, mais cela ne semble pas marcher, il me semble que la macro doit être guidée jusqu’au bout avec l’url complet de l’image voulue (pour reprendre votre exemple : /someDir/d1/d2/someFile.png).
Je dois donc trouver un moyen pour faire en sorte que la macro détermine quelle(s) image(s) prendre en compte en fonction du destinataire voulu, sans spécifier à chaque fois l’url complète (ce qui nuirait à l’objectif d’origine du fichier, qui est d’automatiser la création de lettres sans nécessité d’y toucher en permanence).


et le code complet :

REM Macro qui insère une image
Sub InsereImage(Feuille as object,Cell as string,CellChemin as string,Taille as Double) 

	   Dim sURL As String
	   Dim Chemin As String
       Dim oPage As Object
       Dim oFeuille As Object
       Dim oGraph As Object
       Dim oDoc As Object
       Dim c As Object
       Dim oSize As New com.sun.star.awt.Size
       Dim LargeurCellule, HauteurCellule As Long
       Dim k As Double
       Dim k1,k2,kb As Double
      
       oDoc = thiscomponent
       oFeuille = Feuille
       'Chemin = oDoc.Sheets.getbyname("Référentiels").getcellrangebyname("A5").string 
       'la case visée contient le chemin d'accès au dossier où la macro est censée 
       'prendre les images | ne marche pas
       'Chemin = "C:/Users/LUCIEN/Documents/Police CDS/1_Police CDS/5. Calc/Images"
       'ne marche pas non plus
       sUrl = ConvertToUrl(Chemin)

       oPage = oFeuille.getDrawPage()
       oGraph = oDoc.createInstance("com.sun.star.drawing.GraphicObjectShape")
       oGraph.GraphicURL = sUrl
       oPage.add(oGraph)
       c = oFeuille.getCellRangeByName(Cell)
       oGraph.Anchor = c

         
       LargeurCellule = 10000 'c.Size.Width
       HauteurCellule = 10000 'c.Size.Height

       oSize = oGraph.Graphic.getSize
       With oSize
          k = Taille
             .Width = .Width*k  'largeur
             .Height = .Height*k   'Hauteur
       End With
       oGraph.setsize(oSize)

End sub

au moins 1 acquis :relieved:

ça méritera un sujet séparé.

sur le fond, ça ne serait pas inutile de regarder : utiliser les Procédures, Fonctions ou Propriétés

typiquement un sujet où l’IA peut accélérer l’apprentissage.

Se servir de la fonction FileExists