8809x
001738
2025-06-09

Tutorial Webservice-API in VBA

Il servizio web è una comunicazione tra macchine o programmi. Questa comunicazione è fornita tramite la rete e può quindi essere utilizzata da qualsiasi programma in grado di inviare e ricevere stringhe di caratteri attraverso il protocollo HTTP. RFEM 6 e RSTAB 9 offrono un'interfaccia basata su questi servizi web multipiattaforma. Questo tutorial intende mostrare le basi utilizzando il linguaggio di programmazione VBA.

Fondamenti dell'API Webservice con esempio in VBA

Per la formattazione delle stringhe di testo viene utilizzato il formato XML secondo le specifiche del protocollo SOAP. Un esempio è la seguente richiesta:



    <Body>
        
    </Body>

Un elemento tipico della formattazione XML è l'inizio di una sezione con il carattere "<". Segue un'identificatore e, se non ci sono ulteriori elementi figli, la sezione viene chiusa con "/>". Un esempio è la terza riga:



In presenza di sottoelementi, si inizia con "<", il comando e ">", e si chiude con "</", il comando e ">". Un esempio pertinente è la sezione "Body":


<Body>
    
</Body>

La formattazione con spazi e interruzioni di linea serve solo a scopo illustrativo. Per la trasmissione, non è richiesta. Gli elementi "Body" e "Envelope" sono elementi standard per la trasmissione e vengono utilizzati per ogni comando.

Tutti i comandi disponibili possono essere letti tramite l'interfaccia WSDL. Ci sono software che consentono di generare liste a partire da queste informazioni. Un esempio di tale software è SoapUI. Per l'API di RFEM 6 sono disponibili due liste, una per i comandi applicativi e una per i comandi di modello. Entrambe le liste possono essere scaricate alla fine di questo contributo.

Poiché i comandi vengono inviati tramite HTTP, sono necessari indirizzi URL. L'indirizzo standard per le applicazioni RSTAB/RFEM è "localhost:8081" e può essere modificato nelle impostazioni del programma.

I modelli aperti ricevono indirizzi ascendenti, quindi il primo modello aperto ha l'indirizzo "localhost:8082". Per ottenere l'indirizzo del modello attivo, viene inviato il comando "get_active_model". Una risposta corrispondente da RFEM 6 appare così:



    
        
            
                http://127.0.0.1:8082/
            
        
    

I dettagli aggiuntivi nella sezione "Envelope" (envelope/busta) e la riga iniziale "<?xml version="1.0"?>" servono a mostrare gli standard utilizzati e non saranno ulteriormente considerati qui. È comunque evidente che vengono di nuovo utilizzati gli elementi "Envelope" e "Body". All'interno di "Body" c'è la risposta di RFEM 6 con il nome del comando "get_active_model" seguito dalla parola "Response". Il contenuto di questa risposta è un valore ("value") che rappresenta l'indirizzo del modello attivo. Inoltre, RFEM è ora bloccato per ulteriori accessi.

Nel seguente esempio si vedrà come creare un'asta con due vincoli nodali e un carico. Per comunicare con RFEM tramite VBA, sono necessari i seguenti oggetti:


request As MSXML2.XMLHTTP60
response As MSXML2.DOMDocument

L'oggetto XMLHTTP60 ha una funzione integrata per inviare una richiesta HTTP a un URL e viene quindi utilizzato per la richiesta. La risposta può quindi essere valutata usando il DOMDocument. Il seguente esempio unisce la richiesta mostrata in precedenza "get_active_model" con i comandi utilizzati sotto 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)

Innanzitutto, la richiesta in formato XML viene salvata nella variabile "str_envelope" e, tramite il metodo "Open", la richiesta della variabile "request" viene aperta per RFEM. Con il metodo "Send" ora si può inviare il contenuto della variabile "str_envelope". La risposta può quindi essere recuperata tramite il metodo "ResponseText". In questo caso specifico, viene direttamente caricata nella variabile "response" tramite il metodo "LoadXML".

