Excel VBA-检查xml节点是否存在-如果不存在,请使用其他节点

Excel VBA-检查xml节点是否存在-如果不存在,请使用其他节点,excel,xml,vba,Excel,Xml,Vba,我想将数据从xml文件复制到excel工作簿 每个xml都有标记“客户端名称”,但其中一些xml也有标记“计费客户端名称” 我想用我的代码实现这一点 如果xml中存在标记“Billing client name”,请使用它并忽略标记“client name” 如果xml中没有标记“Billing client name”,请使用标记“client name”中的数据 我的当前代码仅从标记“客户端名称”粘贴数据 我的代码: Dim主工作簿作为工作簿 设置mainWorkBook=ActiveWor

我想将数据从xml文件复制到excel工作簿 每个xml都有标记“客户端名称”,但其中一些xml也有标记“计费客户端名称” 我想用我的代码实现这一点 如果xml中存在标记“Billing client name”,请使用它并忽略标记“client name” 如果xml中没有标记“Billing client name”,请使用标记“client name”中的数据 我的当前代码仅从标记“客户端名称”粘贴数据

我的代码:

Dim主工作簿作为工作簿
设置mainWorkBook=ActiveWorkbook
主工作簿。工作表(“工作表3”)。激活
LR=单元格(Rows.Count,“A”).End(xlUp).Row
“MsgBox LR
对于x=2至LR
设置xmlDoc=CreateObject(“Microsoft.XMLDOM”)
xmlDoc.SetProperty“SelectionLanguage”、“XPath”
xmlDoc.Async=False
加载(“\\path\”和范围(“A”&x)和“.xml”)
设置nodeXML=xmlDoc.getElementsByTagName(“比尔到客户代码”)
Set nodeXML2=xmlDoc.getElementsByTagName(“CLIENTCODE”)
如果nodeXML什么都不是,那么
范围(“B”&x).Value=nodeXML(i).Text
其他的
范围(“B”&x).Value=nodeXML2(i).Text
如果结束
下一个x
如果我将最后几行代码更改为:

如果nodeXML什么都不是,那么
范围(“B”&x).Value=nodeXML2(i).Text
其他的
范围(“B”&x).Value=nodeXML(i).Text
如果结束
我只从标记“Billing client name”中获取值,如果该标记不存在,则没有值

示例xml

<InvoiceData xmlns="http://tempuri.org/InvoiceData.xsd">
   <INVOICE_HEADER>
        <BILL_TO_CLIENTCODE/>
        <CLIENTCODE>61138259</CLIENTCODE>

61138259

第二个在标记Bill to clientcode和clientcode中都有值,但Bill to clientcode应该是主值。

xmlDoc.getElementsByTagName
始终返回集合,但如果没有匹配项,则该集合可能为空,因此需要测试(例如)

并且不检查
nodeXML
是否为空

因此,类似的方法应该有效(未经测试):

子测试仪()
将主工作簿作为工作簿,将xmlDoc作为对象
将sht变暗为工作表
设置mainWorkBook=ActiveWorkbook
设置sht=mainWorkBook.Sheets(“Sheet3”)
对于x=2至短单元格(短行数,“A”)。结束(xlUp)。行
设置xmlDoc=CreateObject(“Microsoft.XMLDOM”)
xmlDoc.SetProperty“SelectionLanguage”、“XPath”
xmlDoc.Async=False
加载(“\\path\”和范围(“A”&x)和“.xml”)
sht.Range(“B”&x).Value=PreferredValue(xmlDoc_
数组(“BILL\u TO\u CLIENTCODE”、“CLIENTCODE”))
下一个x
端接头
函数PreferredValue(文档作为对象,arrTags)
尺寸t、col、rv
对于ARR标签中的每个t
Set col=doc.getElementsByTagName(t)
如果列长度>0,则
rv=列(0)。文本

如果Len(rv)>0,则退出以获取'
xmlDoc.getElementsByTagName
始终返回一个集合,但如果没有匹配项,则该集合可能为空,因此需要测试(例如)

并且不检查
nodeXML
是否为空

因此,类似的方法应该有效(未经测试):

子测试仪()
将主工作簿作为工作簿,将xmlDoc作为对象
将sht变暗为工作表
设置mainWorkBook=ActiveWorkbook
设置sht=mainWorkBook.Sheets(“Sheet3”)
对于x=2至短单元格(短行数,“A”)。结束(xlUp)。行
设置xmlDoc=CreateObject(“Microsoft.XMLDOM”)
xmlDoc.SetProperty“SelectionLanguage”、“XPath”
xmlDoc.Async=False
加载(“\\path\”和范围(“A”&x)和“.xml”)
sht.Range(“B”&x).Value=PreferredValue(xmlDoc_
数组(“BILL\u TO\u CLIENTCODE”、“CLIENTCODE”))
下一个x
端接头
函数PreferredValue(文档作为对象,arrTags)
尺寸t、col、rv
对于ARR标签中的每个t
Set col=doc.getElementsByTagName(t)
如果列长度>0,则
rv=列(0)。文本

如果Len(rv)>0,则退出“这是您的全部代码吗?”?
i
变量是什么?何时更改?您确实应该考虑确保<代码>选项“显式< /代码>”位于您的模块的顶部。如果NoDEXML是“没有< /COD>”,则您有“<代码>”,但您仍然试图使用<代码> NoDEXML(I).Text <代码> -即使您已经确定它是“代码> No.< /代码>”。像
xmlBillToClientCode
xmlClientCode
在上下文中比
nodeXML
nodeXML2
更有意义。正如我所见,我的代码中没有“I”变量,有一个
I
变量-它未在
nodeXML(I)
中声明。如果
选项Explicit
位于模块顶部,则会捕获到该选项。您正在使用它作为
nodeXML
集合的索引号。这是您的全部代码吗?
i
变量是什么?何时更改?您确实应该考虑确保<代码>选项“显式< /代码>”位于您的模块的顶部。如果NoDEXML是“没有< /COD>”,则您有“<代码>”,但您仍然试图使用<代码> NoDEXML(I).Text <代码> -即使您已经确定它是“代码> No.< /代码>”。像
xmlBillToClientCode
xmlClientCode
在上下文中比
nodeXML
nodeXML2
更有意义。正如我所见,我的代码中没有“I”变量,有一个
I
变量-它未在
nodeXML(I)
中声明。如果
选项Explicit
位于模块顶部,则会捕获到该选项。您正在使用它作为您的
nodeXML
集合的索引号。此解决方案仅为标记“Clientcode”提供数据-忽略“Bill to client code”谢谢-但它仅为我提供“Bill to Clientcode”标记的数据并忽略标记“ClienCode”您能用示例XML更新您的问题吗?不需要所有内容,但足以测试。1)精细答案+1:-)2.)更接近原始编码,问题也可以通过
Set nodeXML=xmlDoc.DocumentElement解决。选择SingleNode(“BILL\u to\u CLIENTCODE”)
 If nodeXML.Length > 0 Then