Reputation: 15
I trying to create a VBA macro that converts an excel sheet to xml. The problem is that the excel data contains special characters. I searched here in the forum for some help and guess the ADOB.stream-solution is the one that could solve my problem. But I'm not able to integrate this into my VBA code. So far I got the following code:
Public Sub ExcelToXML()
On Error GoTo ErrorHandler
Dim colIndex As Integer
Dim rwIndex As Integer
Dim asCols() As String
Dim oWorkSheet As Worksheet
Dim sName As String
Dim lCols As Long, lRows As Long
Dim iFileNum As Integer
Set oWorkSheet = ThisWorkbook.Worksheets(1)
sName = oWorkSheet.Name
lCols = oWorkSheet.Columns.Count
lRows = oWorkSheet.Rows.Count
Set objstream = CreateObject("ADODB.Stream")
objstream.Charset = "utf-8"
objstream.Mode = 3
objstream.Type = 2
objstream.Open
ReDim asCols(lCols) As String
iFileNum = FreeFile
Open "C:\temp\test5.xml" For Output As #iFileNum
Worksheets("Sheet1").Range("A1:Z1").Replace _
What:=" ", Replacement:="_", _
SearchOrder:=xlByColumns, MatchCase:=True
For i = 0 To lCols - 1
'Assumes no blank column names
If Trim(Cells(1, i + 1).Value) = "" Then Exit For
asCols(i) = Cells(1, i + 1).Value
Next i
If i = 0 Then GoTo ErrorHandler
lCols = i
objstream.WriteText "<?xml version=""1.0"" encoding=""UTF-8""?>"
objstream.WriteText "<" & "DATA" & ">"
For i = 2 To lRows
If Trim(Cells(i, 1).Value) = "" Then Exit For
obj.stream.WriteText "<" & "PROC" & ">"
For j = 1 To lCols
If Trim(Cells(i, j).Value) <> "" Then
objstream.WriteText " <" & asCols(j - 1) & ">"
objstream.WriteText Trim(Cells(i, j).Value)
objstream.WriteText "</" & asCols(j - 1) & ">"
DoEvents 'OPTIONAL
End If
Next j
objstream.WriteText " </" & "PROC" & ">"
Next i
objstream.WriteText "</" & "DATA" & ">"
ErrorHandler:
If iFileNum > 0 Then Close #iFileNum
objstream.SaveToFile "C:\temp\test6.xml", 2
objstream.Close
Set AdoS = Nothing
Exit Sub
End Sub
The output file is unfortunately empty. Thank you in advance for any assistance you can give me!
Upvotes: 1
Views: 1816
Reputation: 22185
Don't try to create XML files manually - there are already very robust tools that you can use to do it for you. In this case, I'd use the MSXML2
objects. These support UTF8 natively, so you don't need to work about the character encoding or the file IO at all. The code structure is basically the same as writing text directly, but you add nodes instead of writing <node>
, value
, </node>
and trying to keep the structure straight:
'Add a reference to Microsoft XML, v6.0
Sub ExcelToXML()
Worksheets("Sheet1").Range("A1:Z1").Replace _
What:=" ", Replacement:="_", _
SearchOrder:=xlByColumns, MatchCase:=True
With New DOMDocument
'Add XML header
.appendChild .createProcessingInstruction("xml", "version=""1.0"" encoding=""utf-8""")
'Add the root node
Dim root As IXMLDOMElement
Set root = .createElement("DATA")
.appendChild root
'Work with an array, not the actual worksheet.
Dim data() As Variant
data = Worksheets("Sheet1").UsedRange.Value
For r = LBound(data, 1) + 1 To UBound(data, 1)
If Trim$(data(r, 1)) = vbNullString Then Exit For
Dim proc As IXMLDOMElement
'Create a PROC node for the row.
Set proc = root.appendChild(.createElement("PROC"))
For c = LBound(data, 2) To UBound(data, 2)
If Trim$(data(r, c)) <> vbNullString Then
'Add a child for each column.
Dim child As IXMLDOMElement
Set child = proc.appendChild(.createElement(data(1, c)))
child.appendChild .createTextNode(Trim$(data(r, c)))
End If
Next
Next
'Write the file.
.Save "C:\temp\test6.xml"
End With
End Sub
Upvotes: 1