0

I am trying to import XML file into excel and I have tried with the following code

Sub Convert_XML_To_Excel_Through_VBA()
'Code from Officetricks.com
'Add referece from Menu: "Tools -> References -> Microsoft XML Vn.0"
Dim iRow As Integer, iCol As Integer
Dim xmlDoc As MSXML2.DOMDocument60, xmlRoot As MSXML2.IXMLDOMNode
Dim xmlNodes As MSXML2.IXMLDOMNode, xmlData As MSXML2.IXMLDOMNode
Set xmlDoc = New MSXML2.DOMDocument60

'Load & Wait till complete XML Data is loaded
xmlDoc.async = False
xmlDoc.validateOnParse = False
xmlDoc.Load (ThisWorkbook.Path & "\Sample.xml")

'XML Loaded. Now Read Elements One by One into XML DOM Objects
Set xmlRoot = xmlDoc.DocumentElement
Set xmlNodes = xmlRoot.FirstChild

'Read XML Data and Load into Excel Sheet by each Node and Chile Node
iRow = 0
For Each xmlNodes In xmlRoot.ChildNodes
    iRow = iRow + 1
    iCol = 0

    For Each xmlData In xmlNodes.ChildNodes
        iCol = iCol + 1
        If xmlData.BaseName = "sheetDataSet" Then
            ThisWorkbook.ActiveSheet.Cells(1, iCol) = xmlData.BaseName
            Dim e

            For Each e In xmlData.ChildNodes
            Debug.Print e.Text
            'ThisWorkbook.ActiveSheet.Cells(iRow, iCol) = xmlData.Text
            Next e
        End If
    Next xmlData
Next xmlNodes
End Sub

All what I could get is one stream-text like that Header1Header2Yasser10Ahmed20Reda30 Here's the XML content

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<externalLink
	xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
	xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14"
	xmlns:x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main">
	<externalBook
		xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" r:id="rId1">
		<sheetNames>
			<sheetName val="Sheet1"/>
		</sheetNames>
		<sheetDataSet>
			<sheetData sheetId="0" refreshError="1">
				<row r="1">
					<cell r="A1" t="str">
						<v>Header1</v>
					</cell>
					<cell r="B1" t="str">
						<v>Header2</v>
					</cell>
				</row>
				<row r="2">
					<cell r="A2" t="str">
						<v>Yasser</v>
					</cell>
					<cell r="B2">
						<v>10</v>
					</cell>
				</row>
				<row r="3">
					<cell r="A3" t="str">
						<v>Ahmed</v>
					</cell>
					<cell r="B3">
						<v>20</v>
					</cell>
				</row>
				<row r="4">
					<cell r="A4" t="str">
						<v>Reda</v>
					</cell>
					<cell r="B4">
						<v>30</v>
					</cell>
				</row>
			</sheetData>
		</sheetDataSet>
	</externalBook>
</externalLink>

How can I import the data into the sheet properly?

2
  • Can you post the XML? Commented Apr 5, 2020 at 12:42
  • I have posted the XML earlier. Commented Apr 5, 2020 at 13:29

3 Answers 3

3

The XML has a default namespace, you need to assign a prefix to it with SetProperty, then use the prefix in your XPath in your SelectNodes calls. Here's working example.

Sub LoadXML()
  Dim xml As Object
  Set xml = CreateObject("MSXML2.DOMDocument")
  xml.Load ("c:\temp\excel.xml")
  xml.setProperty "SelectionNamespaces", "xmlns:ns='http://schemas.openxmlformats.org/spreadsheetml/2006/main'"

  Dim col As New Collection

  Dim ndRows, ndCols As Object

  Set ndRows = xml.SelectNodes("//ns:row")

  For i = 0 To ndRows.Length - 1
    Set ndCols = ndRows(i).SelectNodes("ns:cell/ns:v")
    For j = 0 To ndCols.Length - 1
      Cells(i + 1, j + 1) = ndCols(j).Text
    Next j
  Next i

End Sub
Sign up to request clarification or add additional context in comments.

2 Comments

FYI - note that the declaration above would load the older version 3.0 by default. However it's absolutely preferrable to get the version 6.0 (any other versions are than 3.0 and 6.0 obsolete nowadays!): suggest to use the current version 6.0 via Set xml = CreateObject("MSXML2.DOMDocument.6.0") in case of late binding as in the answer above; if the xml object is early bound as in OP you'd refer to MSXML2.DOMDocument60 in the declaration & object setting without points after DOMDocument :)
Friendly hint: the node declarations should be: Dim ndRows As Object, ndCols As Object as omitting the first variable would declare as Variant. Further hint: fully qualify your range/cell references as otherwise VBA always assumes the active worksheet, which needn't be the one you are targeting.
2

Using this path from the menu of Excel:

Data/ Get External Data / From Other Sources / From XML Data Import

enter image description here

3 Comments

Thanks a lot. I know this method and I can import it in excel like a table but I need to loop through the nodes so as to get the values stored in the ranges to the worksheet.
I tried this path but with no luck Set list = xDoc.SelectNodes("//externalLink/externalBook/sheetDataSet/sheetData"). How can I locate the right path for rows nodes?
A transformation on the input xml cannot be done directly in Excel (AFAIK). A tool like xmlstarlet can do such a job.
1

Keep traversing down the tree

 Dim e, r, c, addr As String
 For Each e In xmlData.ChildNodes
     For Each r In e.ChildNodes
         For Each c In r.ChildNodes
             addr = c.Attributes(0).Value
             ThisWorkbook.ActiveSheet.Range(addr) = c.Text
         Next
     Next
Next e

4 Comments

Thanks a lot. I got error Object variable or With block variable not set at this line addr = c.Attributes(0).Value
@Yasser Was that with the example you posted or another XML ? Try addr = c.Attributes(0).Text
I have posted the XML and this what I am testing on. Wiliam's solution worked.
No I am running it on Windows 64 Bit and Office 365 32 Bit.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.