5561x
001738
2022-03-23

VBA 中的教程 Web 服务 API

网络服务是机器和程序之间的一种通信。 这种通信是通过网络进行的,因此任何可以通过 HTTP 协议发送和接收字符串的程序都可以使用。 在 RFEM 6 和 RSTAB 9 中基于这些跨平台的网络服务提供了一个接口。 本教程将介绍如何使用 VBA 编程语言。

Webservice API基础知识使用VBA示例

对于字符串的格式设置,按照 SOAP 协议的规范使用 XML 格式。 以下查询作为示例:

<信封 xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<主体>
<get_active_model xmlns="http://www.dlubal.com/rfem.xsd"/>
</正文>
</信封>

XML 格式设置的一个典型元素是具有“<”字符的部分的开头。 然后是标识符,如果没有其他从属元素,则以“/>”结尾。 第三行是一个示例:

<get_active_model xmlns="http://www.dlubal.com/rfem.xsd"/>

如果有子元素,则以“<”、命令和“>”开头,以“</”、命令和“>”结束。 相应的示例是“主体”部分:

<主体>
<get_active_model xmlns="http://www.dlubal.com/rfem.xsd"/>
</正文>

此处使用空格和换行符的格式仅用于说明目的。 这不是传输所必需的。 “主体”和“包络”单元是标准的传递单元,用于每个命令。

所有可用的命令都可以通过 WSDL 接口读取。 可以使用软件来创建列表。 此类软件的一个示例是 SoapUI。 RFEM 6 的 API 有两个列表;应用程序的命令和模型的命令。 两个列表都可以在文末下载。

由于命令是通过 HTTP 发送的,因此寻址时需要使用 URL 地址。 RSTAB/RFEM 应用程序的默认地址是“http://localhost:8081/”,并且可以在程序的设置中进行更改。 打开的模型按照升序分配地址,第一个打开的模型的地址为“http://localhost:8082/”。 要获取激活模型的地址,请发送“get_active_model”命令。 RFEM 6 的相应响应如下所示:

<?xml 版本="1.0"?>
<信封 xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<肥皂:主体>
<n1:get_active_modelResponse
xmlns:n1="http://www.dlubal.com/rfem.xsd">
<值>
http://127.0.0.1:8082/
</value>
</n1:get_active_modelResponse>
</soap:Body>
</soap:信封>

“包络”部分的附加详细信息 以及前面的 "<?xml version="1.0"?>" 行应该首先显示使用的标准,这里不再赘述。 在任何情况下,您都可以看到再次使用了“包络”和“主体”元素。 RFEM 6 的响应包含在“主体”中,命令名称为“get_active_model”,并且附加了单词“Response”。 该响应的内容是一个“值”,即当前模型的地址。 此外,RFEM 现在已被锁定,无法进一步访问。

在下面的示例中,我们要创建一个杆件,该杆件具有两个节点支座和一个荷载。 为了能够通过 VBA 与 RFEM 进行通信,需要以下对象:

请求格式为 MSXML2.XMLHTTP60
响应为 MSXML2.DOMDocument

XMLHTTP60 对象具有用于向 URL 发送 HTTP 请求的内置函数,因此可以用于请求。 然后可以使用 DOMDocument 评估响应。 以下示例将前面显示的“get_active_model”请求与在 VBA 下使用的命令相结合:

' 使用 "get_active_model" 命令获取当前模型的 url
str_envelope =
"<Envelope xmlns=""http://schemas.xmlsoap.org/soap/envelope/"">" & _
" <主体>" & _
" <get_active_model xmlns=""http://www.dlubal.com/rfem.xsd""/>" & _
" </正文>" & _
"</信封>"

' 打开请求并发送
request.Open "发布", "http://localhost:8081/", False
request.Send(str_envelope)

' 获取响应并将其转换为 xml 对象
response.LoadXML(request.responseText)

首先,请求以 XML 格式保存在“str_envelope”变量中,然后在 RFEM 中使用“request”变量的“打开”方法打开请求。 现在可以使用“发送”方法发送变量“str_envelope”的内容。 然后可以使用“ResponseText”方法访问响应。 在这种情况下,它是通过“response”变量的方法“LoadXML”直接导入的。

DOMDocuments 类型的“response”变量具有 LoadXML 方法,因此可以识别 XML 格式。 优点是 DOMDocuments 类型还提供了 GetElementsByTagName 方法。 这允许您直接从代码中提取元素。 下面对前面的代码进行扩展,得到模型的URL地址:

' 获取 http 状态
status = request.status
如果状态 <> "200" 则
MsgBox "get_active_model: 发送失败 - " & response.Text
出口接头
End If

url_model = response.GetElementsByTagName("value")(0).Text

在读取 URL 之前,可以检查响应的状态。 它们是标准化的 HTTP 状态代码。 状态“200”表示传输“正常”。 查询完成后,模型的 URL 保存在 url_model 字符串中。 为此,在 XML 响应中搜索“value”元素。 如果答案包含多个元素,则所有值都保存在“值”部分中,因此无法使用标识符“值”进行评估,但会寻址“值”的子元素。 更多信息将在实际示例中提供。 在模型地址的情况下,唯一的返回值是URL,所以这里的“value”是成功的。

VBA 实例

现在我们已经了解了所有基本元素,下面是一个简单的示例。 我们想在两根柱子上创建一个梁,在该柱子上可以施加杆件荷载。

首先定义和初始化上述变量:

' 定义变量
尺寸要求 As MSXML2.XMLHTTP60
响应暗淡 As MSXML2.DOMDocument60

将 str_envelope 作为字符串变暗
将 url_app 变暗为字符串
将 url_model 变暗为字符串

' 初始化变量
设置请求 = 新建 MSXML2.XMLHTTP60

设置响应 = 新建 MSXML2.DOMDocument60
有反应
.async = False
.preserveWhiteSpace = False
.validateOnParse = False
.resolveExternals = False
' 使用完整的 XPath 功能
.SetProperty "SelectionLanguage", "XPath"
' 添加特定的命名空间以使用路径
.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"" "
结束于

url_app = "http://localhost:8081/"

除了变量“request”和“response”之外,还为请求创建字符串“str_envelope”,并为应用程序和模型的地址创建“url_app”和“url_model”。 在初始化期间,可以调用 SOAP 协议的已知规范来评估响应的 XML 格式。 模型的地址将在后面使用,但必须指定应用程序的地址。 如前所述,必须输入默认地址“http://localhost:8081/”。

下一步是测试与应用程序的连接。 对于该测试,使用“get_information”命令查询应用程序的标准信息:

' 使用命令 "get_information" 检查应用程序的 url
str_envelope = "<信封 xmlns=""http://schemas.xmlsoap.org/soap/envelope/"">" & _
" <主体>" & _
" <get_information xmlns=""http://www.dlubal.com/rfem.xsd""/>" & _
" </正文>" & _
"</信封>"

' 打开请求并发送
request.Open "发布", url_app, False
request.Send(str_envelope)

' 获取响应并将其转换为 xml 对象
response.LoadXML(request.responseText)

' 获取 http 状态
状态 = 请求.状态
如果状态 <> "200" 则
MsgBox "获取信息: 发送失败 - " & response.Text
出口接头
End If

' 读取应用程序信息
将 str1 作为字符串变暗
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, "对 ""get_information"" 请求的响应"

如第一部分所述,XML格式的请求被准备并保存在“str_envelope”中。 “request.Open”打开与应用程序的连接。 关键字“Post”表示请求的发送。 第三个参数设为“true”,即进行同步传输。 最后,“request.Send”发送准备好的字符串。

传输完成后,响应保存在“response”中,并通过“request.Status”检查请求是否成功。 状态由 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 模型命令列表中,您可以看到各种参数。 最重要的是没有标记为“可选”的参数,因为它们必须分别填写。 在示例中将传递以下参数:

begin_modification (url_model)

' 使用 "set_node" 命令在 [0,0,0] 上设置节点 1
str_envelope =
"<Envelope xmlns=""http://schemas.xmlsoap.org/soap/envelope/"">" & _
"<主体>" & _
"<set_node xmlns=""http://www.dlubal.com/rfem.xsd"">" & _
"<值 xmlns="""">" & _
"<no>1</no>" & _
"<type>TYPE_STANDARD</type>" & _
"<coordinate_1>0</coordinate_1>" & _
"<coordinate_2>0</coordinate_2>" & _
"<coordinate_3>0</coordinate_3>" & _
"</value>" & _
"</set_node>" & _
"</Body>" & _
"</信封>"

只有节点编号不是可选的;其余的可以分配,但不是必须的。 除了可能的参数外,命令列表还显示类型列表。 在这种情况下,目前有五种不同的类型是可能的。 已选择默认类型“TYPE_STANDARD”。 第一个节点创建在位置 (0; 0; 0),第二个节点创建在 (5.5; 0; 0)。 十进制数的值如下所示:

...
"<值 xmlns="""">" & _
"<no>2</no>" & _
"<type>TYPE_STANDARD</type>" & _
"<coordinate_1>5.5</coordinate_1>" & _
"<coordinate_2>0</coordinate_2>" & _
"<coordinate_3>0</coordinate_3>" & _
"</value>" & _
...