La variabile "response" di tipo DOMDocument ha il metodo LoadXML e può quindi riconoscere la formattazione XML. Il vantaggio è che il tipo DOMDocument fornisce anche il metodo GetElementsByTagName. Ciò permette di estrarre direttamente elementi dal codice. Di seguito, viene esteso il codice precedente in modo che l'URL del modello sia disponibile:


'   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

Prima di leggere l'URL, si può controllare lo stato della risposta. Si tratta di codici di stato HTTP standardizzati. Lo stato "200" indica che la trasmissione è stata "OK". Dopo questa verifica, l'URL del modello viene salvato nella stringa "url_model". Per questo, dall'XML di risposta, viene cercato l'elemento "value". Se una risposta contiene più elementi, tutti i valori all'interno della sezione "value" vengono memorizzati, quindi non è possibile effettuare una valutazione con l'identificativo "value", ma vengono richiamati gli elementi figli di "value". Maggiori dettagli si trovano nell'esempio pratico. Nel caso dell'indirizzo del modello, l'unico valore restituito è l'URL, quindi "value" qui funziona.

Esempio pratico in VBA

Ora che sono noti tutti gli elementi di base, segue un semplice esempio. Si creerà una trave su due supporti su cui si potrà applicare un carico sull'asta.

Innanzitutto, vengono definite e inizializzate le variabili già presentate:


'    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/"

Oltre alle variabili "request" e "response", vengono create le stringhe "str_envelope" per la richiesta e "url_app" e "url_model" per gli indirizzi dell'applicazione e del modello. Durante l'inizializzazione, possono essere passate le specifiche note del protocollo SOAP per valutare la formattazione XML della risposta. L'indirizzo del modello verrà ottenuto successivamente, ma l'indirizzo dell'applicazione deve essere indicato. Come già menzionato, è necessario specificare l'indirizzo standard:

Nel passaggio successivo si dovrebbe testare la connessione all'applicazione. Per questo test, tramite il comando "get_information" vengono richieste le informazioni standard dell'applicazione:


'   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"

Come descritto nella prima parte, la richiesta formattata in XML viene prima preparata e memorizzata in "str_envelope". "request.Open" apre la connessione all'applicazione. La parola chiave "Post" sta a indicare l'invio della richiesta. Il terzo parametro è impostato su "true", eseguendo così una trasmissione sincrona. Successivamente, "request.Send" invia la stringa preparata.

Dopo la trasmissione, la risposta viene memorizzata in "response" e, con "request.Status", si verifica se la richiesta è stata eseguita con successo. Lo stato viene assegnato da RFEM, quindi in caso di richiesta errata, ad esempio con un comando sconosciuto, verrà restituito un errore. Se lo stato non è "200", il programma si interrompe e l'errore viene visualizzato in una finestra (MsgBox).

Se non ci sono errori, ora è possibile leggere le diverse informazioni trasmesse tramite "GetElementsByTagName". Nell'esempio specifico, le informazioni vengono poi visualizzate in una finestra.

Gli elementi seguenti presentano grandi somiglianze, quindi si tratterà solo delle particolarità (il codice sorgente completo è disponibile per il download). Per la costruzione di un trave su due supporti con un carico su asta, sono necessarie le seguenti funzioni:

  1. Nodo – set_node
  2. Linea – set_line
  3. Materiale – set_material
  4. Sezione – set_section
  5. Asta – set_member
  6. Vincolo Nodal – set_nodal_support
  7. Parametri di calcolo – set_static_analysis_settings
  8. Caso di carico – set_load_case
  9. Carico su asta – set_member_load

La funzione "set_node" ha, come la maggior parte delle altre, molti parametri, che però normalmente non sono necessari. Nell'elenco dei comandi del modello RFEM è possibile consultare la varietà di parametri. Importanti sono soprattutto i parametri che non hanno il tag "optional", poiché questi devono essere sempre compilati. Nell'esempio vengono passati i seguenti parametri:


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>>" & _
    ""

