Základy Webové API na příkladu VBA
Pro formátování řetězce znaků je použito XML formátu dle specifikací protokolu SOAP. Jako příklad nám poslouží následující dotaz:
<Body>
</Body>
Typický prvek XML formátování začíná sekcí se znakem "<". Poté následuje identifikátor a pokud nenásleduje žádné další podřízené prvky, je sekce ukončena "/>". Příkladem je třetí řádek:
Pokud existují podřízené prvky, začíná se "<", příkazem a ">" a konec tvoří "</", příkaz a ">". Odpovídající příklad je sekce "Body":
<Body>
</Body>
Formátování s mezerami a zalamováním řádků slouží pouze k ilustraci a pro přenos není vyžadováno. Prvky "Body" a "Envelope" jsou standardními prvky pro přenos a jsou používány pro každý příkaz.
Všechny dostupné příkazy lze číst prostřednictvím rozhraní WSDL. Existuje software, který z toho může vytvářet seznamy. Takovým softwarem je například SoapUI. Pro API RFEM 6 existují dva seznamy, příkazy pro aplikaci a pro model. Oba seznamy lze stáhnout na konci tohoto příspěvku.
Protože jsou příkazy zasílány přes HTTP, jsou pro jeho adresování potřebné URL adresy. Standardní adresa aplikací RSTAB/RFEM je "localhost:8081" a lze ji změnit v nastavení programu.
Otevřené modely dostávají vzestupné adresy, takže první otevřený model má adresu "localhost:8082". Chcete-li získat adresu aktivního modelu, je odeslán příkaz "get_active_model". Odpověď od RFEM 6 vypadá takto:
http://127.0.0.1:8082/
Další detaily sekce "Envelope" (v češtině: obálka) a úvodní řádek "<?xml version="1.0"?>" mají původně ukázat použité standardy a nebudou zde dále rozebírány. Každopádně je opět patrné použití prvků "Envelope" a "Body". Uvnitř "Body" se nachází odpověď od RFEM 6 prostřednictvím názvu příkazu "get_active_model" a připojeného slova "Response". Obsah této odpovědi je hodnota ("value") a to adresa aktivního modelu. Dále je nyní RFEM pro další přístupy uzamčen.
V následujícím příkladu je vytvářen prut se dvěma uzlovými podporami a zatížením. Pro komunikaci s RFEM přes VBA jsou potřebné následující objekty:
request As MSXML2.XMLHTTP60
response As MSXML2.DOMDocument
Objekt XMLHTTP60 má integrovanou funkci pro odeslání HTTP dotazu na URL a proto je použitý pro dotaz. Odpověď může být poté vyhodnocena pomocí DOMDocuments. Následující příklad spojuje již ukázaný dotaz "get_active_model" s příkazy používanými v 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)
Nejprve je dotaz ve formátu XML uložen do proměnné "str_envelope" a pomocí metody "Open" je proměnná "request" otevřena pro zaslání dotazu na RFEM. Pomocí metody "Send" může být nyní obsah proměnné "str_envelope" odeslán. Odpověď může být poté vyvolána prostřednictvím metody "ResponseText". V konkrétním případě je načtena přímo pomocí metody "LoadXML" do proměnné "response".
Proměnná "response" typu DOMDocuments má metodu LoadXML a dokáže tak rozpoznat XML formátování. Výhodou je, že typ DOMDocuments obsahuje metodu GetElementsByTagName. Tímto způsobem lze přímo extrahovat prvky z kódu. Následující kód rozšíří předchozí kód tak, aby byla k dispozici URL adresa modelu:
' 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
Dříve než je URL načteno, může být také zkontrolován stav odpovědi. Jde o standardizované HTTP stavové kódy. Stav "200" znamená, že přenos byl "OK". Po této kontrole je v řetězci url_model uložena URL modelu. Pro tento účel je z XML odpovědi hledán prvek "value". Pokud odpověď obsahuje více prvků, budou všechny hodnoty v sekci "value" uloženy, takže zde není možné vyhodnotit s identifikátorem "value", ale je třeba oslovit podřízené prvky "value". Více o tom v praktickém příkladu. V případě modelové adresy je jedinou vrácenou hodnotou URL, takže "value" zde vede k úspěchu.
Praktický příklad ve VBA
Jelikož jsou nyní známy všechny základní prvky, následuje jednoduchý příklad. Vytvoří se nosník na dvou pažích, na kterém může být aplikováno zatížení prutu.
Nejprve se definují a inicializují již představené proměnné:
' 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/"
Kromě proměnných "request" a "response" je vytvořen řetězec "str_envelope" pro dotaz a "url_app" a "url_model" pro adresy aplikace a modelu. Při inicializaci mohou být zadány známé specifikace protokolu SOAP pro vyhodnocení XML formátování odpovědi. Adresu modelu obdržíme později, ale adresa aplikace musí být zadána. Jak již bylo zmíněno dříve, je nutné zadat standardní adresu:
V dalším kroku má být otestována spojení s aplikací. Pro tento test jsou standardní informace o aplikaci dotázány pomocí příkazu "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"
Jak bylo popsáno v první části, nejprve je připraven dotaz formátovaný v XML a uložen do "str_envelope". "request.Open" otevírá spojení s aplikací. Klíčové slovo "Post" znamená odeslání dotazu. Třetí parametr je nastaven na "true" a tím je proveden synchronní přenos. Následně "request.Send" odesílá připravený řetězec.
Po přenosu je odpověď uložena do "response" a pomocí "request.Status" se zkontroluje, zda byl dotaz úspěšný. Stav je zadán RFEM, takže v případě chybného dotazu, například neznámého příkazu, vrátí chybu. Pokud stav není "200", je program ukončen a chyba je zobrazena v okně (MsgBox).
Pokud nevzniknou žádné chyby, mohou nyní pomocí "GetElementsByTagName" být čtené různé přenesené informace. V konkrétním příkladu jsou tyto informace poté zobrazeny v okně.
Následující prvky mají velké podobnosti, a proto jsou zmíněné jen specifika (kompletní zdrojový kód je dostupný ke stažení). Pro vytvoření nosníku na dvou podpěrách s prutovým zatížením jsou potřebné následující funkce:
- Uzly – set_node
- Linie – set_line
- Materiál – set_material
- Průřez – set_section
- Prut – set_member
- Uzl lze z podpory – set_nodal_support
- Parametry výpočtu – set_static_analysis_settings
- Zatěžovací stav – set_load_case
- Zatížení na prut – set_member_load
Funkce "set_node" má, stejně jako většina ostatních, mnoho parametrů, které však v normálním případě nejsou potřebné. V již zmíněném seznamu příkazů RFEM modelu může být vidět rozmanitost parametrů. Důležité jsou hlavně parametry, které nemají poznámku "optional", protože ty musí být v každém případě vyplněny. V příkladu jsou předány následující parametry:
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>>" & _
" "
Jediné, co zde není volitelné, je číslo uzlu, zbytek lze nastavit. V seznamu příkazů jsou vedle možných parametrů uvedeny také seznamy typů. Konkrétně je nyní možné vybrat pět různých typů. Vybrán byl standardní typ "TYPE_STANDARD". První zde ukázaný uzel bude vytvořen na místě (0;0;0), druhý uzel na (5,5;0;0). Hodnoty desetinných číslic poté vypadají takto:
…
"" & _
"2 " & _
"TYPE_STANDARD " & _
"5.5 " & _
"0 " & _
"0 " & _
" " & _
…
Další zvláštností představují seznamy. Linie potřebuje dva uzly, jejichž čísla mohou být předána jako seznam. Prvky seznamu, jako zde "definition_nodes", jsou odděleny mezerami:
…
"" & _
"" & _
"1 " & _
"TYPE_POLYLINE " & _
"1 2 " & _
" " & _
" " & _
…
Pro vytvoření prutu je ještě nutné vytvořit průřez, který opět potřebuje materiál. Průřezy a materiály mohou být použity z interní databáze. Proto stačí uvést známý název. Pro materiál je název "S235" a průřez má jméno "IPE 300":
…
"" & _
"" & _
"1 " & _
"1 " & _
"TYPE_STANDARDIZED_STEEL " & _
"IPE 300 " & _
" " & _
" " & _
…
Pro ověření, zda je jméno jako "IPE 300" platné, lze použít vstup na grafickém rozhraní.
Pro zadání samotného prutu nejsou potřeba žádné další znalosti, ale pro zadání pevné podpory je nutné definovat "nekonečnou" pružnost pružiny. Pro předání se použije klíčové slovo "INF":
…
"" & _
"" & _
"1 " & _
"1 " & _
"INF " & _
"INF " & _
"INF " & _
"INF " & _
"0 " & _
"INF " & _
" " & _
" " & _
…
Vytvoření zatěžovacího stavu a výpočetních parametrů nevyžaduje žádné další znalosti. Poslední zvláštností je dodatečná hodnota při vytváření zatížení, která musí být zadána mimo oblast "
…
"
Databáze znalostí