列表是另一个特殊功能。 该线需要两个节点,其编号可以作为列表传递。 列表的元素,例如 "definition_nodes",用空格分隔:

...
"<set_line xmlns=""http://www.dlubal.com/rfem.xsd"">" & _
"<值 xmlns="""">" & _
"<no>1</no>" & _
"<type>TYPE_POLYLINE</type>" & _
"<definition_nodes>1 2</definition_nodes>" & _
"</value>" & _
"</set_line>" & _
...

为了能够创建杆件,必须先创建一个截面,然后再创建一个材料。 可以使用内部数据库中的截面和材料。 因此,指定一个已知的标识符就足够了。 对于材料,标识符为“S235”,截面名称为“IPE 300”:

...
"<set_section xmlns=""http://www.dlubal.com/rfem.xsd"">" & _
"<值 xmlns="""">" & _
"<no>1</no>" & _
"<材料>1</材料>" & _
"<type>TYPE_STANDARDIZED_STEEL</type>" & _
"<name>IPE 300</name>" & _
"</value>" & _
"</set_section>" & _
...

要检查名称(例如“IPE 300”)是否有效,请使用图形用户界面中的条目。

输入杆件本身不需要任何知识,但要输入固定支座,则必须定义一个“无限大”的弹簧刚度。 使用关键字“INF”进行传递:

...
"<set_nodal_support xmlns=""http://www.dlubal.com/rfem.xsd"">" & _
"<值 xmlns="""">" & _
"<no>1</no>" & _
"<nodes>1</nodes>" & _
"<spring_x>INF</spring_x>" & _
"<spring_y>INF</spring_y>" & _
"<spring_z>INF</spring_z>" & _
"<rotational_restraint_x>INF</rotational_restraint_x>" & _
"<rotational_restraint_y>0</rotational_restraint_y>" & _
"<rotational_restraint_z>INF</rotational_restraint_z>" & _
"</value>" & _
"</set_nodal_support>" & _
...

创建荷载工况和计算参数不需要任何额外的知识。 最后一个特点是创建荷载时的附加值,因为它必须在“<值>”区域之外指定。 对于杆件荷载,必须将相应的荷载工况传递到该位置:

...
"<set_member_load xmlns=""http://www.dlubal.com/rfem.xsd"">" & _
"<load_case_no xmlns="""">1</load_case_no>" & _
"<值 xmlns="""">" & _
"<no>1</no>" & _
"<load_type>LOAD_TYPE_FORCE</load_type>" & _
"<members>1</members>" & _
"<load_distribution>LOAD_DISTRIBUTION_UNIFORM</load_distribution>" & _
"<load_direction>LOAD_DIRECTION_GLOBAL_Z_OR_USER_DEFINED_W_TRUE</load_direction>" & _
"<magnitude>1000</magnitude>" & _
"</value>" & _
"</set_member_load>" & _
...

另外需要说明的是,“值”区域内的元素的顺序是无关紧要的,而在“值”区域外则不然。 因此,指定的荷载工况必须位于“值”区域之前。

除了前面介绍的创建和导出数据的功能外,这里还将介绍两个特殊功能。 如果将元素传送到程序中,程序将自动进入“修改”模式。 程序会检查新的元素并将其集成。 如果要创建多个新元素,那么此时最好将程序保留在该编辑模式下,以便更快地进行处理。 为此可以使用函数“begin_modification”和“finish_modification”。 在示例中,在创建第一个节点之前调用“begin_modification”,在创建荷载工况后调用“finish_modification”。 这两个函数也是在程序中作为 VBA 函数创建的。 这些功能是独立的,因此在功能内部重新创建了变量“请求”和“响应”。 但是,由于不需要新的元件,所以在此不再赘述。 一个有趣的比较是使用和不使用这些功能,这总是会导致速度差异。

小结

网络服务 API 是 RFEM 和 RSTAB 功能强大的工具。 通过简单的基于 HTTP 的传输,该接口不仅可以使用 VBA 实现,还可以使用多种编程语言实现,并且可以进行跨平台编程。


作者

Günthel 先生为Dlubal 软件客户提供技术支持。

链接
下载