8809x
001738
09.06.2025

Tutoriel service Web et API en VBA

Le service Web est une communication entre machines ou programmes. Cette communication est fournie via le réseau et peut donc être utilisée par tout programme capable d'envoyer et de recevoir des chaînes via le protocole HTTP. RFEM 6 et RSTAB 9 offrent une interface basée sur ces services Web multiplateformes. Ce tutoriel vise à montrer les fondamentaux en utilisant le langage de programmation VBA.

Bases de l’API service Web avec l’exemple de VBA

Pour le formatage de la chaîne de caractères, le format XML est utilisé selon les spécifications du protocole SOAP. L’exemple suivant sert de référence :


    <Body>
        
    </Body>

Un élément typique du formatage XML est le début d’une section par le caractère « < ». Un identifiant vient ensuite et, si aucun autre élément subordonné ne suit, la section est terminée par "/>". Un exemple est la troisième ligne :

Lorsqu’il y a des sous-éléments, la section commence par « < », la commande et « > » et se termine par "</", la commande et ">". L’exemple approprié est la section « Body » :

<Body>
    
</Body>

Le formatage avec espaces et sauts de ligne sert uniquement d'illustration ici. Il n’est pas requis pour le transfert. Les éléments « Body » et « Envelope » sont des éléments standards pour le transfert et sont utilisés pour chaque commande.

Toutes les commandes disponibles peuvent être lues à l’aide de l’interface WSDL. Il existe des logiciels permettant de générer des listes à partir de ces informations. Un tel logiciel est SoapUI, par exemple. Pour l’API de RFEM 6, il existe deux listes : les commandes pour l’application et celles pour le modèle. Les deux listes peuvent être téléchargées à la fin de cet article.

Comme les commandes sont envoyées via HTTP, des adresses URL sont nécessaires pour les appeler. L’adresse standard des applications RSTAB/RFEM est « localhost:8081 » et peut être modifiée dans les paramètres du programme.


Les modèles ouverts reçoivent des adresses croissantes, de sorte que le premier modèle ouvert a l’adresse « localhost:8082 ».

Pour obtenir l’adresse du modèle actif, la commande « get_active_model » est envoyée. Une réponse correspondante de RFEM 6 ressemble à ceci :


    
        
            
                http://127.0.0.1:8082/
            
        
    

Les détails supplémentaires de la section « Envelope » (français : enveloppe) ainsi que la ligne précédant "<?xml version="1.0"?>" sont destinés à montrer les standards utilisés et ne seront pas abordés ici. On peut constater qu’à nouveau, les éléments « Envelope » et « Body » sont utilisés. À l’intérieur de « Body », la réponse de RFEM 6 est contenue par le nom de la commande "get_active_model" et le mot "Response" ajouté. Le contenu de cette réponse est une valeur ("value"), à savoir l'adresse du modèle actif. De plus, RFEM est maintenant verrouillé pour d’autres accès.

Dans l’exemple suivant, une barre avec deux appuis nodaux et une charge doit être créée. Pour pouvoir communiquer avec RFEM via VBA, les objets suivants sont nécessaires :

request As MSXML2.XMLHTTP60
response As MSXML2.DOMDocument

L’objet XMLHTTP60 a une fonction intégrée pour envoyer une requête HTTP à une URL et est donc utilisé pour la demande. La réponse peut ensuite être évaluée à l’aide du DOMDocument. L’exemple suivant réunit la requête « get_active_model » déjà montrée avec les commandes utilisées sous VBA :

'   get active model url with "get_active_model" command
str_envelope = 
    "" & _
    "   <Body>" & _
    "       " & _
    "   </Body>" & _
    ""

'   open request and send it
request.Open "Post", "http://localhost:8081/", False
request.Send (str_envelope)

'   get response and transform it to an xml-object
response.LoadXML (request.responseText)

Tout d’abord, la requête au format XML est stockée dans la variable "str_envelope" et la méthode "Open" de la variable "request" ouvre la requête à RFEM. La méthode "Send" peut maintenant envoyer le contenu de la variable "str_envelope". La réponse peut ensuite être obtenue par la méthode "ResponseText". Dans ce cas concret, elle est directement lue par la méthode "LoadXML" de la variable "response".

La variable "response" de type DOMDocuments a la méthode LoadXML et peut ainsi reconnaître la mise en forme XML. L'avantage est que le type DOMDocuments fournit également la méthode GetElementsByTagName. Cela permet d'extraire directement des éléments du code. Dans ce qui suit, le code précédent est étendu pour que l'adresse URL du modèle soit disponible :

'   get http-status
status = request.status
If status <> "200" Then
    MsgBox "get_active_model: Sending not successful - " & response.Text
    Exit Sub
End If

url_model = response.GetElementsByTagName("value")(0).Text

