Peut‑on saisir une « commande » dans une cellule Excel pour aller lire une valeur dans SAP ? Pas directement. Voici des méthodes fiables pour déclencher, depuis une feuille, une requête vers SAP et rapatrier le résultat : VBA avec SAP GUI Scripting, ou Power Query via API.
Extraire des données SAP dans Excel à partir d’une cellule
Vue d’ensemble de la question
L’utilisateur demande s’il est possible d’inscrire une « commande de cellule » dans Excel (par exemple une formule) afin d’interroger SAP et d’afficher la réponse immédiatement dans la feuille, sans export ni copier‑coller. En clair : peut‑on écrire quelque chose comme =SAP("MM03";A2;"MARA-MTART")
qui ira chercher la donnée dans SAP et renverra la valeur ?
La réponse courte est : il n’existe aucune formule Excel native qui interroge SAP directement. En revanche, on peut parfaitement atteindre ce résultat de deux façons principales :
- Automatiser SAP GUI depuis Excel avec VBA (SAP GUI Scripting) pour piloter une transaction et récupérer une valeur.
- Interroger SAP sans GUI via des API (BAPI/RFC/OData) et Power Query, puis renvoyer la donnée dans une cellule.
Réponse & solution
Aucune fonction Excel native ne lit directement SAP
Excel ne propose pas de champ ni de formule du type =SAP("…")
. Pour déclencher une requête SAP depuis la feuille et ramener un résultat dans une cellule, il faut passer par un script ou un connecteur.
Utiliser l’API SAP GUI Scripting via VBA
Si vous travaillez avec SAP GUI (WinGUI), SAP GUI Scripting permet à Excel/VBA de piloter la fenêtre SAP comme le ferait un utilisateur : ouvrir une transaction, renseigner les champs, exécuter, lire l’écran et rapatrier la valeur obtenue.
Prérequis côté client
- Activer le scripting dans SAP Logon : SAP Logon ▸ Options ▸ SAP GUI ▸ Scripting ▸ Enable scripting.
- Installer SAP GUI pour Windows et vous assurer que vous pouvez ouvrir votre système SAP manuellement.
Prérequis côté serveur
- Le paramètre
sapgui/user_scripting
doit être activé par l’équipe Basis/IT sur l’instance SAP ciblée. - Votre rôle SAP doit autoriser la transaction et les objets consultés.
Principe de la macro
- Excel récupère la valeur à interroger (ex. un numéro de matériau en A2).
- VBA bascule sur une session SAP ouverte (ou en ouvre une), lance la transaction (ex. MM03), renseigne les champs et exécute.
- VBA lit l’écran ou la grille ALV, extrait la donnée voulue et la colle dans la cellule cible (ex. B2).
Exemple minimal
'Module standard
Option Explicit
Sub LireDepuisSAP()
Dim SapGui As Object, app As Object, conn As Object, sess As Object
```
'Récupérer la session SAP existante (WinGUI)
Set SapGui = GetObject("SAPGUI")
Set app = SapGui.GetScriptingEngine
Set conn = app.Children(0) 'Première connexion ouverte
Set sess = conn.Children(0) 'Première session de la connexion
With sess
.StartTransaction "MM03"
.findById("wnd[0]/usr/ctxtRM_MATNR-LOW").Text = Range("A2").Value
.findById("wnd[0]/tbar[1]/btn[8]").Press 'Exécuter (F8)
'Exemple : lire un champ (adapter l’identifiant à votre écran)
Range("B2").Value = .findById("wnd[0]/usr/tblSAPLMGMMTC_VIEW_TAB/ctxtMARA-MATNR[1,0]").Text
.findById("wnd[0]/tbar[0]/btn[12]").Press 'Fermer
End With
```
End Sub
Ce fragment illustre le concept ; dans un fichier de production, ajoutez la gestion d’erreur et des “attentes actives” pour éviter toute course entre Excel et l’interface SAP.
Bonnes pratiques
Point | Pourquoi / Comment |
---|---|
Droits | Le scripting doit être activé côté serveur ; vos rôles SAP doivent autoriser la transaction et les données consultées. |
Stabilité | Testez l’existence de chaque contrôle (findById ). Attendez la fin du chargement (Busy , Info.IsLowSpeedConnection ) avant toute action. |
Sécurité | Ne stockez jamais de mots de passe en dur. Privilégiez le SSO ou l’ouverture manuelle de la session. |
Maintenance | Centralisez les identifiants d’objets SAP dans des constantes ou un onglet “Config”. Un changement d’écran n’impliquera qu’une mise à jour. |
Alternatives | Pour éviter la dépendance au GUI : OData/BAPI+Power Query, SAP Analysis for Office, ou connecteurs BW. |
Limites
- Dépend fortement de la version SAP GUI et de la disposition des écrans (IDs d’objets).
- Non recommandé pour des robots 24/7 ; préférez BAPI/RFC/OData pour les usages critiques ou volumétriques.
- Monothread : éviter d’exécuter plusieurs macros SAP simultanément sur un même poste.
Modèle de macro robuste (événements + sécurité + journalisation)
Le besoin initial consiste à déclencher la lecture depuis une cellule. Une formule UDF n’est pas adaptée (les UDF ne doivent pas déclencher d’UI ni d’accès système). La bonne pratique est d’utiliser un événement de feuille : à chaque modification d’une cellule d’entrée, la macro lit SAP et met à jour la cellule de sortie.
Architecture suggérée
- Feuille “Saisie” : colonne A = intrant (ex. numéros de matériaux), colonne B = valeur renvoyée.
- Module “modSAP” : fonctions utilitaires (obtention de session, attente, tests d’existence).
- Module “modMM03” : logique métier (navigation, extraction des valeurs).
- Événement
Worksheet_Change
: déclenche l’appel quand A2:A1000 est modifié.
Utilitaires génériques
'modSAP – utilitaires
Option Explicit
Public Function GetSession() As Object
'Retourne la première session SAP disponible
Dim SapGui As Object, app As Object
On Error GoTo EH
```
Set SapGui = GetObject("SAPGUI")
Set app = SapGui.GetScriptingEngine
If app.Connections.Count = 0 Then
Err.Raise vbObjectError + 1, "GetSession", "Aucune connexion SAP n’est ouverte."
End If
If app.Connections(0).Sessions.Count = 0 Then
Err.Raise vbObjectError + 2, "GetSession", "Aucune session SAP active."
End If
Set GetSession = app.Connections(0).Sessions(0)
Exit Function
```
EH:
Err.Raise Err.Number, Err.Source, "SAP GUI non disponible ou scripting inactif. " & Err.Description
End Function
Public Sub WaitReady(ByVal sess As Object, Optional ByVal timeoutMs As Long = 15000)
Dim t As Single: t = Timer
Do While sess.Busy Or sess.Info.IsLowSpeedConnection
DoEvents
If (Timer - t) * 1000& > timeoutMs Then Err.Raise vbObjectError + 3, "WaitReady", "Délai dépassé"
Loop
End Sub
Public Function ExistsById(ByVal sess As Object, ByVal id As String) As Boolean
On Error Resume Next
Dim o As Object: Set o = sess.FindById(id)
ExistsById = Not o Is Nothing
On Error GoTo 0
End Function
Public Sub EnsureOnScreen(ByVal sess As Object, ByVal id As String)
If Not ExistsById(sess, id) Then Err.Raise vbObjectError + 4, "EnsureOnScreen", "Contrôle introuvable : " & id
End Sub
Lecture d’un matériau avec MM03 (valeur simple)
'modMM03 – logique métier
Option Explicit
Public Function MM03_ReadMaterial(ByVal matnr As String) As String
Dim s As Object
Set s = GetSession()
```
Call WaitReady(s)
s.StartTransaction "MM03"
Call WaitReady(s)
s.findById("wnd[0]/usr/ctxtRM_MATNR-LOW").Text = matnr
s.findById("wnd[0]/tbar[1]/btn[8]").Press 'Exécuter
Call WaitReady(s)
'Exemple : lecture d’une valeur (adapter l’ID à votre écran)
Dim idVal As String
idVal = "wnd[0]/usr/txtMARA-MTART" 'Type de matériau, p.ex.
If Not ExistsById(s, idVal) Then
'Alternative : lecture depuis une table/grille
idVal = "wnd[0]/usr/tblSAPLMGMMTC_VIEW_TAB/ctxtMARA-MATNR[1,0]"
End If
Call EnsureOnScreen(s, idVal)
MM03_ReadMaterial = s.findById(idVal).Text
'Retour à l’écran initial
If ExistsById(s, "wnd[0]/tbar[0]/btn[12]") Then s.findById("wnd[0]/tbar[0]/btn[12]").Press
```
End Function
Déclenchement depuis la cellule (événement de feuille)
Placez ce code dans le module de votre feuille (ex. Feuil1 (Saisie)) : il écoute les modifications de A2:A1000, interroge SAP et écrit la valeur en colonne B.
'Feuille "Saisie"
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo EH
Dim zone As Range
Set zone = Application.Intersect(Target, Me.Range("A2:A1000"))
If zone Is Nothing Then Exit Sub
```
Application.EnableEvents = False
Application.ScreenUpdating = False
Dim c As Range
For Each c In zone.Cells
If Len(c.Value2) > 0 Then
Dim val As String
val = MM03_ReadMaterial(CStr(c.Value2))
c.Offset(0, 1).Value = val
Else
c.Offset(0, 1).ClearContents
End If
Next c
```
Leave:
Application.EnableEvents = True
Application.ScreenUpdating = True
Exit Sub
EH:
Me.Range("B1").Value = "Erreur : " & Err.Description
Resume Leave
End Sub
Résultat : l’utilisateur saisit (ou colle) un ou plusieurs codes matériaux en colonne A ; Excel interroge SAP et pose automatiquement le résultat en colonne B. On obtient ainsi le comportement “commande de cellule” sans recourir à une UDF.
Lecture d’une grille ALV (GetCellValue)
Beaucoup de transactions renvoient des tableaux ALV. La lecture se fait depuis l’objet GuiGridView
du conteneur :
Public Function ReadALVCell(ByVal sess As Object, ByVal fieldName As String, ByVal rowIndex As Long) As String
Dim grid As Object
Set grid = sess.findById("wnd[0]/usr/cntlGRID1/shellcont/shell")
ReadALVCell = grid.GetCellValue(rowIndex, fieldName)
End Function
Remarques :
- L’ID exact du contrôle varie :
cntlGRID1
,shellcont[1]/shell
,usr/shell
… Utilisez l’enregistreur de scripts (ALT+F12) pour capturer la hiérarchie. - On peut itérer sur toutes les lignes avec
grid.RowCount
et trouver la première occurrence d’un critère.
Boucle sur une liste (traitement de masse)
Sub MM03_LireListe()
Dim s As Object: Set s = GetSession()
Dim lastRow As Long: lastRow = Cells(Rows.Count, "A").End(xlUp).Row
Dim i As Long, mat As String
```
For i = 2 To lastRow
mat = Trim(CStr(Cells(i, "A").Value))
If mat <> "" Then
Cells(i, "B").Value = MM03_ReadMaterial(mat)
DoEvents
End If
Next i
```
End Sub
Si vous devez lire des centaines ou milliers de clés, sachez que piloter le GUI en boucle est lent. Pour le volume, préférez un BAPI ou la transaction MM17 (ou un extract BW) selon le besoin.
Activer rapidement le scripting et trouver les IDs
- Console / enregistreur de scripts : ALT+F12 dans SAP GUI, puis enregistrez un parcours. Les lignes générées dévoilent les
findById
et simplifient l’écriture de la macro. - Stratégie d’IDs robuste : centralisez les IDs dans un module de constantes ou un onglet de configuration, avec commentaires et date de capture.
Alternative : OData / BAPI + Power Query (sans GUI)
Quand le scripting n’est pas autorisé ou qu’il faut des flux stables, utilisez un accès programmatique : BAPI/RFC (via passerelle) ou OData exposé par SAP Gateway/S4. Dans Excel :
- Obtenir l’URL d’un service OData/BAPI publié par l’IT (avec votre compte autorisé).
- Dans Excel : Données ▸ Récupérer des données ▸ À partir d’un flux OData.
- Se connecter (SSO/Basic/OAuth selon la configuration), sélectionner l’entité (ex. matériaux) et filtrer sur la clé (
$filter=Material eq 'A2'
). - Charger en Connexion uniquement, puis utiliser XLOOKUP / INDEX/EQUIV pour faire correspondre vos numéros en feuille et les valeurs du flux.
Avantages : rafraîchissable, traçable, sans dépendance au rendu des écrans. Inconvénients : nécessite un service exposé et des autorisations spécifiques. Pour BW/BI, des connecteurs dédiés (Analysis for Office, connecteur BW dans Power Query) facilitent les extractions de cubes.
Comparatif des approches
Approche | Points forts | Points à surveiller | Cas d’usage idéal |
---|---|---|---|
VBA + SAP GUI Scripting | Rapide à mettre en œuvre, ne nécessite pas d’API publiée, proche du geste utilisateur. | Dépend de l’UI, fragile si les écrans changent, monothread, non adapté 24/7. | Prototypage, petites séries, automatiser une simple lecture ponctuelle. |
Power Query + OData/BAPI | Stable, gouverné, sans GUI, rafraîchissable, adapté au volume. | Nécessite un service exposé et des autorisations ; conception initiale. | Tableaux de bord, rafraîchissement régulier, grands volumes et traçabilité. |
FAQ
Peut‑on appeler SAP depuis une formule Excel (UDF) ?
Techniquement, vous pourriez créer une UDF en VBA, mais c’est déconseillé : les UDF sont censées être pures (sans effets de bord, ni UI, ni accès système). Utilisez plutôt l’événement Worksheet_Change
ou un bouton/macro assigné.
Faut‑il ouvrir SAP Logon manuellement ?
C’est la méthode la plus simple. Ouvrir SAP par script est possible, mais le chemin de saplogon.exe
varie selon les postes. En pratique, on détecte d’abord une session ouverte via GetObject("SAPGUI")
.
Et si l’écran attendu n’apparaît pas ?
Contrôlez sess.Busy
, utilisez des timeouts, et encapsulez chaque findById
dans un test d’existence. Journalisez les erreurs en haut de la feuille pour que l’utilisateur sache quoi corriger.
Comment faire “en masse” ?
Évitez la boucle GUI pour des milliers de lignes : préférez MM17, un BAPI, ou un extrait BW. Vous gagnerez énormément de temps et de stabilité.
Check‑list de mise en production
Élément | Vérification | Responsable |
---|---|---|
Scripting client | Case “Enable scripting” cochée | Utilisateur / IT poste |
Paramètre serveur | sapgui/user_scripting actif | Basis |
Autorisations | Transactions et objets consultés autorisés | Sécurité/Rôles |
Stabilité IDs | IDs centralisés et commentés | Développeur |
Journalisation | Cellule d’état (ex. B1) affiche les erreurs | Développeur |
Plan B volumétrie | Service OData/BAPI ou BW disponible | IT/Basis |
Dépannage (erreurs fréquentes)
Symptôme | Cause probable | Correctif |
---|---|---|
Object variable or With block variable not set | Aucune session SAP ouverte | Ouvrir SAP Logon et se connecter, ou renforcer GetSession avec messages clairs. |
Permission denied / scripting inactive | Paramètre serveur désactivé | Demander l’activation de sapgui/user_scripting (en lecture seule si nécessaire). |
Contrôle introuvable | Changement d’écran / ID différent | Re‑capturer l’ID avec l’enregistreur (ALT+F12) et mettre à jour l’onglet “Config”. |
Valeurs incohérentes | Synchronisation trop rapide | Utiliser WaitReady après chaque action, éviter les pauses “magiques”. |
Lent en traitement de masse | GUI piloté boucle par boucle | Passer sur OData/BAPI, MM17, ou un extract BW. |
Exemples prêts à l’emploi
Procédure simple assignée à un bouton
Sub LireA2VersB2()
On Error GoTo EH
Dim mat As String: mat = Trim$(Range("A2").Value2)
If mat = "" Then Err.Raise vbObjectError + 10, , "A2 est vide."
Range("B2").Value = MM03_ReadMaterial(mat)
Exit Sub
EH:
Range("B1").Value = "Erreur : " & Err.Description
End Sub
Journal de traces (facultatif)
Sub LogMsg(ByVal msg As String)
With Sheets("Saisie")
.Range("D1").Value = Now
.Range("D2").Value = msg
End With
End Sub
Information complémentaire utile
- Pour tester rapidement vos séquences, utilisez l’enregistreur de scripts : ALT+F12 dans SAP GUI ouvre la console de scripting.
- Évitez l’exécution simultanée de plusieurs macros SAP sur un même poste ; SAP GUI Scripting est monothread.
- Si vous devez écrire une centaine de lectures, regroupez les matériaux dans un fichier texte et utilisez la transaction MM17 ou un BAPI pour obtenir les données en masse ; vous gagnerez du temps par rapport à une boucle VBA unitaire.
Modèle de sécurité & conformité
- Identifiants : n’écrivez jamais vos mots de passe dans le code. Préférez SSO ou invite manuelle.
- Traçabilité : journalisez les lectures sensibles (qui, quoi, quand) selon les politiques internes.
- Mises à jour : documentez la version du script, de SAP GUI, et des écrans capturés.
Performance & fiabilité
- Réduisez ScreenUpdating et les événements pendant l’exécution.
- Regroupez les écritures en bloc (écrire un tableau VBA dans la feuille plutôt que cellule par cellule).
- Prévoyez des timeouts et des messages utilisateurs explicites en haut de la feuille.
Conclusion
On ne peut pas écrire une formule Excel miracle pour lire directement SAP, mais on peut recréer l’expérience : saisir une clé en cellule déclenche un VBA pilotant SAP GUI, ou une requête Power Query vers des API SAP. La première méthode est rapide et pratique pour des usages ponctuels ; la seconde est la référence pour les intégrations pérennes et volumétriques. En appliquant les bonnes pratiques ci‑dessus (droits, stabilité des findById
, sécurité, alternatives API), vous obtiendrez une solution fiable, maintenable et adaptée à votre contexte d’entreprise.