Ceci est une page optimisée pour les mobiles. Cliquez sur ce texte pour afficher la vraie page.

XL 2021 Extraction images depuis commentaire de cellule vers dossier.

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

jeff1494

XLDnaute Occasionnel
Bonjour à toutes et tous;

J'ai un fichier contenant plusieurs feuilles, dont une nommée "INVENDUS" qui contient une liste d'objets.
Une ligne par objet, et en colonne 2 j'ai la description de l'objet qui contient en commentaire une photo de l'objet.

Je voudrais par macro , pour chaque ligne pouvoir extraire la photo contenue en colonne 2, et la sauvegarder dans un dossier que je nomme "JPG_INV", avec comme nom la valeur de la cellule A de la ligne, et une extension ".jpg".

Pour ce faire j'ai récupéré une macro donnée par @patricktoulon sur un autre forum dans un message dont voici le lien (message #15).
Je l'ai placé dans un module nommé "Export_Images".

J'ai juste adapté le code pour correspondre à mes besoins, à priori rien qui ne puisse changer le fonctionnement de la macro.

Le résultat de l'exécution de cette macro, est que je crée bien les images dans le répertoire défini, mais juste la première images qui est affichée comme un carré blanc dans l'explorateur de Windows.

Donc si jamais @patricktoulon passait par là, je lui serais reconnaissant de bien vouloir m'aider à comprendre pourquoi la première image reste comme un carré blanc, alors que les suivantes sont correctement créées. Mais si une autre personne a une idée du pourquoi du comment je suis preneur.

A toutes fins utiles je vous joins un exemple du fichier que j'utilise.

D'avance je remercie tous ceux ou celles qui voudront bien perdre un peu de leur temps pour m'aider.
Bonne journée à toutes et tous.
 

Pièces jointes

Solution
Bonsoir @jeff1494

"Il manquait cela : .Activate"

Pour comprendre ici en Poste #38 : https://excel-downloads.com/threads/export-dimages-renommer-celles-ci.20034890/post-20674531

VB:
Option Explicit

Sub Export_Photos()
    Dim i As Long
    On Error Resume Next
    MkDir ThisWorkbook.Path & "\JPG_INV"
    Err.Clear
'    Sheets.Add After:=Sheets(Sheets.Count)
    Sheets.Add(After:=Sheets("INVENDUS")).Name = "Feuille_Transit"
    
    With Sheets("Feuille_Transit").ChartObjects.Add(0, 0, 100, 100).Chart
        .Parent.Name = "calque"
    End With
    For i = 2 To Sheets("INVENDUS").Cells(Rows.Count, 2).End(xlUp).Row
        If Sheets("INVENDUS").Cells(i, 2).Comment.Shape.Fill.Type = 6 Then
        save_comment_fichier_jpg...
Pour mettre le Boxon j'ai seulement interverti des lignes du tableau.
Ben si avec dans le xml que tu n'utilises pas pour chaque Shape on a l'id le relid et le title . Et pour les Shapes dans le classeur on a l'id ( Ccom.Shape.ID). Je n'ai pas pris le title parce c'est risqué, ce n'est pas forcément le nom de l'objet comme dans le classeur de Jeff.
sauf que l'id qui est dans le xml se présente sous une forme différente (_x0000_s3078) c'est pour cela que je ne prend que les 4 chiffres à droite qui correspondent au Ccom.Shape.ID . Je ne sais pas si les id ont toujours 4 chiffres sinon il faudra faire une adaptation. Et ce type de format n'a l'air d'être que dans des commentaires. Les id de shapes inclus directement dans un classeur ont l'air d'avoir un id qui commence à 1.
 
Dernière édition:
Bonjour @patricktoulon @jurassic pork @fanch55 le forum

j'ai fait un essaie, les images sont renommée dans ce dossier
C:\Votre repertoir qui contient le fichier excel\ExtractionTemp\xl\media\image5.jpeg

