5671x
001738
2022-03-23

Tutorial de serviço web e API em VBA

O serviço web é uma comunicação entre máquinas e programas. Esta comunicação é fornecida através da rede e pode, portanto, ser utilizada por qualquer programa que permita enviar e receber strings através do protocolo HTTP. O RFEM 6 e o RSTAB 9 disponibilizam uma interface baseada nestes serviços web multiplataforma. Este tutorial mostra as noções básicas utilizando a linguagem de programação VBA.

Noções básicas da API de serviço web usando o exemplo do VBA

Para a formatação da string, é utilizado o formato XML de acordo com as especificações do protocolo SOAP. A seguinte consulta serve de exemplo:

<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<Corpo>
<get_active_model xmlns="http://www.dlubal.com/rfem.xsd"/>
</Body>
</Envelope>

Um elemento típico da formatação XML é o início de uma secção com o carácter "<". Isto é seguido de um identificador e, se não houver mais elementos subordinados, a secção é terminada com "/>". Um exemplo é a terceira linha:

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

Se existem subelementos, este inicia com "<", o comando e ">" e termina com "</", o comando e ">". O exemplo apropriado é a secção "Corpo":

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

A formatação com espaços e quebras de linha é utilizada aqui apenas para fins ilustrativos. Esse tipo de letra não é necessário para a transferência. Os elementos "Corpo" e "Envolvente" são elementos padrão para a transferência e são utilizados para cada comando.

Todos os comandos disponíveis podem ser lidos utilizando a interface WSDL. Está disponível um software que pode ser utilizado para criar listas. Um exemplo de software desse tipo é o SoapUI. Existem duas listas para a API do RFEM 6; os comandos para a aplicação e os para o modelo. As duas listas podem ser descarregadas no final deste artigo.

Uma vez que os comandos são enviados através de HTTP, são necessários endereços URL para o endereçamento. O endereço por defeito das aplicações do RSTAB/RFEM é "http://localhost:8081/" e pode ser alterado na configuração do programa. Os modelos abertos são atribuídos aos endereços por ordem ascendente, de forma que o primeiro modelo aberto tem o endereço "http://localhost:8082/". Para obter o endereço do modelo ativo, é enviado o comando "get_active_model". Uma resposta correspondente do RFEM 6 tem a seguinte aparência:

<?xml versão="1.0"?>
<Envelope 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">
<sabão:Corpo>
<n1:get_active_modelResponse
xmlns:n1="http://www.dlubal.com/rfem.xsd">
<valor>
http://127.0.0.1:8082/
</valor>
</n1:get_active_modelResponse>
</soap:Body>
</soap:Envelope>

Os detalhes adicionais da secção "Envolvente" assim como a linha anterior "<?xml versão="1.0"?>" deve mostrar primeiro as normas utilizadas e não será discutida mais tarde aqui. De qualquer forma, pode ver que os elementos "Envolvente" e "Corpo" são novamente utilizados. A resposta do RFEM 6 está contida em "Body" pelo nome de comando "get_active_model" e pela palavra anexada "Response". O conteúdo desta resposta é um "valor", isto é, o endereço do modelo ativo. Além disso, o RFEM está agora bloqueado para acessos adicionais.

No exemplo a seguir, queremos criar uma barra com dois apoios nodais e uma carga. Para poder comunicar com o RFEM através do VBA, são necessários os seguintes objetos:

pedido As MSXML2.XMLHTTP60
resposta As MSXML2.DOMDocument

O objeto XMLHTTP60 tem uma função integrada para enviar um pedido HTTP para um URL e é, portanto, utilizado para o pedido. A resposta pode depois ser avaliada utilizando o DOMDocument. O exemplo a seguir combina a solicitação "get_active_model" exibida anteriormente com os comandos utilizados no VBA:

' obtém a url do modelo ativo com o comando "get_active_model"
str_envelope =
"<Envelope xmlns=""http://schemas.xmlsoap.org/soap/envelope/"">" & _
" <Corpo>" & _
" <get_active_model xmlns=""http://www.dlubal.com/rfem.xsd""/>" & _
" </Body>" & _
"</Envelope>"

' abre o pedido e envia
request.Open "Post", "http://localhost:8081/", False
request.Send (str_envelope)

' obtém resposta e a transforma em um objeto xml
response.LoadXML (request.responseText)

Em primeiro lugar, o pedido é guardado no formato XML na variável "str_envelope" e o pedido é aberto no RFEM utilizando o método "Open" da variável "request". O conteúdo da variável "str_envelope" agora pode ser enviado através do método "Send". A resposta poderá depois ser acedida utilizando o método "ResponseText". Neste caso específico, este é importado diretamente através do método "LoadXML" da variável "response".

A variável "resposta" do tipo DOMDocuments tem o método LoadXML e pode, assim, reconhecer a formatação XML. A vantagem é que o tipo DOMDocuments também fornece o método GetElementsByTagName. Isto permite extrair elementos diretamente do código. Nas seguintes situações, o código anterior é estendido para que o endereço URL do modelo fique disponível:

' obtém status http
estado = pedido.estado
Se estado <> "200" Então
MsgBox "get_active_model: O envio não foi bem-sucedido - " & resposta.Texto
Sub-saída
End If

url_model = resposta.GetElementsByTagName("valor")(0).Texto

Antes de o URL ser lido, o estado da resposta pode ser verificado. São códigos de estado HTTP normalizados. O status "200" significa que a transferência foi "OK". Após esta consulta, o URL do modelo é guardado na string url_model. Para isso, é procurado o elemento "valor" na resposta XML. Se a resposta contém vários elementos, todos os valores são guardados na secção "valor", para que não seja possível qualquer avaliação com o identificador "valor", mas sim os subelementos de "valor". Serão fornecidas mais informações no exemplo prático. No caso do endereço do modelo, o único valor devolvido é o URL, por isso, "valor" é definido com sucesso.

Exemplo prático em VBA

Agora que conhecemos todos os elementos básicos, segue-se um exemplo simples. Queremos criar uma viga constituída por dois pilares aos quais possa ser aplicada uma carga de barra.

Primeiro, as variáveis descritas acima são definidas e inicializadas:

' define as variáveis
Solicitação de escurecimento As MSXML2.XMLHTTP60
Resposta de escurecimento como MSXML2.DOMDocument60

Dim str_envelope As String
Dim url_app como string
Dim url_model como string

' variáveis de inicialização
Definir pedido = novo MSXML2.XMLHTTP60

Definir resposta = novo MSXML2.DOMDocument60
Com resposta
.async = False
.preserveWhiteSpace = False
.validateOnParse = False
.resolveExternals = False
' Usa a funcionalidade completa do XPath
.SetProperty "SelectionLanguage", "XPath"
'Adiciona Namespaces específicos para trabalhar com Caminhos
.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"" "
Terminar com

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

Além das variáveis "request" e "response", é criada a string "str_envelope" para o pedido e "url_app" e "url_model" para os endereços da aplicação e do modelo. Durante a inicialização, as especificações conhecidas do protocolo SOAP podem ser transferidas para avaliar a formatação XML da resposta. O endereço do modelo será utilizado mais tarde, mas o endereço da aplicação tem de ser especificado. Como já mencionado, tem de ser introduzido o endereço predefinido "http://localhost:8081/".

O passo seguinte é testar a ligação à aplicação. Para este teste, as informações padrão da aplicação são consultadas através do comando "get_information":

'verifica a url da aplicação com o comando "get_information"
str_envelope = "<Envelope xmlns=""http://schemas.xmlsoap.org/soap/envelope/"">" & _
" <Corpo>" & _
" <get_information xmlns=""http://www.dlubal.com/rfem.xsd""/>" & _
" </Body>" & _
"</Envelope>"

' abre o pedido e envia
request.Open "Mensagem", url_app, False
request.Send (str_envelope)

' obtém resposta e a transforma em um objeto xml
response.LoadXML (request.responseText)

' obtém status http
estado = pedido.Estado
Se estado <> "200" Então
MsgBox "get_informacao: O envio não foi bem-sucedido - " & resposta.Texto
Sub-saída
End If

'lê as informações da aplicação
Dim str1 as string
str1 = ""
Str1 = Str1 & resposta.GetElementsByTagName("nome")(0).Text & vbLf
Str1 = Str1 & resposta.GetElementsByTagName("tipo")(0).Text & vbLf
Str1 = Str1 & resposta.GetElementsByTagName("versão")(0).Text & vbLf
Str1 = Str1 & resposta.GetElementsByTagName("nome_linguagem")(0).Text & vbLf
Str1 = Str1 & resposta.GetElementsByTagName("id_linguagem")(0).Texto

MsgBox str1, vbInformation, "Resposta ao pedido ""get_information""

Como já descrito na primeira parte, o pedido formatado em XML é preparado e guardado em "str_envelope". "request.Open" abre a ligação à aplicação. A palavra-chave "Post" representa o envio do pedido. O terceiro parâmetro é definido como "true" e, assim, é realizada uma transmissão síncrona. Por fim, "request.Send" envia o texto preparado.

Após a transferência, a resposta é guardada em "resposta" e verificada com "request.Status" se o pedido foi bem-sucedido. O estado é atribuído pelo RFEM para que devolva um erro em caso de pedido errado; por exemplo, um comando desconhecido. Se o estado não for "200", o programa é interrompido e o erro é apresentado numa janela (MsgBox).

Caso não tenham ocorrido erros, as diferentes informações transferidas podem agora ser lidas em voz alta através de "GetElementsByTagName". No exemplo específico, a informação é depois apresentada numa janela.

Os seguintes elementos são muito semelhantes, por isso são descritas apenas funções especiais (o código-fonte completo pode ser descarregado). Para configurar uma viga sobre dois pilares com uma carga de barra, são necessárias as seguintes funções:

  1. Nó - nó_conjunto
  2. Linha - set_line
  3. Material - conjunto_material
  4. Secção - conjunto_secção
  5. Barra - barra_conjunto
  6. Apoio de nó - set_nodal_support
  7. Parâmetros de cálculo - set_static_analysis_settings
  8. Caso de carga - set_load_case
  9. Carga de barra - set_member_load

