VBA循环中执行Find and Replace触发Run-time Error '91'问题
解决Excel宏中无匹配单元格时的Run-time Error '91'问题
你的问题核心在于当Cells.Find找不到含"K"的单元格时,它会返回Nothing(空对象),这时候你直接调用.Activate就会触发"对象变量或With块变量未设置"的错误——因为根本没有可激活的单元格对象。另外,你原来的For Each Cell循环其实是多余的,Find和FindNext本身就能遍历所有匹配项,不需要逐个单元格检查。
修正后的宏代码
Sub TestingFindAndReplace() Dim foundCell As Range Dim firstFoundAddress As String ' 查找第一个含"K"的单元格 Set foundCell = ActiveSheet.UsedRange.Cells.Find(What:="K", _ LookIn:=xlFormulas, LookAt:=xlPart, _ SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=True) ' 如果找到匹配项,开始遍历处理 If Not foundCell Is Nothing Then firstFoundAddress = foundCell.Address ' 记录第一个匹配的地址,避免无限循环 Do ' 替换"K"为空并乘以1000,直接操作单元格,无需激活 foundCell.Value = Replace(foundCell.Value, "K", "") * 1000 ' 查找下一个匹配项 Set foundCell = ActiveSheet.UsedRange.Cells.FindNext(After:=foundCell) ' 当回到第一个匹配的单元格时,退出循环 Loop While Not foundCell Is Nothing And foundCell.Address <> firstFoundAddress End If End Sub
关键改进点说明
- 用对象变量接收查找结果:通过
Set foundCell = Cells.Find(...)捕获查找结果,然后用If Not foundCell Is Nothing判断是否找到匹配,从根源避免空对象操作错误。 - 避免依赖ActiveCell:直接对
foundCell对象进行值修改,不需要激活单元格,代码更高效也更稳定。 - 正确遍历所有匹配项:用
FindNext配合firstFoundAddress记录起始位置,确保遍历所有匹配单元格且不会陷入无限循环。 - 移除多余的For Each循环:
Find系列方法本身就是专门用来查找所有匹配项的,逐个单元格循环完全没必要,还会降低效率。
为什么你的原代码会出错
你原代码里的Cells.Find(...).Activate在找不到匹配时,Cells.Find(...)返回Nothing,这时候调用.Activate就相当于对空对象执行操作,自然会抛出Error 91。另外,For Each Cell循环会让你重复执行查找操作,逻辑上也有冗余。
内容的提问来源于stack exchange,提问作者Jamey Cane
相关产品推荐
相关产品推荐