VB:
Sub ExtraireImagesDepuisClasseurOuvert()
    ' Déclaration des variables utilisées dans le code
    Dim ws As Worksheet               ' Déclare la variable pour la feuille "INVENDUS"
    Dim Plg As Range                  ' Plage des cellules à parcourir (B2:B dernière ligne)
    Dim Cell As Range                 ' Variable représentant chaque cellule de la plage à parcourir
    Dim lastRow As Long               ' Dernière ligne de la feuille (trouve la dernière ligne utilisée de la colonne B)
    Dim CheminClasseur As String      ' Chemin complet du classeur ouvert
    Dim CheminZip As String           ' Chemin complet du fichier ZIP à créer
    Dim DossierTemp As String         ' Chemin du dossier temporaire où le fichier ZIP sera extrait
    Dim DossierMedia As String        ' Chemin vers le sous-dossier "xl\media" où les images sont extraites
    Dim fso As Object                 ' Objet FileSystemObject utilisé pour la manipulation de fichiers/dossiers
    Dim sh As Object                  ' Objet Shell.Application pour interagir avec les fichiers ZIP
    Dim NSdest As Object, NSzip As Object ' Dossiers d'extraction (destination et source ZIP)
    Dim t As Single                   ' Variable pour calculer le temps écoulé (utilisé pour l'attente)
    Dim cheminImage As String         ' Variable non utilisée dans le code actuel (peut être supprimée)
    Dim NouveauNom As String          ' Nouveau nom pour renommer les images en fonction du commentaire de chaque cellule
    Dim i As Integer                  ' Compteur pour créer des noms uniques pour les images
    Dim fichierImage As String        ' Chemin complet du fichier image à traiter
    Dim image As Object               ' Représente un fichier image extrait dans le dossier "xl\media"
 
    ' Récupérer le chemin du classeur ouvert
    CheminClasseur = ThisWorkbook.FullName ' Chemin complet du fichier Excel actuellement ouvert
    CheminZip = ThisWorkbook.Path & "\TempClasseur.zip" ' Définir le chemin du fichier ZIP à créer
    DossierTemp = ThisWorkbook.Path & "\ExtractionTemp\" ' Définir le chemin du dossier temporaire d'extraction
    DossierMedia = DossierTemp & "xl\media\" ' Chemin vers le dossier où les images seront extraites
 
    ' Créer un objet FileSystemObject pour manipuler les fichiers/dossiers
    Set fso = CreateObject("Scripting.FileSystemObject")
 
    ' Supprimer le dossier temporaire existant s'il existe
    On Error Resume Next ' Ignore les erreurs pour ne pas stopper le code en cas de dossier manquant
    If fso.FolderExists(DossierTemp) Then fso.DeleteFolder DossierTemp, True ' Supprimer le dossier et son contenu
    On Error GoTo 0 ' Restaurer la gestion des erreurs par défaut
 
    ' Créer un nouveau dossier temporaire
    fso.CreateFolder DossierTemp
 
    ' Copier le classeur ouvert dans un fichier ZIP
    fso.CopyFile CheminClasseur, CheminZip, True ' Crée une copie du classeur sous forme de fichier ZIP
 
    ' Attendre que le fichier ZIP soit effectivement créé
    t = Timer ' Récupère l'heure de départ
    Do While Not fso.FileExists(CheminZip) ' Boucle tant que le fichier ZIP n'est pas créé
        DoEvents ' Permet à d'autres événements de se produire (pour ne pas bloquer Excel)
        If Timer - t > 5 Then ' Si l'attente dépasse 5 secondes
            MsgBox "Le fichier ZIP n'a pas été créé dans les 5 secondes.", vbCritical
            Exit Sub ' Quitte la macro si le fichier ZIP n'est pas créé dans le délai
        End If
    Loop
 
    ' Créer un objet Shell.Application pour extraire le contenu du ZIP
    Set sh = CreateObject("Shell.Application")
    Set NSdest = sh.Namespace(fso.GetAbsolutePathName(DossierTemp)) ' Dossier de destination pour l'extraction
    Set NSzip = sh.Namespace(fso.GetAbsolutePathName(CheminZip)) ' Fichier ZIP à extraire
 
    ' Extraire le contenu du fichier ZIP dans le dossier temporaire
    NSdest.CopyHere NSzip.Items, 16 ' Le "16" est un flag qui permet l'extraction en mode silencieux
 
    ' Attendre l'apparition du dossier "xl\media" après extraction
    t = Timer ' Récupère l'heure de départ
    Do While Not fso.FolderExists(DossierMedia) ' Boucle tant que le dossier "xl\media" n'existe pas
        DoEvents
        If Timer - t > 10 Then Exit Do ' Quitter après 10 secondes si le dossier n'apparaît pas
    Loop
 
    ' Vérifier si les images ont bien été extraites dans le dossier "xl\media"
    If fso.FolderExists(DossierMedia) Then
        MsgBox "Extraction des images réussie dans le dossier : " & DossierMedia, vbInformation
    Else
        MsgBox "Aucune image trouvée dans 'xl\media'.", vbCritical
    End If
 
    ' Définir la feuille "INVENDUS" pour travailler avec les données
    Set ws = ThisWorkbook.Worksheets("INVENDUS")
    lastRow = ws.Cells(ws.Rows.Count, 2).End(xlUp).Row ' Trouver la dernière ligne utilisée dans la colonne B
    Set Plg = ws.Range("B2:B" & lastRow) ' Définir la plage à parcourir (de B2 à la dernière ligne)

    ' Examiner les fichiers extraits et associer chaque image avec le commentaire de la cellule
    i = 0 ' Initialiser le compteur pour les images
    For Each Cell In Plg ' Parcourir chaque cellule de la plage
        If Not Cell.Comment Is Nothing Then ' Si la cellule contient un commentaire
            ' Extraire le texte du commentaire pour créer un nom d'image unique
            NouveauNom = Cell.Value2
 
            ' Vérifier si le dossier média existe
            If fso.FolderExists(DossierMedia) Then
                ' Parcourir les fichiers dans le dossier média
                For Each image In fso.GetFolder(DossierMedia).Files
                    If InStr(1, image.Name, "image") > 0 Then ' Vérifier que le fichier est une image
                        i = i + 1
                        fichierImage = DossierMedia & "image" & i & ".jpeg" ' Créer le nom complet du fichier image
                        ' Si le fichier image existe, renommer l'image
                        If fso.FileExists(fichierImage) Then
                            fso.MoveFile fichierImage, DossierMedia & NouveauNom & ".jpg" ' Renommer l'image avec le texte du commentaire
                            Exit For ' Quitter la boucle dès qu'une image est renommée
                        End If
                    End If
                Next image
            End If
        End If
    Next Cell

    ' Libération des objets pour éviter les fuites de mémoire
    Set fso = Nothing
    Set sh = Nothing
    Set NSdest = Nothing
    Set NSzip = Nothing
    Set ws = Nothing
