【问题标题】:VBA Excel Macro SelectSingleNode returns nothingVBA Excel 宏 SelectSingleNode 不返回任何内容
【发布时间】:2016-04-06 16:01:57
【问题描述】:

我第一次尝试使用 excel 宏,我编写了代码来解析 Web 服务响应,我想更新标签值 excel中的单个单元格。

以下是我的 XML 的摘录(一个巨大的 Web 服务响应)

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"/>
   <soap:Body>
      <bm:getTransactionResponse xmlns:bm="http://xmlns.oracle.com/XXXCLD/commerce/ZZZYYY_PPP_1">
         <bm:status>
            <bm:success>true</bm:success>
            <bm:message>Wed Apr 06 09:04:32 UTC 2016 - Successfully processed API for test1</bm:message>
         </bm:status>
         <bm:transaction>
            <bm:category>data</bm:category>
            <bm:action>add</bm:action>
            <bm:id>1111</bm:id>
            <bm:process_var_name>xvgfdr</bm:process_var_name>
            <bm:buyer_company_name>test1</bm:buyer_company_name>
            <bm:supplier_company_name>test1</bm:supplier_company_name>
            <bm:step_var_name>waitingForInternalApproval</bm:step_var_name>
            <bm:last_document_number>2</bm:last_document_number>
            <bm:date_added>2016-04-04 12:14:57</bm:date_added>
            <bm:date_modified>2016-04-06 09:04:18</bm:date_modified>
            <bm:data_xml>
               <bm:transaction bm:bs_id="11111" bm:buyer_company_name="test1" bm:buyer_user_name="someone" bm:currency_pref="GBP" bm:data_type="0" bm:document_name="Transaction" bm:document_number="1" bm:document_var_name="transaction" bm:process_var_name="XXX_1" bm:supplier_company_name="test1">
                  <bm:_document_number>1</bm:_document_number>
                  <bm:createdBy_t>SomeOne</bm:createdBy_t>
                  <bm:_price_book_var_name>_default</bm:_price_book_var_name>
                  <bm:createdDate_t>2016-04-04 00:00:00</bm:createdDate_t>
                  <bm:currency_t>INR</bm:currency_t>
                  <bm:_customer_t_first_name/>
                  <bm:_customer_t_last_name/>
                  <bm:_customer_t_company_name>Test Account</bm:_customer_t_company_name>

我正在尝试获取标签 &lt;bm:_customer_t_company_name&gt; 的值

下面是我一直在使用的代码。

Sub Button1_Click()

                'Set and instantiate our working objects
                    Dim Req As Object
                    Dim sEnv As String
                    Dim Resp As New MSXML2.DOMDocument60
                    Set Req = CreateObject("MSXML2.XMLHTTP")
                    Set Resp = CreateObject("MSXML2.DOMDocument.6.0")                   
                    With Req

                    .Open "Post", "https://XXXX.com/", False                    
                    Dim Pwd As String
                    Pwd = Range("D8").Value


                    Dim QuoteId As String
                    QuoteId = Range("D9").Value

                    ' SOAP envelope for submission to the Web Service
                     sEnv = sEnv & "<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"">"
                     sEnv = sEnv & "  <soapenv:Header>"
                     sEnv = sEnv & "  <wsse:Security xmlns:wsse=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"" xmlns:wsu=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"">"
                     sEnv = sEnv & "  <wsse:UsernameToken wsu:Id=""UsernameToken-2"">"
                     sEnv = sEnv & "  <wsse:Username>" & Range("D7").Value & "</wsse:Username>"
                     sEnv = sEnv & "  <wsse:Password Type=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"">" & Pwd & "</wsse:Password>"
                     sEnv = sEnv & "  </wsse:UsernameToken>"
                     sEnv = sEnv & "  </wsse:Security>"
                     sEnv = sEnv & "  </soapenv:Header>"
                     sEnv = sEnv & "  <soapenv:Body>"
                     sEnv = sEnv & "   <bm:getTransaction>"
                     sEnv = sEnv & "    <bm:transaction>"
                     sEnv = sEnv & "    <bm:id>" & Range("D9").Value & "</bm:id>"
                     sEnv = sEnv & "   </bm:transaction>"
                     sEnv = sEnv & "   </bm:getTransaction>"
                     sEnv = sEnv & "  </soapenv:Body>"
                     sEnv = sEnv & "</soapenv:Envelope>"                    
                    ' Send SOAP Request
        .send (sEnv)       

        Resp.LoadXML Req.responseText

        End With
        If Resp Is Nothing Then
            MsgBox "No XML"
        End If
        With Resp

        .setProperty "SelectionNamespaces", "xmlns:bm=""http://xmlns.oracle.com/XXXCLD/commerce/ZZZYYY_PPP_1"" xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"""
        Dim strName As String
        If .SelectSingleNode("//bm:_customer_t_company_name") Is Nothing Then
            MsgBox "No Node"
        End If
        strName = .SelectSingleNode("//bm:_customer_t_company_name").Text
        MsgBox strName
    End With

  'clean up code
    Set Req = Nothing
    Set Resp = Nothing
Range("A1").Value = "DONE"
End Sub

.SelectSingleNode("//soap:Body") 工作正常。 当我测试我的代码时, .SelectSingleNode("//bm:_customer_t_company_name") 总是返回 Nothing 。

.SelectSingleNode("//bm:getTransactionResponse"),什么都不返回。

你能告诉我我做错了什么吗?

这是完整的XML结构截图enter image description here

