Je teste actuellement la mise en place d’un PIM pour gérer notre bibliothèque de médias et les informations produits. L’idée est de centraliser l’information et la rendre accessible au plus grand nombre au travers d’un navigateur mais aussi pour d’autres applications. Dans cet article je vous expliquerais comment procéder pour récupérer ces informations depuis Excel en utilisant l’API d’Akeneo et Flyimg-Akeneo.
Je pars principe que vous savez ce qu’est un PIM, que vous connaissez la solution proposé par Akeneo, que vous connaissez Docker.
Je remercie l’équipe d’Akeneo qui m’a orienté sur les bonnes pistes et je précise que je ne suis pas un expert en VBA.
Pré-requis
- Une instance Akeneo fonctionnelle comportant un catalogue avec quelques produits;
- La possibilité de créer un container Docker pour Flyimg et Traefik activé (marche sans mais vous devrez exposer/mapper le port 80 de votre container);
- Excel avec quelques librairies que nous ajouterons plus tard.
Activer l’API
Connectez-vous en tant qu’administrateur ou bien avec un compte ayant les droits administrateurs. Allez sur la page Système > Connexions API. Créer une autorisation spécifique pour VBA, ensuite attribuez à un groupe dédié afin de gérer les habilitations. Pour mes tests j’ai utilisé le compte administrateur.