End Sub

PS : Ici quand le Zip et le dossier est crée je ne suis pas arrivé a le supprimer (par VBA)

A Supprimer a la manuellement quand il existe (puis recommencer la VBA)
Voir ci-dessous
' Supprimer le dossier temporaire existant
On Error Resume Next
If fso.FolderExists(DossierTemp) Then fso.DeleteFolder DossierTemp, True
On Error GoTo 0

' Créer le dossier temporaire
fso.CreateFolder DossierTemp
 
Dernière édition:
Bonsoir Laurent
et oui le shell application prends possession de l'archive et des dossiers tant qu'il a pas fini
et si il y a eu une erreur il arrive parfois que le dossier devienne un dossier fantom on le voit sur le bureau mais on arrive pas à le supprimer mais qu'il disparaisse au prochain démarrage du pc
dans ton code tu fait pas tout a fait bien et tu renomme les images avec les mauvaises données car dans le zip elle ne sont pas dans le même ordre
avec mon code simplifiée je n'ai pas de soucis pour extraire mais c'est pour renommer
après examen c'est la partie xml sur le vmldrawing1.vml qui me pose problème l'object xml ne le lit pas
j'ai le même problème avec le code de @jurassicpork d'ailleurs
et par pitiééééééééééééééééé vire moi ce FSO gros lourdaud de là
 
tiens laurent
voici une sub et le fichier le msgbox doit afficher le code xml
VB:
Sub test()
 Set xmldoc = CreateObject("MSXML2.DOMDocument")
    xmldoc.async = False
    xmldoc.Load "C:\Users\patricktoulon\Desktop\media\vmlDrawing1.vml"
    XmlNamespaces = "xmlns:v='urn:schemas-microsoft-com:vml' xmlns:o='urn:schemas-microsoft-com:office:office'"
    xmldoc.SetProperty "SelectionNamespaces", XmlNamespaces
    'Set Nodes = xmldoc.SelectNodes("//v:shape")
  MsgBox xmldoc.XML
End Sub

si tu y arrive envoie la sauce
perso j'ai tout essayer je l'ai même transformé en xml iso mais rien y fait il y a un truc dedans qui m'empêche de le lire
 

Pièces jointes

patrick, j'ai comparé ton fichier vmlDrawing1.vml par rapport à celui que j'extrais du fichier du post #74 , il y a des différences et quand je fais une vérification de syntaxe de ton fichier il y a des erreurs .
Voici le genre d'erreur que tu as dans ton fichier :
Code:
 <v:fill o:relid="rId1" o:relid="rId1" o:relid="rId1" o:relid="rId1" o:title="OBJ006"
