最可靠方法是用MSXML2.DOMDocument.6.0对象生成XML:先创建节点并appendChild挂载,再setAttribute;保存UTF-8需ADODB.Stream重写;注意节点大小写、空节点检查及根节点初始化。

用VBA的CreateObject("MSXML2.DOMDocument")生成XML文件最可靠
直接写字符串拼接XML容易出编码、转义、格式错乱问题,尤其含中文或特殊字符时。推荐用MSXML2.DOMDocument对象——它原生支持XML结构校验、自动转义、UTF-8保存,Office 2007及以上都自带,无需额外引用。
-
DOMDocument版本选MSXML2.DOMDocument.6.0(比.3.0更稳定,支持save方法直接写文件) - 必须显式设置
xmlDoc.setProperty "SelectionLanguage", "XPath"(虽非必需,但避免某些XPath查询失效) - 保存前务必调用
xmlDoc.Save "C:\path\to\file.xml",不能只靠xmlDoc.XML输出字符串再手动写入
创建根节点和子节点的正确顺序是createElement → appendChild → setAttribute
顺序错会导致节点丢失或属性不生效。比如想建,必须先创建book元素,再创建title并追加进去,最后才设id属性。
Dim xmlDoc As Object
Set xmlDoc = CreateObject("MSXML2.DOMDocument.6.0")
xmlDoc.async = False
Dim root As Object
Set root = xmlDoc.createElement("library")
xmlDoc.appendChild root
Dim book As Object
Set book = xmlDoc.createElement("book")
root.appendChild book
' 属性必须在节点已挂到树上之后再设
book.setAttribute "id", "123"
Dim title As Object
Set title = xmlDoc.createElement("title")
title.Text = "VBA实战"
book.appendChild title
保存为UTF-8且带BOM的XML文件需手动处理Save后的字节流
xmlDoc.Save默认用系统ANSI编码(如中文Windows是GBK),打开时中文会乱码。虽然可设xmlDoc.loadXML "" & vbNewLine & ...,但Save仍不认这个encoding声明。真正有效的是用ADODB.Stream重写文件:
- 先用
xmlDoc.Save存临时文件或内存 - 再用
ADODB.Stream读取其字节,设置Charset = "UTF-8",再WriteText写回 - 必须调用
stream.Position = 0重置指针,否则ReadText读不到内容
Dim stream As Object
Set stream = CreateObject("ADODB.Stream")
stream.Charset = "UTF-8"
stream.Open
stream.WriteText xmlDoc.XML
stream.SaveToFile "C:\output.xml", 2 ' 2 = adSaveCreateOverWrite
stream.Close
遇到“Object required”错误大概率是appendChild目标节点为空或未初始化
常见于:忘了给root.appendChild child中的root赋值;或用xmlDoc.selectSingleNode查节点但路径错,返回Nothing,后续对它调用appendChild就崩。调试时先If Not node Is Nothing Then ...检查。
- 用
xmlDoc.documentElement确认根节点存在(若没设过根,它是Nothing) - 节点名区分大小写:
selectSingleNode("Book")查不到 - 避免用
xmlDoc.LoadXML加载含声明的字符串——VBA有时解析失败,直接用createElement构建更稳
appendChild某一层。宁可多写一行If Not parent Is Nothing Then parent.appendChild child,也别赌它一定存在。