Création du container Flyimg-Akeneo
Flyimg-Akeneo est un fork de Flyimg dont le rôle est de générer à la demande la déclinaison d’une image source. Il est possible de redimensionner l’image, la faire pivoter, « croper » l’image et bien d’autres choses que je vous laisse découvrir sur le site de Flyimg (https://github.com/flyimg).
Connectez-vous à votre serveur Docker et télécharger la dernière version sur le dépôt Github (https://github.com/opengento/flyimg-akeneo).
Modifier le fichier config/parameters.yml
akeneo_api: base_url: "http://192.168.xxx.xxx" client_id: "1_xxxxx" client_secret: "1xxxx" user: "admin" password: "admin"
base_url : correspond à votre serveur Akeneo
client_id et client_secret correspond aux valeurs que vous avez généré sur la page Système > Connexions API d’Akeneo.
user et password correspond à l’utilisateur faisant partie du groupe autorisé à utiliser cette clé d’API.
Construisez votre image avec la commande
docker build –t flyimg-akeneo --label flyimg-akeneo
Créer votre container avec les labels permettant à Traefik de faire le mappage de port vers le 80. Connectez vous en shell à votre container et lancez la commande
composer install
FlyImg va s’installer en quelques minutes. Une fois fini lancez votre navigateur et essayez de vous connecter à votre container. Si tout se passe bien vous arrivez à une page sur fond gris.

Excel et VBA
Avant d’aller plus loin vous allez avoir besoin du module VBA-Json disponible ici (https://github.com/VBA-tools/VBA-JSON). Dans l’éditeur VBA ajoutez ce module à votre projet et activez la référence « Microsoft Scripting Runtime ».
Commencé par créer un UserForm que vous nommerez : FmOptionsImportImage sur lequel vous ajouterez :
- Une liste déroulante nommée : LsTaille;
- Trois champs texte nommés : TxtLigneRecherche, TxtColonneRecherche, TxtColonneImage;
- Deux boutons : BtValide et BtAnnuler.
Double cliquez sur le bouton « BtValide » et collez ce code
' Quitte le programme
Private Sub BtAnnuler_Click()
Unload Me
End Sub
' Appel de la procédure d'import
Private Sub BtValide_Click()
' Appel de la procédure d'import
Call getRoot(LigRech, ColRech, ColAct)
End Sub
' Charge la liste déroulante
Private Sub UserForm_Activate()
FmOptionsImportImage.LsTaille.AddItem ("50 px")
FmOptionsImportImage.LsTaille.AddItem ("60 px")
FmOptionsImportImage.LsTaille.AddItem ("70 px")
FmOptionsImportImage.LsTaille.AddItem ("80 px")
FmOptionsImportImage.LsTaille.AddItem ("100 px")
FmOptionsImportImage.LsTaille.AddItem ("110 px")
FmOptionsImportImage.LsTaille.AddItem ("120 px")
FmOptionsImportImage.LsTaille.AddItem ("150 px")
End Sub
Créer un module nommez “importImage” et collez tout ce code
'Option Explicit
Public Product, Token As Object
Public strUrl, ColRech, ColAct As String
Public LigRech, CellHeight, imgWidth As Integer
' Encode client_id et secret en base64
' ne marche pas pour le moment
Function EncodeBase64(text As String) As String
Dim arrData() As Byte
arrData = StrConv(text, vbFromUnicode)
Dim objXML As MSXML2.DOMDocument
Dim objNode As MSXML2.IXMLDOMElement
Set objXML = New MSXML2.DOMDocument
Set objNode = objXML.createElement("b64")
objNode.DataType = "bin.base64"
objNode.nodeTypedValue = arrData
EncodeBase64 = objNode.text
Set objNode = Nothing
Set objXML = Nothing
End Function
' Connexion et création du token Akeneo
Sub ConnectAuth()
Dim objRequest, scriptControl As Object
Dim client_id, secret As String
client_id = "1_xxxx"
secret = "1xxxx"
strUrl = "http://192.168.xxx.xxxx"
Set scriptControl = CreateObject("MSScriptControl.ScriptControl")
scriptControl.Language = "JScript"
Set objRequest = CreateObject("MSXML2.XMLHTTP")
With objRequest
.Open "POST", strUrl & "/api/oauth/v1/token", False
.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded"
' ToDo : ne marche pas en générant à la volée le base64 ?
.SetRequestHeader "Authorization", "Basic EncodeBase64"
.Send "grant_type=password&username=admin&password=admin"
Set Token = scriptControl.Eval("(" & .responseText & ")")
End With
End Sub
' Stockage de la largeur de l'image
' et conserve la plus grande
Sub upWidth(imgNewWidth)
If (imgNewWidth > imgWidth) Then
imgWidth = imgNewWidth
End If
End Sub
' Gestion des erreurs json
Sub getError(Code, Message)
Dim pErreur As String
pErreur = CStr(Code)
If (pErreur = 404) Then
MsgBox ("Erreur " & Code & " : " & Message)
Else
MsgBox ("Erreur inconnue")
End If
End Sub
' Récupération de l'objet Product
' Itmref : sku du produit à chercher
Sub getProduct(Itmref)
Dim objRequest As Object
Set objRequest = CreateObject("MSXML2.XMLHTTP")
With objRequest
.Open "GET", strUrl & "/api/rest/v1/products/" & Itmref, False
.SetRequestHeader "Content-Type", "application/json"
.SetRequestHeader "Authorization", "Bearer " & Token.access_token
.Send
Set Product = JsonConverter.ParseJson(.responseText)
End With
End Sub
' Transformation de l'image akeneo par
' flyimg-akeneo
Sub getPicture(ImgHeight)
If (Product("values").Exists("img_0")) Then ‘ Changer img_0 par le nom du champ qui représente l’image que vous voulez insérer
Set img = ActiveSheet.Pictures.Insert("http://AdresseDuServeurFlyImg/upload/st_1,h_" & ImgHeight & "/" & Product("values")("img_0")(1)("data"))
img.Top = ActiveCell.Top + 2
img.Left = ActiveCell.Left + 2
img.Placement = 2
img.PrintObject = 1
' Mise à jour de la largeur de la cellule
Call upWidth(img.Width)
End If
End Sub
Sub getRoot(LigRech, ColRech, ColAct)
Dim ImgHeight As Integer
imgWidth = 0
' Dimension de la cellule
' hauteur de cellule
' 50 -> 50 px
' 60 -> 60 px
' 70 -> 70 px
' 81 -> 80 px
' 100 -> 100 px
' 110 -> 110 px
' 120 -> 120 px
' 150 -> 150 px
' Largeur de la celulle
' 9 -> 50 px
' 11 -> 60 px
' 13 -> 70 px
' 15 -> 80 px
' 19 -> 100 px
' 21 -> 110 px
' 23 -> 120 px
' 28 -> 150 px
Select Case FmOptionsImportImage.LsTaille.List(FmOptionsImportImage.LsTaille.ListIndex)
Case "50 px" To "50 px"
CellHeight = 50 ' hauteur de cellule
ImgHeight = 50
'ImgWidth = 50
Case "60 px" To "60 px"
CellHeight = 60 ' hauteur de cellule
ImgHeight = 60
'ImgWidth = 60
Case "70 px" To "70 px"
CellHeight = 70 ' hauteur de cellule
ImgHeight = 70
'ImgWidth = 70
Case "80 px" To "80 px"
CellHeight = 80 ' hauteur de cellule
ImgHeight = 80
'ImgWidth = 80
Case "100 px" To "100 px"
CellHeight = 100 ' hauteur de cellule
ImgHeight = 100
'ImgWidth = 100
Case "110 px" To "110 px"
CellHeight = 110 ' hauteur de cellule
ImgHeight = 110
'ImgWidth = 110
Case "120 px" To "120 px"
CellHeight = 120 ' hauteur de cellule
ImgHeight = 120
'ImgWidth = 120
Case "150 px" To "150 px"
CellHeight = 150 ' hauteur de cellule
ImgHeight = 150
'ImgWidth = 150
Case "" To ""
MsgBox ("Vous devez choisir une taille d'images")
End Select
' Ligne à laquelle commencer la recherche
If LigRech = 0 Then
LigRech = FmOptionsImportImage.TxtLigneRecherche.Value
If LigRech = "" Then Exit Sub
End If
' Colonne de recherche.
If ColRech = "" Then
ColRech = FmOptionsImportImage.TxtColonneRecherche.Value
If ColRech = "" Then Exit Sub
End If
' Colonne d'affichage
If ColAct = "" Then
ColAct = FmOptionsImportImage.TxtColonneImage.Value
If ColAct = "" Then Exit Sub
End If
' Connexion et récupération du Token
Call ConnectAuth
Range(ColRech & LigRech).Select
For i = 1 To Range("A" & "65535").End(xlUp).Row
If (Range(ColRech & i).Value <> "") Then
' Récupération des informations produit
Call getProduct(Range(ColRech & i).Value)
If (CStr(Product.Exists("code"))) Then
Call getError(Product("code"), Product("message"))
Else
Range(ColAct & i).Select
ActiveCell.EntireRow.RowHeight = CellHeight
Call getPicture(ImgHeight)
End If
End If
Next i
' Ajuste la largeur de la colonne avec
' la largeur de l'image la plus grande
' 4.75 permet la convertion de pixel à points... en gros
ActiveCell.EntireColumn.ColumnWidth = (imgWidth / 4.75) + 0.5
FmOptionsImportImage.BtValide.Visible = False
FmOptionsImportImage.BtAnnuler.Caption = "Quitter"
End Sub
Avant de lancer le programme vous devez modifier dans la fonction ConnectAuth() les variables client_id, secret, strUrl.
Normalement le programme est censé réaliser l'encodage en base64 automatiquement mais pour une raison que je ne connais pas cela ne marche pas (encore), du coups vous allez devoir le faire à la main. Allez sur le site https://www.base64decode.org/ copier/coller les valeurs client_id et secret mais attention sous cette forme
client_id:secret
ne pas oublier le : de séparateur. Ensuite coller le résultat dans la fonction ConnectAuth à la ligne
.SetRequestHeader "Authorization", "Basic VotreEncodageBase64"
Dans la fonction getPicture l'adresse de votre serveur FlyImg est à modifier et le nom du champ contenant le chemin d'accès à l'image (dans mon cas img_0)
If (Product("values").Exists("img_0")) Then
[...]
Set img = ActiveSheet.Pictures.Insert("http://AdresseDuServeurFlyImg/upload/st_1,h_" & ImgHeight & "/" & Product("values")("img_0")(1)("data"))
Test
Dans votre projet VBA, sur la Feuil1, dans la colonne de votre choix saisissez un sku par ligne et lancez le programme en lancant la feuille FmOptionsImportImage. Renseignez les valeurs de taille et dans quelle colonne mettre les images et cliquez sur le bouton "Insérer".
Si tout ce passe bien les images devraient être insérée sur la ligne correspondante au sku et au dimenssion que vous avez séléctionné.
Evolution
Dans le cas où il y a plusieurs images disponible, ouvrir une fenêtre pour permettre à l'utilisateur de sélectionner l'image qu'il souhaite importer.