Solo il numero del nodo qui non è opzionale e il resto può essere assegnato. Nell'elenco dei comandi, oltre ai possibili parametri, vengono mostrate anche le liste per i tipi. Nel caso specifico, sono attualmente possibili cinque diversi tipi. È stato scelto il tipo standard "TYPE_STANDARD". Il primo nodo qui mostrato verrà creato nel punto (0;0;0), il secondo nodo verrà creato in (5,5;0;0). I valori con numeri decimali appaiono come segue:


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

Un'altra particolarità sono le liste. La linea ha bisogno di due nodi, i cui numeri vengono passati come lista. Gli elementi di una lista, come "definition_nodes" qui, sono separati da spazi:


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

Per poter impostare l'asta, deve essere impostata una sezione che necessita di un materiale. Sezioni e materiali possono essere utilizzati dalla banca dati interna. Pertanto, è sufficiente indicare un identificativo noto. Per il materiale, l'identificativo è "S235" e la sezione si chiama "IPE 300":


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

Per verificare se un nome come "IPE 300" è valido, può essere utilizzato l'input nell'interfaccia grafica.

Per l'inserimento dell'asta stessa non sono richieste ulteriori conoscenze, ma per l'inserimento di un vincolo fisso deve essere definita una rigidità a molla "infinita". Per la trasmissione viene utilizzata la parola chiave "INF":


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

L'impostazione del caso di carico e dei parametri di calcolo non richiede ulteriori conoscenze. L'ultima particolarità è un valore aggiuntivo nella creazione del carico, poiché deve essere specificato al di fuori della sezione "". Nel caso del carico su asta, il corrispondente caso di carico deve essere trasmesso lì:


…
    "" & _
        "1" & _
        "" & _
            "1" & _
            "LOAD_TYPE_FORCE" & _
            "1" & _
            "LOAD_DISTRIBUTION_UNIFORM" & _
            "LOAD_DIRECTION_GLOBAL_Z_OR_USER_DEFINED_W_TRUE" & _
            "1000" & _
        "" & _
    "" & _
…
Va anche notato che l'ordine degli elementi all'interno della sezione "value" non è importante, ma lo è all'esterno. Il caso di carico specificato deve quindi comparire prima della sezione "value". Oltre alle funzioni finora presentate per la creazione e la lettura dei dati, ci sono due funzioni particolari da introdurre. Quando si passano elementi al programma, questo entra automaticamente in modalità di "Modification", ovvero modalità di modifica. Il programma verifica i nuovi elementi e procede ad integrarli. Se devono essere creati più nuovi elementi, è utile mantenere il programma in questa modalità di modifica per tale periodo, in modo che l'elaborazione sia più veloce. A tal fine, ci sono le funzioni "begin_modification" e "finish_modification". Nell'esempio, "begin_modification" viene quindi chiamato prima della creazione del primo nodo e "finish_modification" alla fine, dopo la creazione del caso di carico. Le due funzioni sono state definite nel programma anche come funzioni VBA. Le funzioni sono autonome, quindi all'interno delle funzioni vengono nuovamente definiti gli oggetti "request" e "response". Poiché però non sono necessari nuovi elementi per questo, non verrà ulteriormente discusso. È interessante il confronto con e senza l'uso di queste funzioni, che porterà sempre a una differenza di velocità. == Riepilogo == L'API Webservice è uno strumento potente per RFEM e RSTAB. La semplice trasmissione basata su HTTP consente l'implementazione dell'interfaccia in molti linguaggi di programmazione, non solo come mostrato qui in VBA, e permette la programmazione multipiattaforma.


Autore

Il signor Günthel fornisce supporto tecnico per i clienti di Dlubal Software e si prende cura delle loro richieste.

Link
Download


;