Excel VBA中上传XML需分步:先构造XML字符串或DOM对象,再用MSXML2.XMLHTTP60发送,设置Content-Type为text/xml或application/xml,禁用BOM和多余换行,避免FileSystemObject临时文件。
Excel VBA 里用 MSXML2.XMLHTTP 上传 XML 文件
VBA 本身不支持直接“生成并上传 XML”一体化操作,必须分两步:先构造 XML 字符串(或 DOM 对象),再用 HTTP 客户端发出去。关键不是“怎么写 XML”,而是“怎么让服务器接收它”——多数接口要求 Content-Type: text/xml 或 application/xml,且不能有多余 BOM 或换行干扰。
- 别用
FileSystemObject写临时文件再读取上传:慢、多 IO、权限易失败 - 优先用
MSXML2.DOMDocument60构建结构化 XML,调用.xml属性获取字符串;若只是简单拼接,确保手动转义、&、"等字符 - 上传必须用
MSXML2.XMLHTTP60(非WinHttp.WinHttpRequest),后者默认不支持设置Content-Type请求头 - POST 时传原始字符串,不要用
.Send传数组或字典——VBA 会自动序列化成表单格式,服务器收不到 XML
VBA 中构建 XML 的两种可靠方式
拼字符串快但危险,DOM 安全但稍重。选哪个取决于 XML 复杂度和是否含用户输入。
- 纯静态 XML(如固定报文头+单元格值):
xmlStr = "" & vbCrLf xmlStr = xmlStr & "" & Range("A1").Value & "" & Replace(Range("B1").Value, "&", "&") & ""记得手动替换
&→&、→,否则解析失败 - 动态/含嵌套/需验证结构:用
MSXML2.DOMDocument60Set xmlDoc = CreateObject("MSXML2.DOMDocument60") xmlDoc.async = False xmlDoc.loadXML "" Set root = xmlDoc.documentElement Set idNode = xmlDoc.createElement("id") idNode.Text = Range("A1").Value root.appendChild idNode最后用
xmlDoc.xml取字符串,自带编码和转义
上传时常见的 400 / 500 错误原因
服务器返回错误,90% 不是网络问题,而是请求体或头不合规。
-
400 Bad Request:XML 格式非法(检查xmlDoc.parseError.reason)、Content-Type拼错(如写成text/xml;charset=UTF-8,部分 API 只认text/xml)、XML 字符串开头多了 BOM(DomDocument.xml默认无 BOM,拼接字符串也别用StrConv(..., vbFromUnicode)引入) -
401 Unauthorized:没传认证头,或 token 过期——VBA 里加httpObj.setRequestHeader "Authorization", "Bearer " & token -
500 Internal Server Error:服务器端解析失败,常见于字段名大小写不符、必填节点缺失、数值字段传了空字符串而非 - 超时:设
httpObj.setTimeouts 30000, 30000, 60000, 60000(单位毫秒),避免卡死
完整可运行上传示例(含错误处理)
这个片段能跑通大多数 RESTful XML 接口,重点看 setRequestHeader 和 send 的调用时机。