Excel VBA偶发Error 91:对象变量或With块变量未设置
问题排查与解决方案
核心原因分析
Error 91的本质是你尝试访问一个未初始化的对象,具体到你的代码里,就是DPIE.document.getElementsByClassName("right")(171)或者(172)返回了Nothing,导致后续调用.innerHTML失败。之所以下标51/52的模块正常,171/172的偶发报错,主要有两个原因:
页面等待逻辑不充分
你当前只通过Do While DPIE.Busy等待页面加载,但IE的Busy状态仅表示浏览器是否在加载资源,当页面框架加载完成但后续动态内容(比如靠后的元素)还没渲染时,Busy就会变为False。下标171/172的元素属于页面较靠后的位置,加载完成时间更晚,此时直接去取元素就会拿到Nothing;而51/52是靠前的元素,加载更快,所以很少触发问题。硬编码索引的不稳定性
页面的DOM结构可能存在动态变化(比如网站更新、动态加载模块、登录状态不同导致内容变化),这会导致right类的元素数量波动。如果某一次加载后,right类元素总数不足173个(索引从0开始,172是第173个元素),那直接取(171)或(172)就会越界,返回Nothing。
修复方案
1. 完善页面加载等待逻辑
替换原来的等待代码,同时判断Busy和ReadyState,并且增加对目标元素的存在性检查:
Dim DPIE As Object Set DPIE = CreateObject("internetexplorer.application") With DPIE .navigate "http://www.cyclingsimulator.com/team/The_Modern_Timurids" .Visible = False End With ' 等待页面完全加载,包括DOM解析完成 Do While DPIE.Busy Or DPIE.ReadyState <> 4 DoEvents Loop ' 等待目标元素加载完成(针对171索引的元素) Dim DPInfo As Object Do While True Set DPInfo = DPIE.document.getElementsByClassName("right")(171) If Not DPInfo Is Nothing Then Exit Do DoEvents ' 可选:增加超时逻辑,防止无限等待 ' Static startTime As Date: If startTime = 0 Then startTime = Now: If Now - startTime > TimeValue("00:00:10") Then Exit Do Loop Dim DPValue As String DPValue = DPInfo.innerHTML ' 同理处理172索引的元素 Dim RSInfo As Object Do While True Set RSInfo = DPIE.document.getElementsByClassName("right")(172) If Not RSInfo Is Nothing Then Exit Do DoEvents Loop Dim RSValue As String RSValue = RSInfo.innerHTML DPIE.Quit Set DPIE = Nothing
2. 避免硬编码索引,改用精准定位
依赖类名的索引是非常脆弱的,建议根据元素的上下文来定位。比如先找到包含目标数据的父容器,再从父容器里找right类元素,或者结合元素的文本内容、相邻元素来定位:
' 示例:先找到父容器(假设父容器有唯一id) Dim parentContainer As Object Set parentContainer = DPIE.document.getElementById("team-stats") If Not parentContainer Is Nothing Then ' 在父容器内找right类元素,此时索引会更稳定 Set DPInfo = parentContainer.getElementsByClassName("right")(0) ' 此处索引根据实际结构调整 End If
额外建议
- 给所有对象变量加上显式的类型声明(比如
Dim DPInfo As Object),避免隐式变体类型带来的问题。 - 增加错误捕获逻辑,提升模块稳定性:
On Error Resume Next Set DPInfo = DPIE.document.getElementsByClassName("right")(171) On Error GoTo 0 If DPInfo Is Nothing Then MsgBox "目标元素未找到" DPIE.Quit Set DPIE = Nothing Exit Sub End If
内容的提问来源于stack exchange,提问作者I am Here
相关产品推荐
相关产品推荐