【问题讨论】:

  • 我没有测试过这个,也许这会对你有所帮助。将命名空间添加到 xmlnamespacemanager 并将其传递给 selectsingle 节点,例如:我将命名空间分配给 abc 然后 .SelectSingleNode("//abc:bm:_customer_t_company_name"
  • 感谢 Karthik 的快速回复。将代码更改为以下给出运行时错误。 .setProperty "SelectionNamespaces", "xmlns:abc=""xmlns.oracle.com/XXXCLD/commerce/ZZZYYY_PPP_1"" xmlns:soap=""schemas.xmlsoap.org/soap/envelope""" Dim strName As String If .SelectSingleNode("//abc:bm:_customer_t_company_name") 什么都没有Then MsgBox "No Node" End If strName = .SelectSingleNode("//abc:bm:_customer_t_company_name").Text Expected Token 'EOF' found ':' /abc:bm->:

标签: excel vba macros


【解决方案1】:

您提交的代码没有任何问题。您应该检查 Web 服务实际返回的 XML,以确保它具有您要查找的标记。

我将您的示例简化为以下 VBA Sub,它可以正常运行。

Sub Test()
    Dim xml
    Set xml = CreateObject("MSXML2.DOMDocument.6.0")
    xml.LoadXML "<soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/""> <SOAP-ENV:Header xmlns:SOAP-ENV=""http://schemas.xmlsoap.org/soap/envelope/""/> <soap:Body> <bm:getTransactionResponse xmlns:bm=""http://xmlns.oracle.com/XXXCLD/commerce/ZZZYYY_PPP_1""> <bm:status> <bm:success>true</bm:success> <bm:message>Wed Apr 06 09:04:32 UTC 2016 - Successfully processed API for test1</bm:message> </bm:status> <bm:transaction> <bm:category>data</bm:category> <bm:action>add</bm:action> <bm:id>1111</bm:id> <bm:process_var_name>xvgfdr</bm:process_var_name> <bm:buyer_company_name>test1</bm:buyer_company_name> <bm:supplier_company_name>test1</bm:supplier_company_name> <bm:step_var_name>waitingForInternalApproval</bm:step_var_name> <bm:last_document_number>2</bm:last_document_number> <bm:date_added>2016-04-04 12:14:57</bm:date_added> <bm:date_modified>2016-04-06 09:04:18</bm:date_modified> <bm:data_xml> <bm:transaction bm:bs_id=""11111"" bm:buyer_company_name=""test1"" bm:buyer_user_name=""someone"" bm:currency_pref=""GBP"" bm:data_type=""0"" bm:document_name=""Transaction"" bm:document_number=""1"" bm:document_var_name=""transaction"" bm:process_var_name=""XXX_1"" bm:supplier_company_name=""test1""> <bm:_document_number>1</bm:_document_number> <bm:createdBy_t>SomeOne</bm:createdBy_t> <bm:_price_book_var_name>_default</bm:_price_book_var_name> <bm:createdDate_t>2016-04-04 00:00:00</bm:createdDate_t> <bm:currency_t>INR</bm:currency_t> <bm:_customer_t_first_name/> <bm:_customer_t_last_name/> <bm:_customer_t_company_name>Test Account</bm:_customer_t_company_name> </bm:transaction> </bm:data_xml> </bm:transaction> </bm:getTransactionResponse> </soap:Body> </soap:Envelope>"

    xml.SetProperty "SelectionNamespaces", "xmlns:bm=""http://xmlns.oracle.com/XXXCLD/commerce/ZZZYYY_PPP_1"" xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"""

    Debug.Print xml.SelectSingleNode("//bm:_customer_t_company_name").Text
End Sub

输出是Test Account

【讨论】:

  • 嗨,Tmdean,非常感谢您的输入。我通过删除 SelectSingleNode 内衬并添加了以下内容进行了测试,其中包含 Resp .setProperty "SelectionNamespaces", "xmlns:bm=""xmlns.oracle.com/XXXCLD/commerce/ZZZYYY_PPP_1"" xmlns:soap=""schemas.xmlsoap.org/soap/envelope""" WScript.Echo Resp.SelectSingleNode("//bm:_customer_t_company_name").Text End With
  • 行 WScript.... 给出运行时错误“对象变量或未设置块变量”。我在我的代码中使用了 Resp.LoadXML Req.responseText,它是否等同于 xml.LoadXML "
  • 是的,它是等价的。在我的脚本中,我使用 LoadXML 将 SOAP 响应 XML 直接加载到 DOMDocument60 对象中,而不是像您一样执行 Web 请求。由于我的代码有效,看来问题出在您从 Web 服务接收的 XML 输出上,与 SelectSingleNode 或 XML 命名空间没有任何关系。
  • 如果你想在 Excel 中运行我的 VBScript 示例,只需将 WScript.Echo 更改为 Debug.Print
  • SelectSingleNode 行上的以下代码“对象变量或未设置块变量”仍然存在相同的错误。使用 Resp .setProperty "SelectionNamespaces", "xmlns:bm=""xmlns.oracle.com/XXXCLD/commerce/ZZZYYY_PPP_1"" xmlns:soap=""schemas.xmlsoap.org/soap/envelope""" Debug.Print .SelectSingleNode("//bm:_customer_t_company_name").Text 以我通过将 Web 服务响应保存在工作表的文本框中来检查它,这与我在帖子中给出的相同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-27
  • 2019-04-06
  • 2012-02-15
相关资源
最近更新 更多