2013-06-23 61 views
4

我很努力地通過一個XML文件解析excel。我發現了大量的例子,但沒有一個看起來與我正在尋找的完全相同,而且我似乎無法越過錯誤「Object variable or With block variable not set」如何在Excel中使用vba訪問xml中的特定元素和屬性?

xml格式良好看起來像以下:

<xml tag> 
<PLMXML> 
    <WorkflowTemplate name=""> 
    <argument name=""> 
    </argument> 
    </WorkflowTemplate > 
    <WorkflowTemplate name=""> 

我試圖使用VBA獲得所有孩子的名字的價值,並分別得到的參數名稱。我不斷收到錯誤與此代碼:

Dim xmlDoc As MSXML2.DOMDocument 
Dim xmlElement As MSXML2.IXMLDOMElement 
Dim xmlNode As MSXML2.IXMLDOMNode 
Dim xmlAttribute As MSXML2.IXMLDOMAttribute 

Set xmlDoc = New MSXML2.DOMDocument 
xmlDoc.async = False 
xmlDoc.validateOnParse = False 

'ENTER THE PATH WHERE THE XML Workflow DOCUMENT IS STORED: 
Dim DocumentPath As String 
DocumentPath = InputBox("Enter the full path for the xml workflow document, example: C:\workflows\workflowseasy.xml", "Workflow XML File path", "C:\workflows\workflowseasy.xml") 
xmlDoc.Load (DocumentPath) 

Set xmlElement = xmlDoc.DocumentElement 

Set xmlNode = xmlElement.SelectSingleNode("WorkflowTemplate[0]") 


Set xmlAtribute = xmlNode.Attributes.getNamedItem("name") 

我不清楚如何獲取數據使用該解析器在Excel VBA中在文檔中。任何幫助將不勝感激。我目前在參考資料中選擇了Microsoft XML v6.0。

UPDATE

我已經挖成以上,並已經提出了下面的代碼,但我仍然得到了同樣的錯誤:

Dim xmlDoc As MSXML2.DOMDocument60 
Dim xmlRoot As MSXML2.IXMLDOMNode 
Dim xmlTemplate As MSXML2.IXMLDOMNode 
Dim xmlAttributes As MSXML2.IXMLDOMNamedNodeMap 
Dim xmlName As MSXML2.IXMLDOMNode 
Dim xmlChildren As MSXML2.IXMLDOMNodeList 
Dim xmlChild As MSXML2.IXMLDOMNode 
Dim intI As Long 
intI = 1 

Set xmlDoc = New MSXML2.DOMDocument60 
xmlDoc.async = False 
xmlDoc.validateOnParse = False 

'ENTER THE PATH WHERE THE XML Workflow DOCUMENT IS STORED: 
Dim DocumentPath As String 
DocumentPath = InputBox("Enter the full path for the xml workflow document, example: C:\workflows\workflowseasy.xml", "Workflow XML File path", "C:\workflows\workflowseasy.xml") 
xmlDoc.Load (DocumentPath) 

Set xmlRoot = xmlDoc.DocumentElement *****these say they are empty when debugging 
Set xmlChildren = xmlRoot.ChildNodes *****these say they are empty when debugging 
For Each xmlTemplate In xmlChildren *****error occures here 
    If xmlTemplate.nodeName = "WorkflowTemplate" Then 
    Set xmlAttributes = xmlTemplate.Attributes 
    Set xmlName = xmlAttributes.getNamedItem("name") 
    ActiveSheet.Cells(int1, 1).Value = xmlName.Text 
    Set xmlChildren = xmlTemplate.ChildNodes 
    intI = intI + 1 
    End If 
Next xmlTemplate 

最後更新* *

想通了。該文件的加載是問題。出於某種原因傳遞它從msg框中的字符串不起作用,但從gui文件選擇器傳遞它。這是我最終使用的代碼。

Dim xmlDoc As MSXML2.DOMDocument60 
Dim xmlRoot As MSXML2.IXMLDOMNode 
Dim xmlTemplate As MSXML2.IXMLDOMNode 
Dim xmlAttributes As MSXML2.IXMLDOMNamedNodeMap 
Dim xmlName As MSXML2.IXMLDOMNode 
Dim xmlChildren As MSXML2.IXMLDOMNodeList 
Dim xmlChild As MSXML2.IXMLDOMNode 
Dim intI As Long 
intI = 1 

Set xmlDoc = New MSXML2.DOMDocument60 
xmlDoc.async = False 
xmlDoc.validateOnParse = False 

'ENTER THE PATH WHERE THE XML Workflow DOCUMENT IS STORED: 
Dim DocumentPath As String 
With Application.FileDialog(msoFileDialogOpen) 
.Title = "Choose File" 
.AllowMultiSelect = False 
.Show 
'DocumentPath.Show 
DocumentPath = .SelectedItems(1) 
End With 