Avant que l'URL ne soit lue, le statut de la réponse peut encore être vérifié. Il s'agit de codes d'état HTTP standardisés. Le statut "200" signifie que le transfert était "OK". Après cette vérification, la chaîne de caractères url_model enregistre l'URL du modèle. Pour cela, l'élément "value" est recherché dans la réponse XML. Si une réponse contient plusieurs éléments, toutes les valeurs à l'intérieur de la section "value" sont stockées, de sorte qu'il n'est pas possible d'évaluer ici avec l'identifiant "value", mais il faut adresser les sous-éléments de "value". Plus d'informations dans l'exemple pratique. En cas d'adresse du modèle, la seule valeur retournée est l'URL, de sorte que "value" est ici concluant.

Exemple pratique en VBA

Maintenant que tous les éléments de base sont connus, voici un exemple simple. Un porteur sur deux appuis doit être créé, sur lequel une charge de barre peut être appliquée.

Tout d'abord, les variables déjà présentées sont définies et initialisées :

'    define variables
Dim request As MSXML2.XMLHTTP60
Dim response As MSXML2.DOMDocument60

Dim str_envelope As String
Dim url_app As String
Dim url_model As String

'   init variables
Set request = New MSXML2.XMLHTTP60

Set response = New MSXML2.DOMDocument60
With response
    .async = False
    .preserveWhiteSpace = False
    .validateOnParse = False
    .resolveExternals = False
    '   Use full XPath functionality
    .SetProperty "SelectionLanguage", "XPath"
    '   Add specific Namespaces to work with Paths
    .SetProperty "SelectionNamespaces", "xmlns:soap=""http://www.w3.org/2003/05/soap-envelope"" " & _
                    "xmlns:xsd=""http://www.dlubal.com/rfem.xsd"" " & _
                    "xmlns:n1=""urn:schemas-microsoft-com:rowset"" " & _
                    "xmlns=""http://www.dlubal.com/rfem.xsd"" "
End With

url_app = "http://localhost:8081/"

En plus des variables "request" et "response", les chaînes de caractères "str_envelope" pour la requête et "url_app" et "url_model" pour les adresses de l'application et du modèle sont créées. Lors de l'initialisation, les spécifications connues du protocole SOAP pour l'analyse du formatage XML de la réponse peuvent être transmises. L'adresse du modèle sera récupérée plus tard, mais l'adresse de l'application doit être spécifiée. Comme mentionné précédemment, l'adresse par défaut doit être indiquée :

Dans l'étape suivante, la connexion à l'application doit être testée. Pour ce test, les informations standards de l'application sont interrogées via la commande "get_information" :

'   check application url with command "get_information"
str_envelope = "" & _
                "   " & _
                ""

'   open request and send it
request.Open "Post", url_app, False
request.Send (str_envelope)

'   get response and transform it to an xml-object
response.LoadXML (request.responseText)

'   get http-status
status = request.Status
If status <> "200" Then
    MsgBox "get_information: Sending not successful - " & response.Text
    Exit Sub
End If

'   read application information
Dim str1 As String
str1 = ""
str1 = str1 & response.GetElementsByTagName("name")(0).Text & vbLf
str1 = str1 & response.GetElementsByTagName("type")(0).Text & vbLf
str1 = str1 & response.GetElementsByTagName("version")(0).Text & vbLf
str1 = str1 & response.GetElementsByTagName("language_name")(0).Text & vbLf
str1 = str1 & response.GetElementsByTagName("language_id")(0).Text

MsgBox str1, vbInformation, "Response to ""get_information"" request"

Comme décrit dans la première partie, la requête en format XML est d'abord préparée et stockée dans "str_envelope". "request.Open" ouvre la connexion à l'application. Le mot-clé "Post" indique que la requête est envoyée. Le troisième paramètre est réglé sur "true", ce qui exécute un transfert synchronisé. Ensuite, "request.Send" envoie la chaîne préparée.

Après le transfert, la réponse est stockée dans "response" et vérifiée avec "request.Status" pour voir si la requête a réussi. Le statut est attribué par RFEM, donc en cas de requête incorrecte, par exemple une commande inconnue, RFEM renvoie une erreur. Si le statut n'est pas "200", le programme est interrompu et l'erreur est affichée dans une fenêtre (MsgBox).

S'il n'y a pas d'erreurs, les différentes informations peuvent maintenant être lues via "GetElementsByTagName". Dans l'exemple concret, les informations sont ensuite affichées dans une fenêtre.

Les éléments suivants ont de grandes similitudes, il est donc fait mention seulement des particularités (le code source complet est disponible pour téléchargement). Pour construire un porteur sur deux supports avec une charge de barre, les fonctions suivantes sont nécessaires :

  1. Noeud – set_node
  2. Ligne – set_line
  3. Matériau – set_material
  4. Section – set_section
  5. Barre – set_member
  6. Appui nodal – set_nodal_support
  7. Paramètres de calcul – set_static_analysis_settings
  8. Cas de charge – set_load_case
  9. Charge de barre – set_member_load