Como a maioria das outras, a função "set_node" tem muitos parâmetros, mas geralmente não são necessários. Na lista de comandos já mencionada do modelo do RFEM, pode ser visto uma variedade de parâmetros. Acima de tudo, os parâmetros que não estão marcados como "opcionais" são importantes, pois devem ser preenchidos em cada caso. No exemplo, os seguintes parâmetros são transferidos:

modificação_inicial (modelo_url)

' define o nó 1 em [0,0,0] com o comando "set_node"
str_envelope =
"<Envelope xmlns=""http://schemas.xmlsoap.org/soap/envelope/"">" & _
"<Corpo>" & _
"<set_node xmlns=""http://www.dlubal.com/rfem.xsd"">" & _
"<valor xmlns="""">" & _
"<no>1</no>" & _
"<type>TYPE_STANDARD</type>" & _
"<coordenada_1>0</coordenada_1>" & _
"<coordenada_2>0</coordenada_2>" & _
"<coordenada_3>0</coordenada_3>" & _
"</valor>" & _
"</set_node>" & _
"</Body>" & _
"</Envelope>"

Apenas o número do nó não é opcional; o resto pode ser atribuído, mas não tem de ser. Além dos parâmetros possíveis, a lista de comandos também mostra listagens de tipos. Neste caso específico, são atualmente possíveis cinco tipos diferentes. O tipo predefinido "TYPE_STANDARD" foi selecionado. O primeiro nó aqui apresentado é criado na localização (0; 0; 0), o segundo nó em (5.5; 0; 0). Os valores para os números decimais são os seguintes:

...
"<valor xmlns="""">" & _
"<no>2</no>" & _
"<type>TYPE_STANDARD</type>" & _
"<coordenada_1>5.5</coordenada_1>" & _
"<coordenada_2>0</coordenada_2>" & _
"<coordenada_3>0</coordenada_3>" & _
"</valor>" & _
...

As listas são outra função especial. A linha precisa de dois nós, dos quais os números podem ser transferidos como uma lista. Os elementos de uma lista, tais como "nós_de_definição", são separados por espaços:

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

Para poder criar a barra, tem de ser criada uma secção que, por sua vez, requer um material. As secções e os materiais podem ser utilizados a partir da base de dados interna. Por isso, é suficiente especificar um identificador conhecido. Para o material, o identificador é "S235" e a secção tem o nome "IPE 300":

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

Para verificar se um nome como "IPE 300" é válido, pode utilizar a entrada na interface gráfica do utilizador.

Para introduzir a barra em si, não são necessários mais conhecimentos, mas para introduzir um apoio fixo, é necessário definir uma rigidez de mola "infinita". A palavra-chave "INF" é utilizada para a transferência:

...
"<set_nodal_support xmlns=""http://www.dlubal.com/rfem.xsd"">" & _
"<valor xmlns="""">" & _
"<no>1</no>" & _
"<nós>1</nós>" & _
"<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>" & _
"</valor>" & _
"</set_nodal_support>" & _
...

A criação do caso de carga e dos parâmetros de cálculo não requer nenhum conhecimento adicional. A última particularidade é um valor adicional ao criar a carga, porque tem de ser especificado fora da área "<valor>". No caso de uma carga de barra, o caso de carga correspondente tem de ser transferido para lá:

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

Além disso, importa mencionar que a ordem dos elementos dentro da área "valor" é irrelevante, mas fora dela não é. O caso de carga especificado tem, portanto, de vir antes da área "valor".

Além das funções anteriores para criar e exportar dados, existem duas funções especiais que serão apresentadas aqui. Se são transferidos elementos para o programa, o programa entra automaticamente no modo "Alteração". O programa verifica os novos elementos e integra-os. Se estão para ser criados vários elementos novos, é, portanto, útil deixar para este momento o programa neste modo de edição, para que o processamento seja mais rápido. As funções "modificação_início" e "modificação_fim" estão disponíveis para este fim. No exemplo, "modificação_begin" é chamado antes de criar o primeiro nó e "modificação_fim" é chamado no final após criar o caso de carga. Ambas as funções foram também criadas como funções VBA no programa. As funções são independentes e, por isso, as variáveis "pedido" e "resposta" são criadas novamente nas funções. No entanto, uma vez que não são necessários elementos novos para isso, os mesmos não serão aqui descritos. Uma comparação interessante é aquela com e sem a utilização destas funções, que resultará sempre numa diferença de velocidade.

Resumo

O Serviço web e API é uma ferramenta poderosa para o RFEM e o RSTAB. A transferência simples baseada em HTTP permite que a interface seja implementada em várias linguagens de programação, não apenas em VBA como aqui apresentado, mas também é possível uma programação entre plataformas.


Autor

O Eng. Günthel opera na área do apoio técnico para clientes.

Ligações
Downloads