le o:relid est répété plusieurs fois. Quand je regarde dans le fichier xlsm , dans ce fichier il n'y a bien qu'une fois o:relid
Dans ton code j'ai rajouté ces lignes :
VB:
    drawing1VML = UnZipeur.Namespace(sourceZip & "\xl\drawings").Items.Item("vmlDrawing1.vml").Path
    UnZipeur.Namespace(DestFolderimage & "\").CopyHere (drawing1VML)
    drawing1VML = DestFolderimage & "\vmlDrawing1.vml"
Le fichier est bon.
Comment as-tu récupéré ton fichier ? Avec quelle version d'Excel travailles-tu ?
Avec ceci à la fin de ton code, j'obtiens la même chose qu'avec mon code :
VB:
    'fin de dézippage les VML compris
    '----------------------------------------------------------
    'copier les images
    Dim DictShp As Object, DictFile As Object, Ccom As Object, Cel,  Fname$
    Set DictShp = CreateObject("Scripting.Dictionary")
    Set DictFile = CreateObject("Scripting.Dictionary")
    ChargerDicts drawing1VML, drawing1VMLREL, DictShp, DictFile
    For Each Cel In [Tbl_Invendus[Désignation]]
         Set Ccom = Cel.Comment
         Select Case True
           Case Ccom Is Nothing
           Case Not Ccom.Shape.Fill.Type = msoFillPicture
           Case Else
           Fname = DictFile(DictShp(CStr(Ccom.Shape.id)))
           FileCopy DestFolderimage & "\" & Fname, _
               DestFolderimage & "\" & Cel & ".jpg"
         End Select
    Next
  Kill DestFolderimage & "\image*.*"
  Kill drawing1VMLREL
  Kill drawing1VML
  Set DictShp = Nothing: Set DictFile = Nothing
  MsgBox "Extraction des images de commentaires terminée"
End Sub

Sub ChargerDicts(vmlFile, vmlrelFile, DictShp, DictFile)
    Dim fileName$, objName, relId$, shapeId$, XmlNamespaces$
    Dim FSO As Object, xmlDoc As Object, nodes As Object, node As Object
    Set FSO = CreateObject("Scripting.FileSystemObject")
    Set xmlDoc = CreateObject("MSXML2.DOMDocument")
    xmlDoc.async = False
    xmlDoc.Load vmlFile
    XmlNamespaces = "xmlns:v='urn:schemas-microsoft-com:vml' xmlns:o='urn:schemas-microsoft-com:office:office'"
    xmlDoc.SetProperty "SelectionNamespaces", XmlNamespaces
    Set nodes = xmlDoc.SelectNodes("//v:shape")
    For Each node In nodes
       shapeId = Right(node.getAttribute("id"), 4)
       relId = node.ChildNodes(0).getAttribute("o:relid")
       'Debug.Print shapeId,relId
       DictShp.Add shapeId, relId
    Next
    xmlDoc.Load vmlrelFile
    Set nodes = xmlDoc.SelectNodes("//Relationship")
    For Each node In nodes
        fileName = FSO.GetFileName(node.getAttribute("Target"))
        relId = node.getAttribute("Id")
        'Debug.Print relId, fileName
        DictFile.Add relId, fileName
    Next
    Set FSO = Nothing: Set nodes = Nothing: Set xmlDoc = Nothing
End Sub
 
Dernière édition:
Hello,
Patrick, Bon ben je crois savoir d'où vient le problème :
Dans un post précédent quand tu m'as dit que tu avais un message d'erreur avec mon code, j'aurais dû creuser le problème.
J'ai fait un test avec le fichier du post #74 dans un excel2010 sur win7 .
Quand on fait une légère modification du fichier et qu'on l'enregistre, le fichier vmlDrawing1.vml se vérole à l'intérieur du fichier xlsm et en a plusieurs o:relid par shape. Le phénomène ne se produit pas avec Excel 2016. Il doit y avoir une incompatibilité. Si tu peux essayer avec d'autres versions d'Excel.
Ami calmant, J.P
 
c'est dommage par qu'en fait on peut se servir que de lui
fait moi un code avec extraction par Powershell juste pour lui juste pour voir
je ne sais pas si cela servira. Ce qui est grave c'est qu'une ancienne version d'Excel vienne corrompre le fichier vml dans le xlsm. ça sent le bug? Il faudrait que tu construises avec une ancienne version d'Excel un classeur avec des images dans les commentaires pour voir si cela se produit et voir si le vml a la même tête.
 
- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD

Discussions similaires

Réponses
2
Affichages
153
Réponses
19
Affichages
474
Les cookies sont requis pour utiliser ce site. Vous devez les accepter pour continuer à utiliser le site. En savoir plus…