Macro Excel 2010 - Insérer automatiquement des images sans déformation

Bonjour,

Je ne suis pas une pro des macros mais je dois intégrer des photos à une liste de plusieurs centaines de lignes, chaque ligne correspondant à une photo qui se trouve dans un dossier sur mon disque : la photo est là pour identifier l'objet dont on détaille les caractéristiques dans les autres colonnes.

Pour certaines lignes, la photo n'existe pas encore, mais me sera remise plus tard et il faudra que je l'intègre alors.

Voici la macro que j'ai trouvée, en piochant ici et là dans des tutos sur le web. Elle fonctionne, mais avec un bouton, et pour une seule photo sur une seule ligne. Il faudrait que la macro fasse la même chose pour toutes les lignes en une seule fois.

Par ailleurs, je ne sais pas comment indiquer que le bord droit de la photo doit être variable en fonction de la hauteur, pour qu'elle ait la même proportion que l'original et ne soit pas déformée.

Enfin, je ne sais pas comment réduire le poids en pixel de l'image originale pour que mon fichier ne soit pas trop lourd.

Private Sub cmdDisplayPhoto_Click()

Application.ScreenUpdating = False

Dim RegieNumber As String, T As String

myDir = "C:\Documents\Photos\"

RegieNumber = Range("D2")

T = ".jpg"

Range("E2").Value = RegieNumber

On Error GoTo errormessage:

ActiveSheet.Shapes.AddPicture Filename:=myDir & RegieNumber & T, linktofile:=msoFalse, savewithdocument:=msoTrue, Left:=Range("E2").Left, Top:=Range("E2").Top, Width:=60, Height:=78

errormessage:

If Err.Number = 1004 Then

MsgBox "File does not exist" & vbCrLf & "Check of the RegieNumber !"

Range("F2").Value = ""

Range("B2").Value = ""

End If

Application.ScreenUpdating = True

End Sub

Voilà, je ne sais pas si vous pouvez m'aider mais cela fait trois jours que je n'avance plus, donc un coup de main me serait bien utile.

Un grand merci d'avance !

Marie

Bonjour Marie, et bienvenue sur ce Forum !

Il faudrait que la macro fasse la même chose pour toutes les lignes en une seule fois.

Je suppose que tu devrais utiliser une Boucle !

Donc essaye avec le code ci-dessous :

Private Sub cmdDisplayPhoto_Click()
Dim x As Long
Application.ScreenUpdating = False
Dim RegieNumber As String, T As String
myDir = "C:\Documents\Photos\"
For x = 2 To Range("D" & Rows.Count).End(xlUp).Row
    RegieNumber = Range("D" & x)
    T = ".jpg"
    Range("E" & x).Value = RegieNumber
    On Error GoTo errormessage:
    ActiveSheet.Shapes.AddPicture Filename:=myDir & RegieNumber & T, linktofile:=msoFalse, savewithdocument:=msoTrue, Left:=Range("E" & x).Left, Top:=Range("E" & x).Top, Width:=60, Height:=78
errormessage:
    If Err.Number = 1004 Then
        MsgBox "File does not exist" & vbCrLf & "Check of the RegieNumber !"
        Range("F" & x).Value = ""
        Range("B" & x).Value = ""
    End If
Next
End Sub

Restant à ta dispo!

Merci beaucoup Juice, ça fonctionne, c'est formidable !

Le seul souci, c'est que les photos ont toutes la même largeur ce qui fait que la photo est déformée, car je ne sais pas comment écrire qu'elles doivent avoir une largeur proportionnelle à la largeur d'origine en fonction de la nouvelle hauteur.

je pense que c'est dans cette partie du code :

ActiveSheet.Shapes.AddPicture Filename:=myDir & RegieNumber & T, linktofile:=msoFalse, savewithdocument:=msoTrue, Left:=Range("E" & x).Left, Top:=Range("E" & x).Top, Width:=60, Height:=78

Au lieu de Width:=60 il faudrait mettre quelque chose mais je ne sais pas trop quoi.

Tu as une idée ?

J'ai changé comme ceci, mais ça ne marche pas non plus :

ActiveSheet.Shapes.AddPicture Filename:=myDir & RegieNumber & T, linktofile:=msoFalse, savewithdocument:=msoTrue, Left:=Range("E" & x).Left, Top:=Range("E" & x).Top, Width:=LockAspectRatio, Height:=78