La fonction "set_node" a, comme la plupart des autres, plusieurs paramètres, qui ne sont normalement pas nécessaires. Dans la liste des commandes du modèle RFEM déjà mentionnée, la diversité des paramètres peut être vue. Sont surtout importants les paramètres qui n'ont pas la mention "optional", car ceux-ci doivent être remplis dans tous les cas. Dans l'exemple, les paramètres suivants sont transmis :

begin_modification (url_model)

'   set node 1 on [0,0,0] with "set_node" command
str_envelope =
    "" & _
        "<Body>" & _
            "" & _
                "" & _
                    "1" & _
                    "TYPE_STANDARD" & _
                    "0" & _
                    "0" & _
                    "0" & _
                "" & _
            "" & _
        "</Body>>" & _
    ""

Seul le numéro de noeud n'est pas optionnel et le reste peut être attribué. Dans la liste des commandes, en plus des paramètres possibles, des listes pour les types sont également présentées. Dans ce cas concret, cinq types différents sont actuellement possibles. Le type standard "TYPE_STANDARD" a été choisi. Le premier noeud illustré ici est créé à la position (0;0;0), le second noeud à (5,5;0;0). Les valeurs avec des décimales ressemblent à ceci :

…
"" & _
        "2" & _
        "TYPE_STANDARD" & _
        "5.5" & _
        "0" & _
        "0" & _
    "" & _
…

Une autre particularité réside dans les listes. La ligne a besoin de deux noeuds, dont les numéros peuvent être transmis sous forme de liste. Les éléments d'une liste, comme ici "definition_nodes", sont séparés par un espace :

…
    "" & _
        "" & _
            "1" & _
            "TYPE_POLYLINE" & _
            "1 2" & _
        "" & _
    "" & _
…

Pour pouvoir créer la barre, une section doit encore être créée, qui elle-même nécessite un matériau. Les sections et matériaux peuvent être utilisés à partir de la base de données interne. Par conséquent, la simple indication d'un identificateur connu suffit. Pour le matériau, l'identifiant est "S235" et la section a le nom "IPE 300" :

…
    "" & _
        "" & _
            "1" & _
            "1" & _
            "TYPE_STANDARDIZED_STEEL" & _
            "IPE 300" & _
        "" & _
    "" & _
…

Pour vérifier si un nom comme "IPE 300" est valide, l'entrée peut être utilisée dans l'interface graphique.

Pour l'entrée de la barre elle-même, aucune autre connaissance n'est requise, mais pour l'entrée d'un appui fixe, une rigidité de ressort "infinie" doit être définie. Le mot-clé "INF" est utilisé pour la transmission :

…
    "" & _
        "" & _
            "1" & _
            "1" & _
            "INF" & _
            "INF" & _
            "INF" & _
            "INF" & _
            "0" & _
            "INF" & _
        "" & _
    "" & _
…

L'ajout du cas de charge et des paramètres de calcul ne nécessite pas de connaissances supplémentaires. La dernière particularité est un élément supplémentaire lors de l'ajout de la charge, car il doit être donné en dehors de la section "". Dans le cas de la charge de barre, le cas de charge associé doit y être transmis :

…
    "" & _
        "1" & _
        "" & _
            "1" & _
            "LOAD_TYPE_FORCE" & _
            "1" & _
            "LOAD_DISTRIBUTION_UNIFORM" & _
            "LOAD_DIRECTION_GLOBAL_Z_OR_USER_DEFINED_W_TRUE" & _
            "1000" & _
        "" & _
    "" & _
…
En complément, il convient de mentionner que l'ordre des éléments à l'intérieur de la section "value" n'a pas d'importance, mais que c'est le cas à l'extérieur. Le cas de charge spécifié doit donc se trouver avant la section "value". En plus des fonctions précédentes pour l'ajout et la lecture de données, il existe deux fonctions particulières à mentionner. Lorsque des éléments sont transmis au programme, celui-ci passe automatiquement en "mode de modification", c'est-à-dire en mode d'édition. Le programme vérifie les nouveaux éléments et les intègre. Si plusieurs nouveaux éléments doivent être ajoutés en même temps, il est donc judicieux de laisser le programme en mode d'édition pendant cette durée pour accélérer le traitement. À cette fin, il existe les fonctions "begin_modification" et "finish_modification". Dans l'exemple, "begin_modification" est donc appelé avant l'ajout du premier nœud et "finish_modification" à la fin, après l'ajout du cas de charge. Les fonctions ont également été définies dans le programme en tant que fonctions VBA. Elles sont autonomes et c'est pourquoi les variables "request" et "response" sont redéfinies à l'intérieur. Mais comme aucun nouvel élément n'est nécessaire pour elles, cela ne sera pas approfondi ici. Comparer la performance avec et sans l'utilisation de ces fonctions montrera toujours une différence de vitesse. == Résumé == L'API service Web est un outil puissant pour RFEM et RSTAB. Le transfert simple via HTTP permet l'implémentation de l'interface dans de nombreux langages de programmation, pas seulement celui présenté ici, VBA, et permet une programmation multiplateforme.


Auteur

M. Günthel fournit une assistance technique aux clients de Dlubal Software.

Liens
Téléchargements


;