A classe TWsdlManager faz o tratamento para arquivos WSDL (Web Services Description Language). Esta classe implementa métodos para identificação das informações de envio e resposta das operações definidas, além de métodos para envio e recebimento do documento SOAP.
Hierarquia
- TWsdlManager
Construtores
Propriedades
Métodos
Observações
A classe trabalha com 2 tipos de dados: os tipos complexos, que são as seções do XML, e os tipos simples, que são as tags que recebem valor. Por exemplo, numa operação de inserção de clientes, a tag "cliente" é um tipo complexo, pois contém os dados do cliente dentro, e a tag "nome" é um tipo simples, pois recebe diretamente um valor (no caso, o nome do cliente).
TWsdlManager irá realizar o parse de um WSDL, seja por uma URL ou por arquivo, e irá montar internamente uma lista com os tipos simples e outra com os tipos complexos. A lista de tipos complexos terá somente os tipos complexos que tenham número variável de ocorrências. Por exemplo, se tiver 2 tipos complexos onde um deles tem mínimo de 1 e máximo de 1, e outro com mínimo de 1 e máximo 2, só o que tem o valor mínimo diferente do valor máximo irá ser listado.
Através do método NextComplex é possível verificar quais são esses elementos de tipo complexo que necessitam de definição do número de ocorrências. Esse método deve ser chamado em recursão, até não existirem mais elementos retornados (irá retornar Nil). Para cada elemento retornado deve-se definir a quantidade de vezes que a tag irá aparecer no XML final (SOAP). Para isso utiliza-se o método SetComplexOccurs. Caso não seja especificado a quantidade de vezes que a tag irá aparecer, a classe irá considerar a quantidade como 0 (zero).
Caso seja passado zero no método SetComplexOccurs ele irá marcar os elementos simples e complexos dentro da tag para serem ignorados, o que fará com que os elementos complexo internos não apareçam no retorno do método NextComplex, e os elementos simples internos não serão retornados pelo método SimpleInput.
Uma vez definida a quantidade de vezes que os tipos complexos irão aparecer na mensagem SOAP, aí pode chamar o método SimpleInput, para poder retornar quais são os campos que irão receber valor. Os tipos simples podem ter seus valores definidos através dos métodos SetValue (para 1 valor apenas) ou SetValues (para mais de 1 valor). Para saber a quantidade de valores aceitos pelo tipo simples é só olhar a quantidade mínima e máxima informada no método SimpleInput, índices 3 e 4 de cada tag, respectivamente.
- Através do método SimpleInput, a classe irá disponibilizar uma lista com os elementos que serão definidos na mensagem SOAP que será enviada. A lista possui o nome dos elementos e o id interno deles. Logo, para definir o valor de um elemento utiliza-se o id do mesmo. Mas é possível também definir o valor passando o nome do elemento, fazendo com que a classe procure o mesmo, seja o primeiro encontrado (métodos SetFirst ou SetFirstArray) ou de acordo com os elementos pai (métodos SetValPar ou SetValParArray), e defina seu valor.
- WSDL - Web Services Description Language (Linguagem para descrição de web services) é uma linguagem baseada em XML para descrição dos serviços, operações e métodos de um web service. O documento gerado a partir do documento WSDL é no formato SOAP. Para mais informações sobre WSDL acesse o endereço: http://www.w3.org/TR/wsdl.
- SOAP - Simple Object Access Protocol (Protocolo Simples de Acesso a Objetos) é um protocolo baseado em XML para troca de informações estruturadas em plataforma descentralizada e distribuída, normalmente web services. Para mais informações acesse: http://www.w3.org/TR/soap/.
- Para saber como habilitar e configurar o módulo no Protheus, acesse: https://tdn.totvs.com/display/public/PROT/Configurar+Portais+e+Webservices
- Para obter mais informações dos modelos regulamentados pela W3C - World Wide Web Consortium, acesso o endereço: http://www.w3c.org.
- Alguns endereços com tutoriais sobre as tecnologias envolvidas podem ser acessados em http://www.w3schools.com/ e http://www.tutorialspoint.com/.
Envio e recebimento de mensagens
A classe TWsdlManager está preparada para enviar e receber mensagens apenas no formato SOAP. O envio das mensagens é feito através do método SendSoapMsg, que por padrão monta automaticamente a mensagem com base nos valores definidos antes do envio, ou envia uma mensagem já definida em uma variável CARACTERE passada por parâmetro.
Ao receber a resposta, que deve estar no formato SOAP também, a classe irá fazer o parse da mensagem e gera uma resposta pré-formatada. Para desabilitar o processamento da mensagem de resposta deve-se definir a propriedade lProcResp com o valor .F. (falso) antes do envio da mensagem ao servidor. Essa definição pode ser feita apenas uma vez. A resposta SOAP recebida pela classe pode ser obtida através do método GetSoapResponse e a resposta pré-formatada através do método GetParsedResponse.
Caso a propriedade lProcResp tenha o valor .F. (falso), a resposta pré-formatada não será gerada e o método GetParsedResponse irá retornar uma string vazia. Além disso, será necessário tratar manualmente a resposta recebida, que pode ser obtida pelo método GetSoapResponse.
O método SendSoapMsg irá retornar apenas após receber a mensagem de resposta e fazer ou não o parse. Caso esteja fazendo o parse da resposta e dê algum erro no parse, mesmo que o envio e recebimento das mensagens tenha sido feito com sucesso, o método irá retornar .F. (falso). Contudo, caso não esteja fazendo o parse de resposta e seja recebido uma resposta do tipo SOAP Fault, o método irá retornar .T. (verdadeiro), pois o envio e recebimento de mensagens foi feito com sucesso.
Exemplos
Exemplo 1.A - Cria um WebService Agenda com elemento complexo
#include "protheus.ch" #include "apwebsrv.ch" WSSTRUCT Contato WSDATA Nome AS String WSDATA Telefone AS String OPTIONAL ENDWSSTRUCT WSSTRUCT Contatos WSDATA Registros AS ARRAY OF Contato ENDWSSTRUCT WSSERVICE Agenda WSDATA _status AS Boolean WSDATA _dados AS Contatos WSMETHOD InsereContatos WSMETHOD ListaContatos ENDWSSERVICE WSMETHOD InsereContatos WSRECEIVE _dados WSSEND _status WSSERVICE Agenda Local nI // Exibe os dados recebidos. Eles seriam inseridos em uma tabela de um banco de dados for nI := 1 to Len( ::_dados:Registros ) conout( "Registro " + cValToChar( nI ) ) conout( "Nome: " + ::_dados:Registros[nI]:Nome ) conout( "Telefone: " + IIf( Empty( ::_dados:Registros[nI]:Telefone ), "Nao tem", ::_dados:Registros[nI]:Telefone ) + CRLF ) next nI // Devove um status informando que a operação foi feita com sucesso. Esse status será devolvido na mensagem SOAP de resposta a esse método. ::_status := .T. // Retorna que a operação foi feita com sucesso para a camada do Protheus. Return .T. WSMETHOD ListaContatos WSRECEIVE NULLPARAM WSSEND _dados WSSERVICE Agenda Local nDay := dow( date() ) Local oNewContato if nDay == 1 .Or. nDay == 7 SetSoapFault( "Metodo não disponível", "Este serviço não funciona no fim de semana." ) return .F. endif // Os dados de retorno seriam pegos do banco de dados. // Para esse exemplo iremos popular o retorno com dados fixos. // Cria a instância de retorno ( WSDATA _dados AS Contatos ) ::_dados := WSClassNew( "Contatos" ) // inicializa a propriedade da estrutura de retorno // WSDATA Registros AS ARRAY OF Contato ::_dados:Registros := {} // Cria e alimenta uma nova instancia do Contato oNewContato := WSClassNew( "Contato" ) oNewContato:Nome := "Fulano" oNewContato:Telefone := "98765" AAdd( ::_dados:Registros, oNewContato ) // Cria e alimenta uma nova instancia do Contato oNewContato := WSClassNew( "Contato" ) oNewContato:Nome := "Ciclano" oNewContato:Telefone := "95678" AAdd( ::_dados:Registros, oNewContato ) varInfo("listaContatos", ::_dados:Registros) // Retorna que a operação foi feita com sucesso para a camada do Protheus. Return .T.
Exemplo 1.B - Testa o web service Agenda criado no exemplo 1.A
User Function WSAgenda() Local oWsdl Local xRet Local aOps := {}, aComplex := {}, aSimple := {} // CRIA O OBJETO DA CLASSE TWSDLMANAGER oWsdl := TWsdlManager():New() // SETA O MODO DE TRABALHO DA CLASSE PARA "VERBOSE" oWsdl:lVerbose := .T. // FAZ O PARSE DE UMA URL conOut(" realizando parse de url...") xRet:= oWsdl:ParseURL( "http://localhost:8079/ws/Agenda.apw?WSDL" ) if xRet== .F. conOut(" realizando parse de url... erro: " + oWsdl:cError) Return else conOut(" realizando parse de url... feito") endif conOut(chr(10) + chr(10)) // LISTA AS OPERACÕES DISPONIVEIS conOut(" listando as operacões disponiveis...") aOps := oWsdl:ListOperations() if Len( aOps ) == 0 conOut(" listando as operacões disponiveis... erro: " + oWsdl:cError) Return else varinfo( "aOps", aOps ) conOut(" listando as operacões disponiveis... feito") endif conOut(chr(10) + chr(10)) // DEFINE UMA OPERACAO conOut(" setando operacao LISTACONTATOS...") xRet:= oWsdl:SetOperation( "LISTACONTATOS" ) if xRet== .F. conOut(" setando operacao LISTACONTATOS... erro: " + oWsdl:cError) Return else conOut(" setando operacao LISTACONTATOS... feito") endif conOut(chr(10) + chr(10)) // LISTA OS ELEMENTOS COMPLEXOS DA OPERACAO conOut(" listando elementos complexos da operacao...") aComplex := oWsdl:NextComplex() varinfo( "aComplex", aComplex ) conOut(" listando elementos complexos da operacao... feito") conOut(chr(10) + chr(10)) // LISTA OS ELEMENTOS SIMPLES DA OPERACAO conOut(" listando elementos simples da operacao...") aSimple := oWsdl:SimpleInput() varinfo( "aSimple", aSimple ) conOut(" listando elementos simples da operacao... feito") conOut(chr(10) + chr(10)) // RECEBE E IMPRIME A MENSAGEM FORMATADA PARA ENVIO conOut(" pegando mensagem formatada para envio...") conout( oWsdl:GetSoapMsg() ) conOut(" pegando mensagem formatada para envio... feito") conOut(chr(10) + chr(10)) // ENVIA A MENSAGEM PARA O SERVIDOR conOut(" enviando mensagem para o servidor...") xRet:= oWsdl:SendSoapMsg() if xRet== .F. conOut(" enviando mensagem para o servidor... erro: " + oWsdl:cError ) Return else conOut(" enviando mensagem para o servidor... feito") endif conOut(chr(10) + chr(10)) // RECEBE A MENSAGEM DE RESPOSTA conOut(" pegando a mensagem de resposta do servidor...") conout( oWsdl:GetSoapResponse() ) conOut(" pegando a mensagem de resposta do servidor... feito") conOut(chr(10) + chr(10)) // DEFINE UMA OPERACAO conOut(" setando operacao INSERECONTATOS...") xRet:= oWsdl:SetOperation( "INSERECONTATOS" ) if xRet== .F. conOut(" setando operacao INSERECONTATOS... erro: " + oWsdl:cError) Return else conOut(" setando operacao INSERECONTATOS... feito") endif conOut(chr(10) + chr(10)) // LISTA OS ELEMENTOS COMPLEXOS DA OPERACAO conOut(" listando elementos complexos da operacao...") aComplex := oWsdl:NextComplex() varinfo( "aComplex", aComplex ) conOut(" listando elementos complexos da operacao... feito") conOut(chr(10) + chr(10)) // SETA QUANTAS VEZES O ELEMENTO COMPLEXO APARECERÁ conOut(" setando ocorrencias de elemento complexo...") while ValType( aComplex ) == "A" if ( aComplex[2] == "CONTATO" ) .And. ( aComplex[5] == "INSERECONTATOS#1._DADOS#1.REGISTROS#1" ) occurs := 2 // o objeto complexo aparecerá 2 vezes else occurs := 0 endif xRet:= oWsdl:SetComplexOccurs( aComplex[1], occurs ) if xRet== .F. conout( " setando ocorrencias de elemento complexo... erro: erro ao definir elemento " + aComplex[2] + ", ID " + cValToChar( aComplex[1] ) + ", com " + cValToChar( occurs ) + " ocorrencias" ) return endif aComplex := oWsdl:NextComplex() enddo conOut(" setando ocorrencias de elemento complexo... feito") conOut(chr(10) + chr(10)) // LISTA OS ELEMENTOS SIMPLES DA OPERACAO conOut(" listando elementos simples da operacao...") aSimple := oWsdl:SimpleInput() varinfo( "aSimple", aSimple ) conOut(" listando elementos simples da operacao... feito") conOut(chr(10) + chr(10)) // SETA OS VALORES DOS ELEMENTOS SIMPLES /* cada elemento complexo do nosso exemplo (contato) possui dois elementos simples (nome e telefone); No nosso exemplo temos 2 elementos complexos, então temos que setar 4 elementos simples setamos cada elemento simples sequencialmente: registro 1 propridade 1 do exemplo registro 1 propridade 2 do exemplo registro 2 propridade 1 do exemplo registro 2 propridade 2 do exemplo */ conOut(" localizando posicao do ID e definindo valor da propriedade...") nPos := aScan( aSimple, {|aVet| aVet[2] == "NOME" .AND. aVet[5] == "INSERECONTATOS#1._DADOS#1.REGISTROS#1.CONTATO#1" }) conOut(" ID: " + cValToChar(nPos) + " | PROPRIEDADE: " + cValToChar(aSimple[nPos][2])) xRet := oWsdl:SetValue( aSimple[nPos][1], "Ciclano" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "TELEFONE" .AND. aVet[5] == "INSERECONTATOS#1._DADOS#1.REGISTROS#1.CONTATO#1" }) conOut(" ID: " + cValToChar(nPos) + " | PROPRIEDADE: " + cValToChar(aSimple[nPos][2])) xRet := oWsdl:SetValue( aSimple[nPos][1], "98765" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "NOME" .AND. aVet[5] == "INSERECONTATOS#1._DADOS#1.REGISTROS#1.CONTATO#2" }) conOut(" ID: " + cValToChar(nPos) + " | PROPRIEDADE: " + cValToChar(aSimple[nPos][2])) xRet := oWsdl:SetValue( aSimple[nPos][1], "Beltrano" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "TELEFONE" .AND. aVet[5] == "INSERECONTATOS#1._DADOS#1.REGISTROS#1.CONTATO#2" }) conOut(" ID: " + cValToChar(nPos) + " | PROPRIEDADE: " + cValToChar(aSimple[nPos][2])) xRet := oWsdl:SetValue( aSimple[nPos][1], "912345" ) conOut(" localizando posicao do ID e definindo valor da propriedade... feito") conOut(chr(10) + chr(10)) // EXIBE A MENSAGEM QUE SERÁ ENVIADA conOut(" pegando mensagem formatada para envio...") conout( oWsdl:GetSoapMsg() ) conOut(" pegando mensagem formatada para envio... feito") conOut(chr(10) + chr(10)) // ENVIA A MENSAGEM SOAP AO SERVIDOR conOut(" enviando mensagem para o servidor...") xRet:= oWsdl:SendSoapMsg() if xRet== .F. conout(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>") conOut(" enviando mensagem para o servidor... erro: " + oWsdl:cError ) Return else conOut(" enviando mensagem para o servidor... feito") endif conOut(chr(10) + chr(10)) // PEGA A MENSAGEM DE RESPOSTA conOut(" pegando a mensagem de resposta do servidor...") conout( oWsdl:GetSoapResponse() ) conOut(" pegando a mensagem de resposta do servidor... feito") conOut(chr(10) + chr(10)) Return
Exemplo 2 - Testa um web service externo com elementos simples
User Function Teste() Local oWsdl Local xRet Local aOps := {}, aComplex := {}, aSimple := {} // Cria o objeto da classe TWsdlManager oWsdl := TWsdlManager():New() // Faz o parse de uma URL xRet := oWsdl:ParseURL( "http://wsf.cdyne.com/WeatherWS/Weather.asmx?WSDL" ) if xRet == .F. conout( "Erro: " + oWsdl:cError ) Return endif aOps := oWsdl:ListOperations() if Len( aOps ) == 0 conout( "Erro: " + oWsdl:cError ) Return endif varinfo( "", aOps ) // Define a operação xRet := oWsdl:SetOperation( "GetCityForecastByZIP" ) //xRet := oWsdl:SetOperation( aOps[1][1] ) if xRet == .F. conout( "Erro: " + oWsdl:cError ) Return endif aComplex := oWsdl:NextComplex() varinfo( "", aComplex ) aSimple := oWsdl:SimpleInput() varinfo( "", aSimple ) // Define o valor de cada parâmeto necessário xRet := oWsdl:SetValue( 0, "90210" ) //xRet := oWsdl:SetValue( aSimple[1][1], "90210" ) if xRet == .F. conout( "Erro: " + oWsdl:cError ) Return endif // Exibe a mensagem que será enviada conout( oWsdl:GetSoapMsg() ) // Envia a mensagem SOAP ao servidor xRet := oWsdl:SendSoapMsg() if xRet == .F. conout( "Erro: " + oWsdl:cError ) Return endif // Pega a mensagem de resposta conout( oWsdl:GetSoapResponse() ) if xRet == .F. conout( "Erro: " + oWsdl:cError ) Return endif Return
Exemplo 3 - Testa um web service externo com elementos complexos
User Function tstComplex() Local oWsdl Local xRet Local aOps := {} Local aComplex := {} Local aSimple := {} Local nPos := 0, nOccurs := 0 oWsdl := TWsdlManager():New() oWsdl:cSSLCACertFile := "\certs\myconectaca.pem" oWsdl:cSSLCertFile := "\certs\000001_cert.pem" oWsdl:cSSLKeyFile := "\certs\000001_key.pem" xRet := oWsdl:ParseURL( "https://homextservicos-siafi.tesouro.gov.br/siafi2014he/services/cpr/manterContasPagarReceber?wsdl" ) if xRet == .F. conout( "Erro: " + oWsdl:cError ) Return endif aOps := oWsdl:ListOperations() if Len( aOps ) == 0 conout( "Erro: " + oWsdl:cError ) Return endif xRet := oWsdl:SetOperation( "cprDHCadastrarDocumentoHabil" ) if xRet == .F. conout( "Erro: " + oWsdl:cError ) Return endif aComplex := oWsdl:NextComplex() while ValType( aComplex ) == "A" varinfo( "aComplex", aComplex ) if ( aComplex[2] == "docOrigem" ) .And. ( aComplex[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.dadosBasicos#1" ) nOccurs := 1 elseif ( aComplex[2] == "pco" ) .And. ( aComplex[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1" ) nOccurs := 2 elseif ( aComplex[2] == "pcoItem" ) .And. ( aComplex[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.pco#1" ) nOccurs := 2 elseif ( aComplex[2] == "pcoItem" ) .And. ( aComplex[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.pco#2" ) nOccurs := 1 else nOccurs := 0 endif xRet := oWsdl:SetComplexOccurs( aComplex[1], nOccurs ) if xRet == .F. conout( "Erro ao definir elemento " + aComplex[2] + ", ID " + cValToChar( aComplex[1] ) + ", com " + cValToChar( nOccurs ) + " ocorrencias" ) return endif aComplex := oWsdl:NextComplex() enddo if xRet == .F. return endif aSimple := oWsdl:SimpleInput() varinfo( "aSimple", aSimple ) nPos := aScan( aSimple, {|aVet| aVet[2] == "codUgEmit" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "158122" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "anoDH" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "2014" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "codTipoDH" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "NP" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "dtEmis" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.dadosBasicos#1" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "26/12/2014" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "dtVenc" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.dadosBasicos#1" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "03/01/2015" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "dtPgtoReceb" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.dadosBasicos#1" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "03/01/2015" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "dtAteste" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.dadosBasicos#1" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "26/12/2014" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "vlr" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.dadosBasicos#1" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "2000.00" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "codUgPgto" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.dadosBasicos#1" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "158122" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "codCredorDevedor" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.dadosBasicos#1" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "06981180000116" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "txtObser" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.dadosBasicos#1" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "TESTE INCLUSAO DH TOTVS" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "numDocOrigem" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.dadosBasicos#1.docOrigem#1" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "123456" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "dtEmis" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.dadosBasicos#1.docOrigem#1" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "20/01/2010" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "codIdentEmit" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.dadosBasicos#1.docOrigem#1" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "654321" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "vlr" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.dadosBasicos#1.docOrigem#1" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "100.00" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "numSeqItem" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.pco#1" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "1" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "codSit" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.pco#1" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "AAA111" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "codUgEmpe" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.pco#1" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "7" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "numSeqItem" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.pco#1.pcoItem#1" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "1" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "numEmpe" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.pco#1.pcoItem#1" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "123456123456" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "codSubItemEmpe" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.pco#1.pcoItem#1" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "123" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "vlr" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.pco#1.pcoItem#1" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "20.00" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "numSeqItem" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.pco#1.pcoItem#2" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "2" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "numEmpe" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.pco#1.pcoItem#2" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "654321654321" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "codSubItemEmpe" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.pco#1.pcoItem#2" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "321" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "vlr" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.pco#1.pcoItem#2" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "30.00" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "numSeqItem" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.pco#2" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "99" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "codSit" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.pco#2" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "ABCDEF" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "codUgEmpe" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.pco#2" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "99" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "numSeqItem" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.pco#2.pcoItem#1" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "88" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "numEmpe" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.pco#2.pcoItem#1" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "111222333444" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "codSubItemEmpe" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.pco#2.pcoItem#1" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "444" ) nPos := aScan( aSimple, {|aVet| aVet[2] == "vlr" .AND. aVet[5] == "cprDHCadastrarDocumentoHabil#1.cprDHCadastrar#1.pco#2.pcoItem#1" } ) xRet := oWsdl:SetValue( aSimple[nPos][1], "50.00" ) conout( oWsdl:GetSoapMsg() ) Return
Abrangência
Builds superiores a 121227P.