xmlDoc.Load (DocumentPath) 

Set xmlRoot = xmlDoc.DocumentElement 
Set xmlChildren = xmlRoot.ChildNodes 
For Each xmlTemplate In xmlChildren 
    If xmlTemplate.nodeName = "WorkflowTemplate" Then 
    Set xmlAttributes = xmlTemplate.Attributes 
    Set xmlName = xmlAttributes.getNamedItem("name") 
    ActiveSheet.Cells(int1, 1).Value = xmlName.Text 
    Set xmlChildren = xmlTemplate.ChildNodes 
    intI = intI + 1 
    End If 
Next xmlTemplate 

目前該分配值部分的代碼休息,而是通過變量拉動正確的價值觀,並在XML信息正確抽取的代碼去。

+0

你會得到什麼錯誤? –

+0

當我到達Set xmlNode = xmlElement.SelectSingleNode時,它失敗。 – user2513952

+0

我試過用這個來看看我是否至少可以得到值,但是這似乎沒有給我任何東西。完全跳過for循環Set xmlList = xmlDoc。SelectNodes(「// WorkflowTemplate」) 對於xmlList中的每個xmlNode Debug.Print xmlNode.Text Next xmlNode – user2513952

回答

1

我認爲問題中提供的最終代碼可能並不總是遍歷整個xml文檔,因爲xmlChildren變量在循環期間被覆蓋,所以我認爲這可能只是得到第一個子節點並且它是第一個子節點等等。

要遍歷整個文檔,您可以調用一個單獨的過程並構建遞歸調用,以便它將跟隨每個子節點,但隨後返回到完成時調用的列表。

這裏是我在哪裏尋找一個特定的XML元素的所有實例的簡化示例,假設在XML文檔的所有車含有:

<?xml version="1.0" encoding="UTF-8"?> 
<ImportConfig> 
    <ShoppingCarts description="Any carts added here will be picked up by the auto import"> 
     <cart>shopping cart 1 name here</cart> 
     <cart>shopping cart 2 name here</cart> 
    </ShoppingCarts> 
</ImportConfig> 

下面的第一個步驟是特異於本實施例中即其中標籤被命名爲etc,但其他兩個可以用於任何xml文檔(第一個只是它們如何使用的一個示例):

' Chris Prosser 09/07/2014 
' example use of getElementList (in this case to get all cart elements) 

Sub getCarts() 
    Dim carts As Collection 
    Dim i As Integer 

    Set carts = New Collection 
    getElementList "C:\Users\Chris\Dropbox\VBAutomation\AutoImportConfig.xml", "cart", carts 

    For i = 1 To carts.count 
     Debug.Print carts.Item(i) 
    Next 

End Sub 

' Chris Prosser 09/07/2014 
' Gets the values of all instances of a specific element from an xml file 

Sub getElementList(xml_file_path As String, _ 
          elementName As String, _ 
          elementValuesList As Collection) 

    Dim xmlDoc As MSXML2.DOMDocument 
    Dim xmlRoot As MSXML2.IXMLDOMNode 
    Dim xmlChildren As MSXML2.IXMLDOMNodeList 
    Dim xmlElement As MSXML2.IXMLDOMElement 

    Set xmlDoc = New MSXML2.DOMDocument 
    xmlDoc.async = False 
    xmlDoc.validateOnParse = False 
    xmlDoc.Load (xml_file_path) 
    Set xmlRoot = xmlDoc.documentElement 
    Set xmlChildren = xmlRoot.childNodes 

    iterateOverChildNodes xmlChildren, elementName, elementValuesList 

End Sub 

' Chris Prosser 09/07/2014 
' Call with a list of xmlNodes (can be generated from a file using getElementList) 
' and an element name to search for. The procedure find child nodes and re-runs 
' recursively until all branchs from the list of nodes passed in have been traversed 

Sub iterateOverChildNodes(xmlChildren As MSXML2.IXMLDOMNodeList, _ 
          elementName As String, _ 
          elementValuesList As Collection) 

    Dim xmlElement As MSXML2.IXMLDOMElement 
    Dim xmlGrandChildren As MSXML2.IXMLDOMNodeList 

    For Each xmlElement In xmlChildren 
     If xmlElement.nodeName = elementName Then 
      'Debug.Print xmlElement.nodeTypedValue 
      elementValuesList.Add xmlElement.nodeTypedValue 
     Else 
      Set xmlGrandChildren = xmlElement.childNodes 
      iterateOverChildNodes xmlGrandChildren, elementName, elementValuesList 
     End If 
    Next xmlElement 

End Sub 
相關問題