Images importées avec Macro ne s'affichent pas dans Excel
Bonjour à tous,
Pour importer de manière automatique des images dans un fichier excel, j'ai créé une macro (4000 images à traiter).
principe du code :
1/ pour chaque ligne, en dernière colonne je crée le chemin d'accès à l'image souhaitée
2/ La macro boucle jusqu'à la fin de la feuille et insère une image, redimensionnée et liée à la cellule
NB : je crée un dossier image contenant les images en version vignette pour des raisons de poids.
Deux soucis :
1/ J'ai développé sur Mac et les images ne sont pas visible, une icone avec une croix rouge les remplace.
Mais le principal soucis n'est pas là car la macro marche sur le PC de la personne pour laquelle j'ai développé l'outil.
2/ quand cette personne partage le fichier ainsi complété, les images ne s'affichent pas sur un autre PC. Elles sont là aussi remplacée par un message "l'image liée est absente..." voire copie écran ci-après.
Vous trouverez sur ci-joint
Le fichier excel avec la macro (toutes les lignes n'y sont pas, juste de quoi tester)
un dossier avec quelques images pour tester
Vos avis sont les bienvenus, y compris sur mon code qui doit être améliorable
Merci à tous
Bonjour,
N'est-ce pas dû au fait que les images soient indisponibles sur cet autre PC ?
Comment avez-vous inséré les images ? Avec la méthode .addpicture ?
Si c'est le cas, voici le lien microsoft https://docs.microsoft.com/fr-fr/office/vba/api/excel.shapes.addpicture
Vous y verrez qu'il faut définir le paramètre linktofile sur msofalse et le paramètre savewithdocument sur msotrue pour que l'image reste liée au fichier (et donc devienne indépendante de son chemin d'accès).
Cdlt,
Bonjour,
Merci pour votre réponse.
J'ai utilisé picture.insert...
Est-ce que des équivalents à linktofile et savewithdocument existent ?
Merci pour votre aide
Bonjour,
Je ne sais pas (mais je n'ai pas l'impression). En fait, je ne trouve pas de documentation sur la collection pictures puisque, d'après mes brèves recherches, celle-ci n'est conservée que pour des questions de compatibilité.
Donc, il vaut mieux que vous consultiez le lien de mon premier commentaire et que vous utilisiez la méthode .addpicture de la collection shapes. C'est la même chose, on ajoute une image mais qui appartient à l'ensemble des formes.
Si vous voulez, vous pouvez poster la partie du code qui gère l'insertion et je pourrais essayer de l'adapter...
Cdlt,
Re,
Merci pour votre retour.
Voici mon code qui insère les images et boucle sur toutes les lignes du tableau :
range("Y3").select 'on se positionne sur la première cellule contenant le chemin de la première image à insérer
For i = 1 To (Nlignes - 2) 'on exclue les deux premières lignes d'entête
chemin = ActiveCell.Value 'on récupère le chemin de l'image à insérer
ActiveCell.Offset(0, 1).Select
ActiveCell.RowHeight = 100
Set img = ActiveSheet.Pictures.Insert(chemin) 'insertion de l'image correspondant au chemin
With img
img.Top = ActiveCell.Top
img.Left = ActiveCell.Left
img.Name = Left(chemin, Len(chemin) - 4) & i ' facultatif - Donne un nom à l'image
img.Height = 100 ' s'ajuste à la hauteur de la ligne
img.linktofile = False
img.savewithfile = True
img.Placement = xlMoveAndSize 'pour vérouiller l'image à la cellule
End With
ActiveCell.Offset(1, -1).Select 'pour déplacer à au chemin suivant
Next
La partie d'insertion image est en violet,
Re,
Voici un essai d'adaptation du code (non testé) :
Sub test()
'https://docs.microsoft.com/fr-fr/office/vba/api/excel.shapes.addpicture '<<< pour paramètres
'debut code
application.screenupdating = False
with activesheet
dl = .cells(.rows.count, "Y").end(xlup).row 'dernière ligne non vide en Y
For i = 3 To dl 'de la ligne 3 à la dernière
chemin = .cells(i, "Y").Value 'chemin en Y
with .cells(i, "Z") 'avec Z
.RowHeight = 100 'ajuste hauteur ligne
imgLeft = .Left 'stocke position gauche de cellules
imgTop = .Top 'stock position haute
imgWidth = .columnwidth 'larg col
imgHeight = .rowheight 'haut lignes
End With
with .shapes.AddPicture(chemin, msofalse, msotrue, imgLeft, imgTop, imgWidth, imgHeight) 'ajoute image (renvoie objet shape)
.name = replace(chemin, ".jpg", "") & i 'modifie nom (sans ".jpg")
.Placement = xlMoveAndSize 'pour vérouiller l'image à la cellule
end with
next i
end with
application.screenupdating = true
end subCdlt,
Re,
Merci je teste tout ça...
Pour l'instant, je ne vois pas d'erreur particulière...
Le truc c'est que sur mac, le séparateur est différent ":" ou "/" de celui de windows "\".
On pourrait faire un essai en adaptant une ligne :
For i = 3 To dl 'de la ligne 3 à la dernière
chemin = replace(.cells(i, "Y").Value, "\", application.pathseparator) 'chemin en Y
with .cells(i, "Z") 'avec ZA voir...
Mais il faut que ces mêmes images existent sous ce même chemin (ce dont je doute un peu)...
Cdlt,
en effet j'avais creusé cette piste d'erreur... j'ai peut-être oublié une correction
Est-ce que tu peux essayer, pour faire un test, en utilisant ce code :
Sub test()
'https://docs.microsoft.com/fr-fr/office/vba/api/excel.shapes.addpicture '<<< pour paramètres
'debut code
dim t()
application.screenupdating = False
with activesheet
dl = .cells(.rows.count, "Y").end(xlup).row 'dernière ligne non vide en Y
For i = 3 To dl 'de la ligne 3 à la dernière
chemin = .cells(i, "Y").Value 'chemin en Y
if dir(chemin) <> "" then
with .cells(i, "Z") 'avec Z
.RowHeight = 100 'ajuste hauteur ligne
imgLeft = .Left 'stocke position gauche de cellules
imgTop = .Top 'stock position haute
imgWidth = .columnwidth 'larg col
imgHeight = .rowheight 'haut lignes
End With
with .shapes.AddPicture(chemin, msofalse, msotrue, imgLeft, imgTop, imgWidth, imgHeight) 'ajoute image (renvoie objet shape)
.name = replace(chemin, ".jpg", "") & i 'modifie nom (sans ".jpg")
.Placement = xlMoveAndSize 'pour vérouiller l'image à la cellule
end with
else
n = n + 1: redim preserve t(1 to n): t(n) = chemin & " - ligne " & i
end if
next i
if n > 0 then msgbox "Images introuvables :" & vbcrlf & vbcrlf & join(t, vbcrlf)
end with
application.screenupdating = true
end subCdlt,
Re,
grosse progression ! ça fonctionne mais à chaque image ça me demande d'autoriser l'accès au dossier image puis à l'image :
Quand je dis gros progrès c'est qu'avec tous les codes que j'avais testé avant, sur mon mac les images étaient remplacées par une icone avec une croix rouge tandis que le code fonctionnait sur un PC.
C'est la première fois que les images s'affichent sur mon mac
J'ai vérifié et le dossier contenant les images est bien "public" et non protégé
je viens de constater que si je relance la macro cela fonctionne sans demander les accès !
Je trouve un PC pour tester...
Ah c'est super !
Pour ce nouveau problème, il semble qu'il soit propre à Office 2016 (et versions suivantes probablement) pour Mac. Voici un lien :
https://docs.microsoft.com/fr-fr/office/vba/office-mac/grantaccesstomultiplefiles
L'autorisation est demandée, si j'ai bien compris, pour accéder à chaque fichier. Une fois que cette autorisation a été accordée par l'utilisateur, elle est mémorisée...
Un essai quand même :
Sub test()
'https://docs.microsoft.com/fr-fr/office/vba/api/excel.shapes.addpicture '<<< pour paramètres
'https://docs.microsoft.com/fr-fr/office/vba/office-mac/grantaccesstomultiplefiles '<<< pour Mac
'debut code
dim t()
application.screenupdating = False
with activesheet
dl = .cells(.rows.count, "Y").end(xlup).row 'dernière ligne non vide en Y
filearray = application.transpose(.range("Y3:Y" & dl))
fileAccessGranted = GrantAccessToMultipleFiles(filearray)
For i = 3 To dl 'de la ligne 3 à la dernière
chemin = .cells(i, "Y").Value 'chemin en Y
if dir(chemin) <> "" then
with .cells(i, "Z") 'avec Z
.RowHeight = 100 'ajuste hauteur ligne
imgLeft = .Left 'stocke position gauche de cellules
imgTop = .Top 'stock position haute
imgWidth = .columnwidth 'larg col
imgHeight = .rowheight 'haut lignes
End With
with .shapes.AddPicture(chemin, msofalse, msotrue, imgLeft, imgTop, imgWidth, imgHeight) 'ajoute image (renvoie objet shape)
.name = replace(chemin, ".jpg", "") & i 'modifie nom (sans ".jpg")
.Placement = xlMoveAndSize 'pour vérouiller l'image à la cellule
end with
else
n = n + 1: redim preserve t(1 to n): t(n) = chemin & " - ligne " & i
end if
next i
if n > 0 then msgbox "Images introuvables :" & vbcrlf & vbcrlf & join(t, vbcrlf)
end with
application.screenupdating = true
end subCdlt,
Sur PC ça fonctionne parfaitement merci !
Je vais tester ce MAc et ne manquerai pas de te faire mon retour.
Le problème est donc résolu, mais pour que je comprenne mon erreur qu'est-ce qui ne fonctionnait pas ? Et pourquoi créer un tableau comme tu l'as fait ?
Merci
Je me disais en effet que ça irait mieux sur le PC.
Et bien, je ne sais toujours pas pourquoi ça a bloqué. J'ai le sentiment que l'erreur était due à un mauvais "paramétrage" de la méthode .addpicture et particulièrement à un problème au niveau des chemins d'accès (chemin vide car référence à une mauvaise colonne : Y sur le code au lieu de V sur l'image par exemple ou à un problème de séparateur mac ou encore en problème d'inexistence de certaines de ces images, ou du chemin approprié, sur le mac).
Enfin, pour moi c'était lié au chemin.
Donc j'ai rajouté un test d'existence de fichier permettant de stocker les chemins introuvables et de les renvoyer par msgbox. Mais le premier code que j'ai posté était déjà fonctionnel (à condition d'avoir des chemins existants). En aucun cas, ce test n'a permis de résoudre le problème. Je pense que c'est toi qui a corrigé/modifié quelque chose qui n'allait pas
Bonjour,
J'ai tardé tester le nouveau code sur Mac avec la modif pour autoriser l'accès à tous le fichiers
J'ai comme message d'erreur "type 13 incompatibilité de type" sur la ligne fileAccessGranted = GrantAccessToMultipleFiles(filearray)
J'ai tenté en déclarant les variables mais ça ne marche pas mieux.
Une idée ?
Merci
Bonjour,
C'est une fonction que j'ai découverte comme toi donc c'est difficile à dire, sans mac pour tester...
Pour moi, Le problème porte sur la ligne juste au-dessus. Il faut vérifier qu'il y a plus d'une ligne en Y3:Ydl, que les lignes contiennent bien des chaines de caractères qui sont des chemins valides (avec le séparateur des macs "/", ou ":" sur les systèmes plus anciens).
D'instinct, je pense qu'il s'agit d'un problème de séparateur vu que ça a fonctionné sur windows...
A plus,
OK je vais tester ces pistes.
J'étais surpris dans le code que la valeur du booléen ne soit pas initiée à true.
J'ai essayé en la déclarant et initiant à true mais sans meilleure résultat.
je te tiens informé
Merci en tout cas



