8819x
001738
2025-06-09

Руководство по веб-сервису API в VBA

Веб-сервис — это коммуникация между машинами или программами. Это взаимодействие осуществляется через сеть и может использоваться любой программой, которая может отправлять и получать строки через HTTP-протокол. RFEM 6 и RSTAB 9 предлагают интерфейс на основе этих кроссплатформенных веб-сервисов. Этот учебник должен показать основы на примере языка программирования VBA.

Основа 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" прочитать различные переданные данные. В конкретном примере информация затем отображается в окне.

Следующие элементы имеют большую схожесть, поэтому рассматриваются только особенности (полный исходный код доступен для загрузки). Для создания балки на двух опорах со стержневой нагрузкой нужны следующие функции:

  1. Узел – set_node
  2. Линия – set_line
  3. Материал – set_material
  4. Сечение – set_section
  5. Стержень – set_member
  6. Узловая поддержка – set_nodal_support
  7. Параметры расчета – set_static_analysis_settings
  8. Случай нагрузки – set_load_case
  9. Стержневая нагрузка – 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" & _
        "" & _
    "" & _
…

Создание случая нагрузки и параметров расчета не требует дополнительных знаний. Последняя особенность – это дополнительное значение при создании нагрузки, так как оно должно быть указано вне секции "". В случае стержневой нагрузки соответствующий случай нагрузки указывается там:

…
    "" & _
        "1" & _
        "" & _
            "1" & _
            "LOAD_TYPE_FORCE" & _
            "1" & _
            "LOAD_DISTRIBUTION_UNIFORM" & _
            "LOAD_DIRECTION_GLOBAL_Z_OR_USER_DEFINED_W_TRUE" & _
            "1000" & _
        "" & _
    "" & _
…
Стоит также отметить, что порядок элементов внутри секции "value" не имеет значения, но вне нее важен. Указанный случай нагрузки должен находиться перед секцией "value". Помимо предыдущих функций для создания и считывания данных, существуют еще две особые функции, которые стоит упомянуть. Когда программе передаются элементы, она автоматически переходит в режим "Modification" (режим редактирования). Программа проверяет новые элементы и обрабатывает их. Если нужно создать несколько новых элементов, имеет смысл оставить программу в этом режиме на это время, чтобы обработка была быстрее. Для этой цели существуют функции "begin_modification" и "finish_modification". В примере "begin_modification" вызывается перед созданием первого узла, а "finish_modification" – после создания случая нагрузки. Эти функции также создаются в программе как функции VBA. Они автономны, поэтому в них снова создаются переменные "request" и "response". Поскольку для этого не нужны новые элементы, дальнейшее обсуждение этой темы здесь не требуется. Интересно сравнение с и без использования этих функций, который всегда дает разницу в скорости. == Заключение == Webservice API – это мощный инструмент для RFEM и RSTAB. Простая HTTP-основная передача позволяет реализовать этот интерфейс во многих языках программирования, а не только в VBA, как показано здесь, и сделать возможным платформенно независимое программирование.


Автор

Г-н Гюнтель осуществляет техническую поддержку пользователей Dlubal Software.

Ссылки
Скачивания


;