Help !

Re-

Excuse moi pour mon absence de retour, mais je suis normalement inactif le week-end :p (L'week-end c'est fait pour être posay dans son canapay)

Et puis j'ai réfléchis et tenter de trouver des solutions mais c'est pas facile à résoudre ton cas.

En gros tu veux garder une image non déformer après avoir toucher à la hauteur de celle-ci; Donc que la largeur de l'image s'adapte à la nouvelle hauteur.

Ton cas dans un exemple simple :

Dans l'exemple, sa ferra donc : (150 x 100) / 200 = 75 -> Qui serait la LARGEUR idéale pour que mon Image ne paraisse pas déformée après j'ai modifié la HAUTEUR

Tout sa pour dire que si tu veux une solution à ton problème : Faut juste trouver la hauteur initiale de ton image :p

Restant à dispo! (Mais Lundi hein oh xD)

Bonsoir,

Moi non plus je ne travaille pas le week-end !

Je ne vais pas pouvoir trouver la hauteur initiale de l'image, j'en ai 500 à importer. Mais je note bien que c'est une piste, c'est forcément un bout de la solution.

Je vais donc continuer à chercher dans les tutos... Si je trouve, je te dis.

Merci encore en tous cas de ton aide ! C'est déjà formidable que j'arrive à avoir un bout de la bonne image pour chaque ligne.

Marie

Bonjour,

Si tu veux avoir un rapport hauteur/largeur, il te suffit de multiplier la hauteur initiale par le rapport de la largeur initiale sur la nouvelle largeur :

=Hauteur_Initiale x Largeur_Initiale/Nouvelle_Largeur

Exemple, une piste simple avec un code récupéré sur le net (Excel-Malin.com) et quelques modifs pour avoir les dimensions séparées dans un tableau :

H = 200 x 150 / 100 = 300

Sub test()

    Dim Tbl() As Single
    Dim R As Single
    Dim Hauteur As Integer

    Tbl = DimensionsImage(myDir & RegieNumber & T)
    If Tbl(1) = -1 Then MsgBox "Erreur sur la photo '" & myDir & RegieNumber & T & "' !": Exit Sub

    'adapter le rapport R = Tbl(2) / Tbl(1) ou R = Tbl(1) / Tbl(2)
    R = Tbl(2) / Tbl(1)

    Hauteur = 78

    ActiveSheet.Shapes.AddPicture myDir & RegieNumber & T, msoFalse, msoTrue, Range("E" & x).Left, Range("E" & x).Top, Hauteur, Hauteur * R

End Sub

