Основа Webservice API на примере VBA
Для форматирования строк используется XML-формат в соответствии со спецификациями протокола SOAP. Примером может служить следующий запрос:
<Body>
</Body>
Типичным элементом XML-форматирования является начало секции с символом "<". После него следует идентификатор и, если не следует никаких дополнительных элементов, секция завершается символом "/>". Примером является третья строка:
Если существуют подэлементы, секция начинается с "<", команды и ">", и завершается "</", командой и ">". Примером подходит секция "Body":
<Body>
</Body>
Форматирование с помощью пробелов и разрывов строк здесь служит только для наглядности. Для передачи это не требуется. Элементы "Body" и "Envelope" являются стандартными элементами для передачи и используются для каждой команды.
Все доступные команды можно прочитать с помощью интерфейса WSDL. Существуют программы, которые позволяют создавать списки из этих команд. Одной из таких программ является SoapUI. Для API RFEM 6 существуют два списка, один для команд приложения и один для команды модели. Оба списка можно скачать в конце этой статьи.
Поскольку команды отправляются по HTTP, для обращения к ним требуется URL-адрес. Стандартный адрес приложений RSTAB/RFEM - "localhost:8081" и его можно изменить в настройках программы.
Открытые модели получают последовательно увеличивающиеся адреса, так что первая открытая модель имеет адрес "localhost:8082".
Чтобы получить адрес активной модели, отправляется команда "get_active_model". Соответствующий ответ от RFEM 6 выглядит так:
http://127.0.0.1:8082/
Дополнительные детали секции "Envelope" (с английского: конверт) и предваряющая строка "<?xml version="1.0"?>" показывают используемые стандарты и не обсуждаются здесь далее. В любом случае можно увидеть, что снова используются элементы "Envelope" и "Body". Внутри "Body" находится ответ RFEM 6 с именем команды "get_active_model" и присоединенным словом "Response". Содержанием этого ответа является значение ("value") - адрес активной модели. Кроме того, RFEM теперь заблокирован для дальнейших доступов.
В следующем примере будет создан стержень с двумя узловыми поддержками и нагрузкой. Чтобы взаимодействовать с RFEM через VBA, требуются следующие объекты:
request As MSXML2.XMLHTTP60
response As MSXML2.DOMDocument
Объект XMLHTTP60 имеет встроенную функцию для отправки HTTP-запроса по URL и поэтому используется для запроса. Ответ затем можно оценить с помощью DOMDocuments. Следующий пример объединяет ранее показанный запрос "get_active_model" с командами, используемыми в 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)
Сначала запрос в XML-формате сохраняется в переменной "str_envelope" и с помощью метода "Open" переменной "request" открывается запрос к RFEM. С помощью метода "Send" теперь можно отправить содержимое переменной "str_envelope". Ответ можно затем получить через метод "ResponseText". В данном случае он читается напрямую в переменную "response" с помощью метода "LoadXML".
Переменная "response" типа DOMDocuments имеет метод LoadXML и может распознать XML-форматирование. Преимущество заключается в том, что тип DOMDocuments также предоставляет метод GetElementsByTagName. Это позволяет напрямую извлекать элементы из кода. Далее будет дополнен предыдущий код, так что адрес URL модели станет доступен:
' 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
Прежде чем читать URL, можно проверить статус ответа. Это стандартизированные HTTP-коды статуса. Статус "200" означает, что передача "ОК". После этой проверки в строковую переменную url_model сохраняется URL модели. Для этого в XML-ответе ищется элемент "value". Если ответ содержит несколько элементов, все значения в секции "value" сохраняются, так что здесь нельзя использовать идентификатор "value", а нужно обращаться к подэлементам "value". Подробнее об этом в практическом примере. В случае адреса модели единственным возвращаемым значением является URL, так что "value" здесь приведет к успеху.
Практический пример на VBA
Теперь, когда известны все базовые элементы, следует простой пример. Следует создать балку на двух опорах, на которой можно приложить стержневую нагрузку.
Сначала определяются и инициализируются уже представленные переменные:
' 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/"
Помимо переменных "request" и "response", создаются строковая переменная "str_envelope" для запроса и "url_app" и "url_model" для адресов приложения и модели. При инициализации могут быть переданы известные спецификации протокола SOAP для оценки XML-форматирования ответа. Адрес модели будет получен позже, но адрес приложения должен быть указан. Как и упоминалось ранее, необходимо указать стандартный адрес:
На следующем шаге необходимо проверить соединение с приложением. Для этого теста с помощью команды "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"
Как уже было описано в первой части, сначала готовится запрос в формате XML и сохраняется в "str_envelope". "request.Open" открывает соединение с приложением. Ключевое слово "Post" означает отправку запроса. Третий параметр установлен на "true", что означает, что выполняется синхронная передача. Затем "request.Send" отправляет подготовленную строку.
После передачи ответ сохраняется в "response" и с помощью "request.Status" проверяется, был ли запрос успешным. Статус назначается RFEM, так что если запрос был ошибочным, например, неизвестная команда, RFEM возвращает ошибку. Если статус не "200", программа прекращает работу и ошибка отображается в окне (MsgBox).
Если ошибок не возникло, теперь можно с помощью "GetElementsByTagName" прочитать различные переданные данные. В конкретном примере информация затем отображается в окне.
Следующие элементы имеют большую схожесть, поэтому рассматриваются только особенности (полный исходный код доступен для загрузки). Для создания балки на двух опорах со стержневой нагрузкой нужны следующие функции:
- Узел – set_node
- Линия – set_line
- Материал – set_material
- Сечение – set_section
- Стержень – set_member
- Узловая поддержка – set_nodal_support
- Параметры расчета – set_static_analysis_settings
- Случай нагрузки – set_load_case
- Стержневая нагрузка – set_member_load
Функция "set_node" имеет, как и большинство других, много параметров, но в обычном случае они не требуются. В уже упомянутом списке команд модели RFEM можно увидеть разнообразие параметров. Важны прежде всего параметры, у которых нет пометки "optional", потому что они должны быть обязательно заполнены. В примере переданы следующие параметры:
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>>" & _
" "
Единственным необязательным здесь является номер узла, остальное можно задать. В списке команд кроме возможных параметров также представлены списки для типов. В конкретном случае возможно пять разных типов. Был выбран стандартный тип "TYPE_STANDARD". Здесь показан первый узел, создаваемый в точке (0;0;0), второй узел в точке (5,5;0;0). Значения с десятичными числами выглядят следующим образом:
…
"" & _
"2 " & _
"TYPE_STANDARD " & _
"5.5 " & _
"0 " & _
"0 " & _
" " & _
…
Еще одной особенностью являются списки. Линия требует двух узлов, номера которых можно передать в виде списка. Элементы списка, как здесь "definition_nodes", разделяются пробелами:
…
"" & _
"" & _
"1 " & _
"TYPE_POLYLINE " & _
"1 2 " & _
" " & _
" " & _
…
Чтобы создать стержень, необходимо создать сечение, которое в свою очередь требует материала. Сечения и материалы могут использоваться из внутренней базы данных. Поэтому достаточно указать известный идентификатор. Для материала используется идентификатор "S235", а для сечения используется имя "IPE 300":
…
"" & _
"" & _
"1 " & _
"1 " & _
"TYPE_STANDARDIZED_STEEL " & _
"IPE 300 " & _
" " & _
" " & _
…
Для проверки, допустимо ли имя "IPE 300", можно воспользоваться вводом в графическом интерфейсе.
Для введения самого стержня не требуется дополнительных знаний, однако для ввода фиксированной поддержки необходимо определить "бесконечную" жесткость пружины. Для передачи используется ключевое слово "INF":
…
"" & _
"" & _
"1 " & _
"1 " & _
"INF " & _
"INF " & _
"INF " & _
"INF " & _
"0 " & _
"INF " & _
" " & _
" " & _
…
Создание случая нагрузки и параметров расчета не требует дополнительных знаний. Последняя особенность – это дополнительное значение при создании нагрузки, так как оно должно быть указано вне секции "…
"