Excel VBA解析ISBN对应XML获取书名时触发运行时错误91
解决Excel VBA解析ISBN XML时的Run-time Error 91问题
错误原因分析
Run-time Error 91本质是对象引用未设置,也就是xmlDoc.SelectSingleNode返回了Nothing,后续代码尝试访问它的属性(比如.Attributes("title").Text)时触发错误,常见诱因:
- 在线XML加载失败(网络波动、ISBN对应XML不存在)
- XPath表达式编写错误,无法匹配目标节点
- XML文档包含命名空间,未在解析时声明导致节点查找失败
修正后的VBA代码
Sub GetBookTitleFromISBN() Dim xmlDoc As Object Dim ws As Worksheet Dim lastRow As Long Dim i As Long Dim isbn As String Dim xmlUrl As String Dim targetNode As Object ' 设置工作表(根据实际表名修改) Set ws = ThisWorkbook.Worksheets("Sheet1") lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row ' 创建XML文档对象 Set xmlDoc = CreateObject("MSXML2.DOMDocument.6.0") xmlDoc.async = False ' 根据目标XML的实际命名空间调整,示例为常见图书XML命名空间 xmlDoc.setProperty "SelectionNamespaces", "xmlns:dc='http://purl.org/dc/elements/1.1/' xmlns:bib='http://purl.org/net/biblio#'" For i = 1 To lastRow isbn = Trim(ws.Cells(i, "A").Value) If isbn <> "" Then ' 构造XML请求URL(示例用Open Library接口,根据实际数据源调整) xmlUrl = "https://openlibrary.org/api/books?bibkeys=ISBN:" & isbn & "&format=xml&jscmd=data" ' 加载XML并处理加载错误 If xmlDoc.Load(xmlUrl) Then ' 优先查找format为Book的work节点 Set targetNode = xmlDoc.SelectSingleNode("//work[@format='Book']") If Not targetNode Is Nothing Then ws.Cells(i, "B").Value = targetNode.Attributes("title").Text Else ' 备选方案:查找第一个work节点 Set targetNode = xmlDoc.SelectSingleNode("//work") If Not targetNode Is Nothing Then ws.Cells(i, "B").Value = targetNode.Attributes("title").Text Else ws.Cells(i, "B").Value = "未找到匹配书名" End If End If Else ' 加载失败时返回错误原因 ws.Cells(i, "B").Value = "XML加载失败:" & xmlDoc.parseError.reason End If Else ws.Cells(i, "B").Value = "ISBN为空" End If Next i ' 释放对象 Set xmlDoc = Nothing Set ws = Nothing MsgBox "处理完成" End Sub
关键修正点
- 加载结果校验:先判断
xmlDoc.Load的返回值,避免加载失败后继续执行节点查找 - 节点存在性判断:访问节点属性前,必须确认
targetNode不为Nothing - 命名空间声明:如果目标XML带命名空间,必须通过
setProperty "SelectionNamespaces"声明,否则XPath无法匹配节点 - 备选逻辑:优先节点不存在时,提供兜底查找方案,避免直接报错
额外注意事项
- 确保Excel允许访问外部数据:在文件选项→信任中心→信任中心设置→宏设置中,启用对VBA项目的信任,同时允许外部内容加载
- 手动验证XML结构:先访问单个ISBN对应的XML地址,确认节点结构、命名空间,再调整XPath表达式
- 控制请求频率:ISBN数量较多时,添加
Application.Wait Now + TimeValue("00:00:01")延迟,防止被数据源限制访问
内容的提问来源于stack exchange,提问作者user1883779
相关产品推荐
相关产品推荐

