Webservice to komunikacja między maszynami i programami. Komunikacja ta odbywa się za pośrednictwem sieci i dlatego może być wykorzystywana przez dowolny program, który może wysyłać i odbierać ciągi znaków za pośrednictwem protokołu HTTP. Programy RFEM 6 i RSTAB 9 zapewniają interfejs oparty na tych wieloplatformowych usługach sieciowych. Ten tutorial pokazuje podstawy korzystania z języka programowania VBA.
Podstawy Webservice API na przykładzie VBA
Do sformatowania ciągu znaków wykorzystywany jest format XML zgodnie ze specyfikacjami protokołu SOAP. Przykładem może być poniższe zapytanie:
kod.vba#
http://schemas.xmlsoap.org/soap/envelope/">
/kod#
Typowym elementem formatowania XML jest początek sekcji od znaku „<”. Następnie nadawany jest identyfikator, a w przypadku braku innych elementów podrzędnych przekrój jest zamykany za pomocą "/>". Jednym z przykładów jest trzecia linia:
kod.vba#
http://www.dlubal.com/rfem.xsd"/>
/kod#
Jeśli istnieją podelementy, zaczyna się on na "<", polecenie i ">", a kończy na "", polecenie i ">". Odpowiednim przykładem jest sekcja "Body":
kod.vba#
#/kod#
Formatowanie ze spacjami i końcami linii zostało tu zastosowane wyłącznie w celach ilustracyjnych. Nie jest to wymagane do transferu. Elementy "Body" i "Obwiednia" są standardowymi elementami do transferu i są używane w każdym poleceniu.
Wszystkie dostępne polecenia można odczytać za pomocą interfejsu WSDL. Dostępne jest oprogramowanie, za pomocą którego można tworzyć zestawienia. Przykładem takiego oprogramowania jest SoapUI. Dla API programu RFEM 6 istnieją dwie listy; poleceniami dla aplikacji i dla modelu. Obie listy można pobrać na końcu tego artykułu.
Ponieważ polecenia są wysyłane przez HTTP, do adresowania wymagane są adresy URL. Domyślny adres aplikacji RSTAB/RFEM to "http://localhost:8081/" i można go zmienić w ustawieniach w programie. Otwieranym modelom przydzielane są adresy w kolejności rosnącej, dzięki czemu pierwszy otwarty model ma adres "http://localhost:8082/". Aby uzyskać adres aktywnego modelu, wysyłane jest polecenie "get_active_model". Odpowiednia odpowiedź z programu RFEM 6 wygląda następująco:
#kod.vba#
http://127.0.0.1:8082/
#/kod#
Więcej informacji w sekcji „Obwiednia” podobnie jak w poprzednim wierszu "" powinien najpierw zawierać zastosowane normy i nie będzie tutaj dalej omawiany. W każdym razie widać, że elementy "Envelope" i "Body" są ponownie używane. Odpowiedź programu RFEM 6 jest zawarta w polu „Body” w nazwie polecenia „get_active_model” i dołączonym słowie „Odpowiedź”. Treść tej odpowiedzi jest „wartością”, a mianowicie adresem aktywnego modelu. Ponadto program RFEM jest teraz zablokowany.
W poniższym przykładzie chcemy utworzyć pręt z dwiema podporami węzłowymi i obciążeniem. Do komunikacji z programem RFEM za pośrednictwem VBA wymagane są następujące obiekty:
#kod.vba#
zapytanie As MSXML2.XMLHTTP60
Odpowiedź As MSXML2.DOMDocument
#/kod#
Obiekt XMLHTTP60 posiada wbudowaną funkcję wysyłania żądania HTTP na adres URL i dlatego jest wykorzystywany w żądaniu. Odpowiedź można następnie ocenić za pomocą DOMDocument. Poniższy przykład łączy pokazane wcześniej żądanie "get_active_model" z poleceniami używanymi w VBA:
#kod.vba#
' Uzyskaj aktywny adres URL modelu za pomocą polecenia "get_active_model"
str_envelope =
„" & _
"
& _
" & _
"
& _
' otwórz wniosek i wyślij
request.Open "Post", "http://localhost:8081/", False
request.Send (str_envelope)
' uzyskaj odpowiedź i przekształć ją w obiekt xml
response.LoadXML (request.responseText)
#/kod#
Najpierw zapytanie jest zapisywane w formacie XML w zmiennej "str_envelope", a zapytanie jest otwierane w programie RFEM przy użyciu metody "Open" zmiennej "request". Zawartość zmiennej "str_envelope" może być teraz wysyłana przy użyciu metody "Send". Odpowiedź można uzyskać za pomocą metody "ResponseText". W tym konkretnym przypadku jest on importowany bezpośrednio przy użyciu metody „LoadXML” zmiennej „response”.
Zmienna "response" typu DOMDocuments posiada metodę LoadXML i tym samym może rozpoznać formatowanie XML. Zaletą jest to, że typ DOMDocuments udostępnia również metodę GetElementsByTagName. Pozwala to na wyodrębnianie elementów bezpośrednio z kodu. Poniżej dotychczasowy kod został rozszerzony w taki sposób, że dostępny jest adres URL modelu:
#kod.vba#
' uzyskaj status-http
status = zapytanie.status
Jeżeli status <> "200" Wtedy
MsgBox "get_active_model: Wysyłanie nie powiodło się - " & odpowiedź.Tekst
Wyjście z Sub
End If
url_model = Response.GetElementsByTagName("value")(0) .Text
#/kod#
Przed odczytaniem adresu URL można sprawdzić status odpowiedzi. Są to znormalizowane kody stanu HTTP. Status "200" oznacza, że transfer przebiegł "OK". Po tym zapytaniu adres URL modelu jest zapisywany w ciągu znaków url_model. W tym celu w odpowiedzi XML wyszukiwany jest element "value". Jeżeli odpowiedź zawiera kilka elementów, wszystkie wartości są zapisywane w sekcji "wartość", tak że nie jest możliwe obliczenie za pomocą identyfikatora "wartość", ale odwoływane są podelementy "wartość". Więcej informacji na praktycznym przykładzie. W przypadku adresu modelu jedyną zwracaną wartością jest adres URL, dlatego tutaj "wartość" jest pomyślna.
== Praktyczny przykład w VBA ==
Teraz, gdy znamy wszystkie podstawowe elementy, mamy prosty przykład. Chcemy utworzyć belkę na dwóch słupach, do której można przyłożyć obciążenie prętowe.
Najpierw definiowane i inicjalizowane są zmienne opisane powyżej:
#kod.vba#
'zdefiniuj zmienne
Żądanie przyciemnienia As MSXML2.XMLHTTP60
Odpowiedź Dim As MSXML2.DOMDocument60
Dim str_envelope As String
Dim url_app As String
Dim url_model As String
' zmienne początkowe
Ustaw żądanie = Nowy MSXML2.XMLHTTP60
Ustaw odpowiedź = Nowy MSXML2.DOMDocument60
Z odpowiedzią
.async = False
.preserveWhiteSpace = False
.validateOnParse = False
.resolveExternals = False
' Użyj pełnej funkcjonalności XPath
.SetProperty "SelectionLanguage", "XPath"
' Dodaj określone przestrzenie nazw do pracy ze ścieżkami
.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"" "
Koniec na
url_app = "http://hostlokalny:8081/"
#/kod#
Oprócz zmiennych „request” i „response” tworzony jest ciąg znaków „str_envelope” dla żądania oraz „url_app” i „url_model” dla adresów aplikacji i modelu. Podczas inicjalizacji można przesłać znane specyfikacje protokołu SOAP w celu oceny formatowania XML odpowiedzi. Adres modelu zostanie pobrany później, ale należy podać adres aplikacji. Jak już wspomniano, należy wprowadzić domyślny adres "http://localhost:8081/".
Kolejnym krokiem jest przetestowanie połączenia z aplikacją. Na potrzeby tego testu standardowe informacje o aplikacji są wyszukiwane za pomocą polecenia "get_information":
#kod.vba#
' sprawdź adres URL aplikacji za pomocą polecenia "get_information"
str_envelope = "" & _
& _
' otwórz wniosek i wyślij
request.Open "Post", url_app, False
request.Send (str_envelope)
' uzyskaj odpowiedź i przekształć ją w obiekt xml
response.LoadXML (request.responseText)
' uzyskaj status-http
status = zapytanie.Status
Jeżeli status <> "200" Wtedy
MsgBox "get_information: Wysyłanie nie powiodło się - " & odpowiedź.Tekst
Wyjście z Sub
End If
' odczyt informacji o aplikacji
Dim str1 As String
pozycja1 = ""
słowo1 = słowo1 i odpowiedź.GetElementsByTagName("name")(0).Text & vbLf
słowo1 = słowo1 i odpowiedź.GetElementsByTagName("type")(0).Text & vbLf
słowo1 = słowo1 i odpowiedź.GetElementsByTagName("version")(0).Text & vbLf
słowo1 = słowo1 i odpowiedź.GetElementsByTagName("language_name")(0).Text & vbLf
słowo1 = słowo1 i odpowiedź.GetElementsByTagName("language_id")(0).Text
MsgBox str1, vbInformation, "Odpowiedź na żądanie ""get_information"""
#/kod#
Jak już opisano w pierwszej części, żądanie w formacie XML jest przygotowywane i zapisywane w "str_envelope". "request.Open" otwiera połączenie z aplikacją. Słowo kluczowe „Post” oznacza wysłanie zapytania. Trzeci parametr zostaje ustawiony na „prawda”, dzięki czemu realizowana jest transmisja synchroniczna. Na koniec "request.Send" wysyła przygotowany ciąg znaków.
Po wysłaniu odpowiedź jest zapisywana w "odpowiedzi" i sprawdzana przez "request.Status", czy żądanie się powiodło. Status jest przydzielany przez program RFEM, a w przypadku nieprawidłowego żądania zwracany jest błąd; na przykład nieznane polecenie. Jeżeli status nie jest "200", program zostanie przerwany, a błąd zostanie wyświetlony w oknie (MsgBox).
Jeżeli nie wystąpiły żadne błędy, za pomocą funkcji „GetElementsByTagName” można odczytać różne przesyłane informacje. W konkretnym przykładzie informacje są wyświetlane w oknie.
Poniższe elementy są bardzo podobne, dlatego opisane są tylko specjalne funkcje (kompletny kod źródłowy można pobrać). Aby ustawić belkę na dwóch słupach z obciążeniem prętowym, wymagane są następujące funkcje:
# Węzeł – zbiór_węzeł
# Linia – zbiór_linii
# Materiał – zbiór_materiału
# Przekrój – zbierz_przekrój
# Pręt – zbiór_pręt
# Podpora węzłowa – set_nodal_support
# Parametry obliczeń - ustawienia_analizy_zbioru
# Przypadek obciążenia – set_load_case
# Obciążenie prętowe - set_member_load
Jak większość innych funkcji, funkcja "set_node" ma wiele parametrów, ale zazwyczaj nie są one wymagane. We wspomnianej już liście poleceń modelu RFEM można zobaczyć różnorodność parametrów. Ważne są przede wszystkim parametry, które nie są oznaczone jako „opcjonalne”, ponieważ należy je uzupełnić w każdym przypadku. W tym przykładzie przenoszone są następujące parametry:
#kod.vba#
Begin_modification (url_model)
' ustaw węzeł 1 na [0,0,0] za pomocą polecenia "set_node"
str_envelope =
„" & _
"
>" & _
#/kod#
Tylko numer węzła nie jest opcjonalny; resztę można przypisać, ale nie musi. Oprócz możliwych parametrów na liście poleceń wyświetlane są również zestawienia typów. W tym konkretnym przypadku obecnie dostępnych jest pięć różnych typów. Wybrano domyślny typ "TYPE_STANDARD". Pokazany tutaj pierwszy węzeł jest utworzony w położeniu (0; 0; 0), drugi węzeł w położeniu (5.5; 0; 0). Wartości liczb dziesiętnych są następujące:
#kod.vba#
...
"" & _
"2" & _
"TYPE_STANDARD" & _
"5.5" & _
"0" & _
"0" & _
"" & _
...
#/kod#
Kolejną cechą szczególną są listy. Linia potrzebuje dwóch węzłów, których numery można przenieść w postaci listy. Elementy listy, takie jak "definicja_węzły", są oddzielone spacjami:
#kod.vba#
...
„" & _
"" & _
"1" & _
"TYPE_POLYLINE" & _
"1 2" & _
"" & _
"" & _
...
#/kod#
Aby móc utworzyć pręt, należy utworzyć przekrój, co z kolei wymaga materiału. Można korzystać z przekrojów i materiałów z wewnętrznej bazy danych. Dlatego wystarczy podać znany identyfikator. W przypadku materiału identyfikatorem jest "S235", a przekrój ma nazwę "IPE 300":
#kod.vba#
...
„" & _
"" & _
"1" & _
"1" & _
"TYPE_STANDARDIZED_STEEL" & _
"IPE 300" & _
"" & _
"" & _
...
#/kod#
Aby sprawdzić, czy nazwa taka jak "IPE 300" jest prawidłowa, można użyć wpisu w graficznym interfejsie użytkownika.
Aby wprowadzić sam pręt, nie jest wymagana dalsza wiedza, ale aby wprowadzić utwierdzoną podporę, należy zdefiniować "nieskończoną" sztywność sprężystą. Do transferu używane jest słowo kluczowe "INF":
#kod.vba#
...
"" & _
"" & _
"1" & _
"1" & _
"INF" & _
"INF" & _
"spring_z>INF" & _
"" i _
"0" & _
"" i _
"" & _
"" & _
...
#/kod#
Tworzenie przypadku obciążenia i parametrów obliczeniowych nie wymaga dodatkowej wiedzy. Ostatnia osobliwość stanowi wartość dodatkową podczas tworzenia obciążenia, ponieważ musi zostać zdefiniowana poza obszarem "". W przypadku obciążenia prętowego należy tam przenieść odpowiedni przypadek obciążenia:
#kod.vba#
...
„" & _
"1" & _
"" & _
"1" & _
"LOAD_TYPE_FORCE" & _
"1" & _
"LOAD_DISTRIBUTION_UNIFORM" & _
"LOAD_DIRECTION_GLOBAL_Z_OR_USER_DEFINED_W_TRUE" & _
"1000" & _
"" & _
"" & _
...
#/kod#
Ponadto należy wspomnieć, że kolejność elementów w obszarze „wartość” jest nieistotna, ale nie poza obszarem. Określony przypadek obciążenia musi zatem pojawić się przed polem „wartość”.
Oprócz poprzednich funkcji służących do tworzenia i eksportowania danych, w tym miejscu zostaną przedstawione dwie funkcje specjalne. Jeżeli elementy są przeniesione do programu, program automatycznie przechodzi w tryb "Modyfikacji". Program sprawdza i integruje nowe elementy. Jeżeli ma zostać utworzonych kilka nowych elementów, dobrze jest pozostawić program tymczasem w tym trybie edycji, aby przyspieszyć obróbkę. W tym celu dostępne są funkcje "begin_modification" i "finish_modification".
W tym przykładzie, "begin_modification" jest wywoływane przed utworzeniem pierwszego węzła, a "finish_modification" jest wywoływane na końcu po utworzeniu przypadku obciążenia. Obie funkcje zostały również utworzone jako funkcje VBA w programie. Funkcje te są niezależne, dlatego też zmienne "request" i "response" są ponownie tworzone w obrębie funkcji. Ponieważ jednak nie są do tego wymagane żadne nowe elementy, nie będą one tutaj omawiane. Ciekawym porównaniem jest porównanie z wykorzystaniem i bez tych funkcji, które zawsze będzie skutkować różnicą prędkości.
== Uwagi końcowe ==
Webservice API to wydajne narzędzie dla programów RFEM i RSTAB. Prosty transfer oparty na protokole HTTP umożliwia implementację interfejsu w wielu językach programowania, nie tylko w VBA, jak pokazano tutaj, a także programowanie międzyplatformowe.