Public Function DimensionsImage(Fichier As String) As Single()
    'par Excel-Malin.com ( https://excel-malin.com )

    Dim Tbl(1 To 2) As Single
    Dim T
    Dim Dimensions As String
    Dim objShell As Object
    Dim objDossier As Object
    Dim objFichier As Object

    On Error GoTo Erreur

    Dim ImageDossier As Variant
    Dim ImageFichier As Variant

    ImageFichier = Mid(Fichier, InStrRev(Fichier, "\") + 1)
    ImageDossier = Left(Fichier, Len(Fichier) - Len(ImageFichier))

    Set objShell = CreateObject("Shell.Application")

    Set objDossier = objShell.Namespace(ImageDossier)
    Set objFichier = objDossier.ParseName(ImageFichier)

    Dimensions = CStr(objFichier.ExtendedProperty("Dimensions"))
    Dimensions = Left(Dimensions, Len(Dimensions) - 1)
    Dimensions = Right(Dimensions, Len(Dimensions) - 1)

    T = Split(Dimensions, "x")

    Tbl(1) = CSng(Trim(T(0)))
    Tbl(2) = CSng(Trim(T(1)))

    DimensionsImage = Tbl()

    Set objFichier = Nothing

    Exit Function

Erreur:
    Tbl(1) = -1
    Tbl(2) = -1

    DimensionsImage = Tbl()

End Function

Bonjour à tous,

Et merci à nouveau pour votre aide, c'est génial, je ne me sens plus seule devant mon problème !

Donc j'ai fait un mix pour essayer d'intégrer les propositions de Juice et Theze, et voilà ce que cela donne, mais... cela ne marche pas ! Il doit y avoir une erreur, et certainement plusieurs, mais je suis tellement nouvelle en macro que je ne sais pas du tout où elles sont. Si vous avez des pistes...

Private Sub cmdDisplayPhoto_Click()

Dim x As Long
Application.ScreenUpdating = False
Dim RegieNumber As String, T As String
For x = 2 To Range("D" & Rows.Count).End(xlUp).Row
    RegieNumber = Range("D" & x)
    T = ".jpg"
    Range("E" & x).Value = RegieNumber

Dim Tbl() As Single
Dim R As Single
Dim Hauteur As Integer

    myDir = "C:\Documents\Photos\"

    Tbl = DimensionsImage(myDir & RegieNumber & T)
    If Tbl(1) = -1 Then MsgBox "Erreur sur la photo '" & myDir & RegieNumber & T & "' !": Exit Sub

    'adapter le rapport R = Tbl(2) / Tbl(1) ou R = Tbl(1) / Tbl(2)
    R = Tbl(2) / Tbl(1)

    Hauteur = 78

    ActiveSheet.Shapes.AddPicture myDir & RegieNumber & T, msoFalse, msoTrue, Range("E" & x).Left, Range("E" & x).Top, Hauteur, Hauteur * R

End With

Public Function DimensionsImage(Fichier As String) As Single()
    'par Excel-Malin.com ( https://excel-malin.com )

    Dim Tbl(1 To 2) As Single
    Dim T
    Dim Dimensions As String
    Dim objShell As Object
    Dim objDossier As Object
    Dim objFichier As Object

    On Error GoTo Erreur

    Dim ImageDossier As Variant
    Dim ImageFichier As Variant

    ImageFichier = Mid(Fichier, InStrRev(Fichier, "\") + 1)
    ImageDossier = Left(Fichier, Len(Fichier) - Len(ImageFichier))

    Set objShell = CreateObject("Shell.Application")

    Set objDossier = objShell.Namespace(ImageDossier)
    Set objFichier = objDossier.ParseName(ImageFichier)

    Dimensions = CStr(objFichier.ExtendedProperty("Dimensions"))
    Dimensions = Left(Dimensions, Len(Dimensions) - 1)
    Dimensions = Right(Dimensions, Len(Dimensions) - 1)

    T = Split(Dimensions, "x")

    Tbl(1) = CSng(Trim(T(0)))
    Tbl(2) = CSng(Trim(T(1)))

    DimensionsImage = Tbl()

    Set objFichier = Nothing

    Exit Function

Erreur:
    Tbl(1) = -1
    Tbl(2) = -1

    DimensionsImage = Tbl()

End Function

Re- Marie,

Salut Theze,

Bon, je suis repartie de rien pour refaire ton code, parceque je ne comprenais plus où on en était là xD

Ci-dessous le code largement testé et qui fonctionne chez moi :

Par "fonctionne" j’entends que :

  • La largeur s'ajuste automatiquement pour ne pas que l'image paraisse déformée

Je te laisse voir et revenir vers nous :p

Sub InstertImage()
Dim Hauteur As Long, Largeur As Long, NewLargeur As Long
Dim Way As String, Title As String, Ext As String
Dim Sh As Object
Dim x As Long
Way = "C:\Documents\Photos\"
Ext = ".jpg"
For x = 2 To Range("D" & Rows.Count).End(xlUp).Row
    Title = Cells(x, 4)
    Set Sh = ActiveSheet.Pictures.Insert(Way & Title & Ext)
    Hauteur = Sh.Height
    Largeur = Sh.Width
    Sh.Delete
    NewLargeur = ((78 * Largeur) / Hauteur)
    ActiveSheet.Shapes.AddPicture Filename:=Way & Title & Ext, linktofile:=msoFalse, savewithdocument:=msoTrue, Left:=Range("E" & x).Left, Top:=Range("E" & x).Top, Width:=NewLargeur, Height:=78
Next
End Sub

Restant à dispo

Bonjour,

Dans le même esprit :

Private Sub cmdDisplayPhoto_Click()

    Dim Tbl() As Single
    Dim Dossier As String
    Dim Fichier As String
    Dim Ext As String
    Dim Hauteur As Integer
    Dim Largeur As Integer
    Dim X As Long

    Dossier = "C:\Documents\Photos\"
    Ext = ".jpg"
    Hauteur = 78 'c'est la hauteur qui va définir la taille de l'image
    'Largeur = 78 si c'est la largeur qui va définir la taille de l'image

    Application.ScreenUpdating = False

    For X = 2 To Range("D" & Rows.Count).End(xlUp).Row

        Fichier = Range("D" & X)
        Range("E" & X).Value = Dossier

        Tbl = DimensionsImage(Dossier & Fichier & Ext)
        If Tbl(1) = -1 Then MsgBox "Erreur sur la photo '" & Dossier & Fichier & Ext & "' !": Exit Sub

        'Tbl(1) = largeur, Tbl(2) = hauteur
        Largeur = Tbl(1) / (Tbl(2) / Hauteur) '<--- la largeur de la photo est rammenée au même rapport que la hauteur
        'Hauteur = Tbl(2) / (Tbl(1) / Largeur) '<--- si c'est la largeur qui doit fixer la taille de l'image

        ActiveSheet.Shapes.AddPicture mydir & RegieNumber & T, msoFalse, msoTrue, Range("E" & X).Left, Range("E" & X).Top, Largeur, Hauteur

    Next X

End Sub

je ne re-poste pas la fonction qui reste inchangée !

Cher Juice,

Je suis impressionnée par ta nouvelle formule, qui marche (presque) parfaitement.

Donc les photos maintenant s'affichent bien :

  • en hauteur 78,
  • en largeur variable, ce qui fait qu'elles ne sont pas déformées,
  • automatiquement pour toutes les cellules, ce qui est le but de la manœuvre.

Sauf que le programme s'arrête dès qu'il y a une photo manquante : il affiche toutes les photos au-dessus et aucune au-dessous.

Et il indique le message suivant : "Erreur d'exécution 1004 : impossible de lire la propriété Insert de la classe Pictures"

Quand je clique sur Débogage, la ligne suivante est surlignée :

Set Sh = ActiveSheet.Pictures.Insert(Way & Title & Ext)

Je suis sûre que tu as la solution.

Merci, merci, merci mille fois encore, c'est déjà formidable.

Marie

Marie,

Ah oui j'ai zappé de te remettre ton gestionnaire d'erreur.

Je te fais sa et je reviens vers toi !

A toute ;D

Re-

Est-ce que tu veux absolument un message d'erreur si l'image n'existe pas ?

Parce que la méthode que tu a de base [...]

On Error GoTo errormessage:

errormessage:
If Err.Number = 1004 Then
MsgBox "File does not exist" & vbCrLf & "Check of the RegieNumber !"

[...] ne fonctionne pas avec mon code, alors qu'une simple ligne : On Error Resume Next permet d'extraire toute les images d'un coup.

Nouveau code avec gestion de l'erreur :

Sub InstertImage()
Dim Hauteur As Long, Largeur As Long, NewLargeur As Long
Dim Way As String, Title As String, Ext As String
Dim Sh As Object
Dim x As Long
Way = "C:\Documents\Photos\"
Ext = ".jpg"
For x = 2 To Range("D" & Rows.Count).End(xlUp).Row
    Title = Cells(x, 4)
    On Error Resume Next
    Set Sh = ActiveSheet.Pictures.Insert(Way & Title & Ext)
    Hauteur = Sh.Height
    Largeur = Sh.Width
    Sh.Delete
    NewLargeur = ((78 * Largeur) / Hauteur)
    ActiveSheet.Shapes.AddPicture Filename:=Way & Title & Ext, linktofile:=msoFalse, savewithdocument:=msoTrue, Left:=Range("E" & x).Left, Top:=Range("E" & x).Top, Width:=NewLargeur, Height:=78
Next
End Sub

Restant à ta dispo si sa conviens pas

Cher Juice,

Bon ben je crois que là on est bons.... Ça marche !!!!

Et ça marche super bien même.

Mille mercis encore à toi et à tous ceux qui ont aidé.

Vous n'imaginez pas comme ça va me rendre service ce programme !

Vous êtes super forts !

Bonne journée et peut être à bientôt,

Marie

Rechercher des sujets similaires à "macro 2010 inserer automatiquement images deformation"