Webservice è una comunicazione tra macchine e programmi. Questa comunicazione è fornita tramite la rete e può, quindi, essere utilizzata da qualsiasi programma in grado di inviare e ricevere stringhe tramite il protocollo HTTP. RFEM 6 e RSTAB 9 forniscono un'interfaccia basata su questi Webservice multi-piattaforma. Questo tutorial mostra le nozioni di base utilizzando il linguaggio di programmazione VBA.
Nozioni di base sull'API Webservice utilizzando l'esempio di VBA
Per la formattazione della stringa, viene utilizzato il formato XML secondo le specifiche del protocollo SOAP. La seguente query funge da esempio:
- code.vba#
http://schemas.xmlsoap.org/soap/envelope/">
#/codice#
Un elemento tipico della formattazione XML è l'inizio di una sezione con il carattere "<". Quindi, segue un identificatore e, se non sono presenti altri sottoelementi, la sezione viene chiusa con "/>". Un esempio è la terza linea:
#code.vba#
#/codice#
Se ci sono sotto-elementi, inizia con "<", il comando e ">" e termina con "", il comando e ">". L'esempio appropriato è la sezione "Corpo":
#code.vba#
#/codice#
La formattazione con spazi e interruzioni di linea è utilizzata qui solo a scopo illustrativo. Questo non è necessario per il trasferimento. Gli elementi "Corpo" e "Inviluppo" sono elementi standard per il trasferimento e vengono utilizzati per ogni comando.
Tutti i comandi disponibili possono essere letti utilizzando l'interfaccia WSDL. È disponibile un software che può essere utilizzato per creare elenchi. Un esempio di tale software è SoapUI. Ci sono due elenchi per l'API di RFEM 6; i comandi per l'applicazione e quelli per il modello. Entrambi gli elenchi possono essere scaricati alla fine di questo articolo.
Poiché i comandi vengono inviati tramite HTTP, gli indirizzi URL sono necessari per l'indirizzamento. L'indirizzo predefinito delle applicazioni RSTAB/RFEM è "http://localhost:8081/" e può essere modificato nelle impostazioni del programma. Ai modelli aperti vengono assegnati gli indirizzi in ordine crescente in modo che il primo modello aperto abbia l'indirizzo "http://localhost:8082/". Per ottenere l'indirizzo del modello attivo, viene inviato il comando "get_active_model". Una risposta corrispondente da RFEM 6 è simile alla seguente:
#code.vba#
http://127.0.0.1:8082/
#/codice#
I dettagli aggiuntivi della sezione "Inviluppo". così come la riga precedente "" dovrebbe prima mostrare gli standard utilizzati e non saranno discussi ulteriormente qui. In ogni caso, puoi vedere che gli elementi "Inviluppo" e "Corpo" vengono utilizzati di nuovo. La risposta di RFEM 6 è contenuta in "Corpo" dal nome del comando "get_active_model" e dalla parola aggiunta "Risposta". Il contenuto di questa risposta è un "valore", ovvero l'indirizzo del modello attivo. Inoltre, RFEM è ora bloccato per ulteriori accessi.
Nell'esempio seguente, vogliamo creare un'asta con due vincoli esterni dei nodi e un carico. Per poter comunicare con RFEM tramite VBA, sono necessari i seguenti oggetti:
#code.vba#
richiesta Come MSXML2.XMLHTTP60
risposta Come MSXML2.DOMDocument
#/codice#
L'oggetto XMLHTTP60 ha una funzione integrata per inviare una richiesta HTTP a un URL ed è, quindi, utilizzato per la richiesta. La risposta può quindi essere valutata utilizzando DOMDocument. L'esempio seguente combina la richiesta "get_active_model" mostrata in precedenza con i comandi utilizzati in VBA:
#code.vba#
' ottieni l'URL del modello attivo con il comando "get_active_model".
str_envelope =
"" & _
" " & _
" " & _
" " & _
""
' apri la richiesta e inviala
request.Open "Post", "http://localhost:8081/", False
request.Send (str_envelope)
' ottiene la risposta e la trasforma in un oggetto xml
response.LoadXML (request.responseText)
#/codice#
Innanzitutto, la richiesta viene salvata in formato XML nella variabile "str_envelope" e la richiesta viene aperta in RFEM utilizzando il metodo "Apri" della variabile "richiesta". Il contenuto della variabile "str_envelope" può ora essere inviato utilizzando il metodo "Invia". È quindi possibile accedere alla risposta utilizzando il metodo "ResponseText". In questo caso specifico, questo viene importato direttamente tramite il metodo "LoadXML" della variabile "response".
La variabile "response" del tipo DOMDocuments ha il metodo LoadXML e può quindi riconoscere la formattazione XML. Il vantaggio è che il tipo DOMDocuments fornisce anche il metodo GetElementsByTagName. Ciò consente di estrarre elementi direttamente dal codice. Di seguito, il codice precedente viene esteso in modo che l'indirizzo URL del modello sia disponibile:
#code.vba#
' ottiene lo stato http
stato = richiesta.stato
Se lo stato <> "200" Allora
MsgBox "get_active_model: Invio non riuscito - " & response.Text
Esci sub
End If
url_model = response.GetElementsByTagName("value")(0).Text
#/codice#
Prima che l'URL venga letto, è possibile controllare lo stato della risposta. Sono codici di stato HTTP standardizzati. Lo stato "200" significa che il trasferimento è stato "OK". Dopo questa query, l'URL del modello viene salvato nella stringa url_model. Per questo, l'elemento "valore" viene cercato nella risposta XML. Se una risposta contiene più elementi, tutti i valori vengono salvati nella sezione "valore", in modo che non sia possibile alcuna valutazione con l'identificatore "valore", ma vengono indirizzati i sotto-elementi di "valore". Ulteriori informazioni saranno fornite nell'esempio pratico. Nel caso dell'indirizzo del modello, l'unico valore restituito è l'URL, quindi "valore" ha esito positivo qui.
== Esempio pratico in VBA ==
Ora che conosciamo tutti gli elementi di base, segue un semplice esempio. Vogliamo creare una trave su due colonne a cui è possibile applicare un carico dell'asta.
Innanzitutto, le variabili sopra descritte sono definite e inizializzate:
#code.vba#
' definisce le variabili
Dim richiesta Come MSXML2.XMLHTTP60
Dim risposta Come MSXML2.DOMDocument60
Dim str_envelope As String
Dim url_app come stringa
Dim url_model As String
' variabili init
Imposta richiesta = Nuovo MSXML2.XMLHTTP60
Imposta risposta = Nuovo MSXML2.DOMDocument60
Con risposta
.async = Falso
.preserveWhiteSpace = Falso
.validateOnParse = Falso
.resolveExternals = Falso
' Utilizza la funzionalità completa di XPath
.SetProperty "SelectionLanguage", "XPath"
' Aggiungi spazi dei nomi specifici per lavorare con i percorsi
.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"" "
Termina con
url_app = "http://localhost:8081/"
#/codice#
Oltre alle variabili "request" e "response", viene creata la stringa "str_envelope" per la richiesta e "url_app" e "url_model" per gli indirizzi dell'applicazione e del modello. Durante l'inizializzazione, le specifiche note del protocollo SOAP possono essere trasferite per valutare la formattazione XML della risposta. L'indirizzo del modello sarà preso in seguito, ma l'indirizzo dell'applicazione deve essere specificato. Come già accennato, è necessario inserire l'indirizzo predefinito "http://localhost:8081/".
Il prossimo passo è testare la connessione all'applicazione. Per questo test, le informazioni standard dell'applicazione vengono richieste utilizzando il comando "get_information":
#code.vba#
' controlla l'URL dell'applicazione con il comando "get_information"
str_envelope = "" & _
" " & _
""
' apri la richiesta e inviala
request.Apri "Post", url_app, False
request.Send (str_envelope)
' ottiene la risposta e la trasforma in un oggetto xml
response.LoadXML (request.responseText)
' ottiene lo stato http
stato = richiesta.Stato
Se lo stato <> "200" Allora
MsgBox "get_information: Invio non riuscito - " & response.Text
Esci sub
End If
' legge le informazioni sull'applicazione
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("versione")(0).Text & vbLf
str1 = str1 & response.GetElementsByTagName("language_name")(0).Text & vbLf
str1 = str1 & response.GetElementsByTagName("language_id")(0).Text
MsgBox str1, vbInformation, "Risposta alla richiesta ""get_information""
#/codice#
Come già descritto nella prima parte, la richiesta in formato XML viene preparata e salvata in "str_envelope". "request.Open" apre la connessione all'applicazione. La parola chiave "Post" sta per l'invio della richiesta. Il terzo parametro è impostato su "true" e quindi viene eseguita una trasmissione sincrona. Infine, "request.Send" invia la stringa preparata.
Dopo il trasferimento, la risposta viene salvata in "response" e controllata con "request.Status" per verificare se la richiesta ha avuto esito positivo. Lo stato è assegnato da RFEM in modo che restituisca un errore in caso di richiesta errata; ad esempio, un comando sconosciuto. Se lo stato non è "200", il programma viene interrotto e l'errore viene visualizzato in una finestra (MsgBox).
Se non si sono verificati errori, le varie informazioni trasferite possono ora essere lette utilizzando "GetElementsByTagName". Nell'esempio specifico, le informazioni vengono quindi visualizzate in una finestra.
I seguenti elementi sono molto simili, quindi sono descritte solo le caratteristiche speciali (il codice sorgente completo può essere scaricato). Per impostare una trave su due colonne con un carico dell'asta, sono necessarie le seguenti funzioni:
# Nodo - set_node
# Linea - set_line
# Materiale – set_materiale
# Sezione - set_section
# Asta - set_asta
# Vincolo esterno del nodo – set_nodal_support
# Parametri di calcolo – set_static_analysis_settings
# Caso di carico - set_load_case
# Carico dell'asta - set_member_load
Come la maggior parte delle altre, la funzione "set_node" ha molti parametri, ma di solito non sono richiesti. Nell'elenco dei comandi già menzionato del modello RFEM, è possibile vedere la varietà di parametri. Soprattutto, i parametri che non sono contrassegnati come "opzionali" sono importanti, poiché devono essere compilati in ogni caso. Nell'esempio, vengono trasferiti i seguenti parametri:
#code.vba#
begin_modification (url_model)
' imposta il nodo 1 su [0,0,0] con il comando "set_node".
str_envelope =
"" & _
" " & _
" " & _
"" & _
"1" & _
"TYPE_STANDARD" & _
" 0 " & _
"0" & _
"0" & _
"" & _
" " & _
" >" & _
""
#/codice#
Solo il numero del nodo non è opzionale; il resto può essere assegnato, ma non deve esserlo. Oltre ai possibili parametri, l'elenco dei comandi mostra anche gli elenchi dei tipi. In questo caso specifico, sono attualmente possibili cinque diversi tipi. È stato selezionato il tipo predefinito "TYPE_STANDARD". Il primo nodo mostrato qui viene creato nella posizione (0; 0; 0), il secondo nodo in (5.5; 0; 0). I valori per i numeri decimali sono i seguenti:
#code.vba#
…
"" & _
"2" & _
"TYPE_STANDARD" & _
"5.5" & _
"0" & _
"0" & _
"" & _
…
#/codice#
Gli elenchi sono un'altra caratteristica speciale. La linea ha bisogno di due nodi di cui i numeri possono essere trasferiti come un elenco. Gli elementi di un elenco, come "definition_nodes", sono separati da spazi:
#code.vba#
…
"" & _
"" & _
"1" & _
"TYPE_POLYLINE" & _
"1 2" & _
"" & _
"" & _
…
#/codice#
Per poter creare l'asta, è necessario creare una sezione trasversale, che a sua volta richiede un materiale. Sezioni trasversali e materiali possono essere utilizzati dal database interno. Pertanto, è sufficiente specificare un identificatore noto. Per il materiale, l'identificatore è "S235" e la sezione trasversale ha il nome "IPE 300":
#code.vba#
…
"" & _
"" & _
"1" & _
"1" & _
"TYPE_STANDARDIZED_STEEL" & _
"IPE 300" & _
"" & _
"" & _
…
#/codice#
Per verificare se un nome come "IPE 300" è valido, è possibile utilizzare la voce nell'interfaccia utente grafica.
Per inserire l'asta stessa, non sono necessarie ulteriori conoscenze, ma per inserire un vincolo fisso, è necessario definire una rigidezza della molla "infinita". La parola chiave "INF" è utilizzata per il trasferimento:
#code.vba#
…
"" & _
"" & _
"1" & _
"1" & _
"INF" & _
"INF" & _
"INF" & _
"INF" & _
"0" & _
"INF" & _
"" & _
"" & _
…
#/codice#
La creazione del caso di carico e dei parametri di calcolo non richiede alcuna conoscenza aggiuntiva. L'ultima particolarità è un valore aggiuntivo durante la creazione del carico, perché deve essere specificato al di fuori dell'area "". Nel caso di un carico dell'asta, il caso di carico corrispondente deve essere trasferito lì:
#code.vba#
…
"" & _
"1" & _
"" & _
"1" & _
"LOAD_TYPE_FORCE" & _
"1" & _
"LOAD_DISTRIBUTION_UNIFORM" & _
"LOAD_DIRECTION_GLOBAL_Z_OR_USER_DEFINED_W_TRUE" & _
"1000" & _
"" & _
"" & _
…
#/codice#
Inoltre, va menzionato che l'ordine degli elementi all'interno dell'area "valore" è irrilevante, ma al di fuori di essa non lo è. Il caso di carico specificato deve quindi precedere l'area "valore".
Oltre alle funzioni precedenti per la creazione e l'esportazione dei dati, ci sono due funzioni speciali che verranno mostrate qui. Se gli elementi vengono trasferiti al programma, il programma passa automaticamente in modalità "Modifica". Il programma controlla i nuovi elementi e li integra. Se devono essere creati diversi nuovi elementi, è quindi utile lasciare il programma in questa modalità di modifica per questo periodo, in modo che l'elaborazione sia più veloce. A tale scopo sono disponibili le funzioni "begin_modification" e "finish_modification".
Nell'esempio, "begin_modification" viene chiamato prima di creare il primo nodo e "finish_modification" viene chiamato alla fine dopo aver creato il caso di carico. Entrambe le funzioni sono state create anche come funzioni VBA nel programma. Le funzioni sono indipendenti, e quindi le variabili "richiesta" e "risposta" sono create di nuovo all'interno delle funzioni. Tuttavia, poiché non sono necessari nuovi elementi per questo, non saranno descritti ulteriormente qui. Un confronto interessante è quello con e senza l'uso di queste funzioni, che risulteranno sempre in una differenza di velocità.
== Conclusione ==
L'API Webservice è un potente strumento per RFEM e RSTAB. Il semplice trasferimento basato su HTTP consente l'implementazione dell'interfaccia in molti linguaggi di programmazione, non solo in VBA come mostrato qui, ed è possibile la programmazione multipiattaforma.