我正在尝试使用 Excel VBA 将 XML 文件导入电子表格。虽然它有效,但当我只想从文件中提取特定标签数据并将每个特定标签中的数据插入我的电子表格中时,我正在导入整个 XML,距离我的活动单元格几行。例如……
ActiveCell = A1
PurchaseOrder into A2
InvoiceNumber into A3
BuyerCurrency into A4
Sub cmdImportDataFromFile()
Dim fd As Office.FileDialog
Set fd = Application.FileDialog(msoFileDialogFilePicker)
Dim myRow As ListRow
Dim row_number As Integer
With fd
If .Show = True Then
xmlfilename = .SelectedItems(1)
'Process the file
Dim fDoc As Object
Set xDoc = CreateObject("MSXML2.DOMDocument")
xDoc.async = False: xDoc.validateonparse = False
xDoc.Load (xmlfilename)
'Get Root Node
Set selInvoice = xDoc.DocumentElement
'row_number = 6
For Each InvoiceHeader In selInvoice.ChildNodes
Debug.Print "<InvoiceNumber>:" & InvoiceHeader.ChildNodes(0).text
Debug.Print "<PurchaseOrderNumber>:" & InvoiceHeader.ChildNodes(1).text
'Debug.Print "<PurchaseOrderNumber>:" & Product.ChildNodes(0).text
Debug.Print "----------------------"
ActiveCell(1, 1).Value = invoiceheader.ChildNodes(0).text
ActiveCell(1, 2).Value = invoiceheader.ChildNodes(1).text
Next InvoiceHeader
End If
End With
End Sub
一旦你有了根节点,你可以简单地使用
SelectSingleNode
方法来检索所需的节点...
Debug.Print "<InvoiceNumber>:" & selInvoice.SelectSingleNode("//InvoiceNumber").Text
Debug.Print "<PurchaseOrderNumber>:" & selInvoice.SelectSingleNode("//PurchaseOrderNumber").Text
在尝试获取单个节点的文本内容时,有几点需要考虑:
由于您的 xml 文件包含名称空间声明,因此您也必须集成它,以便能够直接使用 XPath 表达式寻址节点。
您可能混淆了单张发票下的从属级别;所需节点的顺序实际上是:
Invoices/Invoice/Header/InvoiceHeader/...
此外,您应该通过
CreateObject("MSXML2.DOMDocument.6.0"
引用最新的xml版本(使用后期绑定符合您的帖子)。
调用示例
'1) Get File name
' ...
' xmlfilename = ...
'2) Set xml document to memory in its latest version 6.0 (late binding)
Dim xDoc As Object: Set xDoc = CreateObject("MSXML2.DOMDocument.6.0")
'3) Add namespace
xDoc.SetProperty "SelectionNamespaces", _
"xmlns:n='http://www.xxxxxx.com'" ' note the udf n-prefix
'4) Load xml file
If xDoc.Load(xmlfilename) Then
Dim invoice As Object, invoices As Object
'a) addressing Invoice indirectly (being the next hierarchy level under DocumentElement)
Set invoices = xDoc.DocumentElement.ChildNodes
'b) addressing Invoice directly using namespace prefix n:
'' Set invoices = xDoc.DocumentElement.SelectNodes("//n:Invoice")
For Each invoice In invoices
' assuming actual text content in wanted nodes
' (otherwise dim tmp as object, set tmp = ... and recheck via If Not tmp Is Nothing then ...)
Debug.Print String(29, "-")
Debug.Print "InvoiceNumber: " & invoice.SelectSingleNode("n:*/n:*/n:InvoiceNumber").Text
Debug.Print "PurchaseOrderNumber: " & invoice.SelectSingleNode("n:*/n:*/n:PurchaseOrderNumber").Text
Next
End If
示例文件(例如 invoices.xml)
出于测试目的,您可能需要将以下 xml 文件内容复制到您的硬盘:
<?xml version="1.0" encoding="utf-8"?>
<Invoices xmlns="http://www.xxxxxx.com">
<Invoice>
<PaymentTerms>
</PaymentTerms>
<Header>
<InvoiceHeader>
<InvoiceNumber>3000380</InvoiceNumber>
<PurchaseOrderNumber>96428312</PurchaseOrderNumber>
</InvoiceHeader>
<PaymentTerms>
</PaymentTerms>
</Header>
<Data>
</Data>
</Invoice>
<Invoice>
<Header>
<InvoiceHeader>
<InvoiceNumber>3000381</InvoiceNumber>
<PurchaseOrderNumber>96428313</PurchaseOrderNumber>
</InvoiceHeader>
</Header>
<Data>
</Data>
</Invoice>
</Invoices>
立即窗口输出:
-----------------------------
InvoiceNumber: 3000380
PurchaseOrderNumber: 96428312
-----------------------------
InvoiceNumber: 3000381
PurchaseOrderNumber: 96428313