如何根据指定单元格值跨工作表引用单元格并解决VBA错误1004
问题原因分析
- 事件递归触发:
Worksheet_Change是工作表内容修改时触发的事件,你在事件内部修改K3单元格的内容,会再次触发该事件,无限循环最终导致报错、Excel崩溃。 - 代码兼容性差:当前仅硬编码判断了2016年的情况,后续新增年份需要反复修改代码,且未做工作表存在性校验,若选中的年份没有对应工作表就会直接报错。
- 单元格引用未指定所属工作表:代码中直接写
Range("J2")默认取当前代码所在工作表的单元格,但特殊场景下可能出现引用错位。
解决方法
直接替换为以下优化后的代码即可:
Option Explicit Sub Worksheet_Change(ByVal Target As Range) ' 仅当修改的单元格是J2时才执行后续逻辑 If Target.Address <> "$J$2" Then Exit Sub ' 关闭事件触发,防止修改单元格时递归触发当前事件 Application.EnableEvents = False On Error GoTo ErrHandler ' 出错时跳转到错误处理 Dim selectYear As String selectYear = Me.Range("J2").Value ' Me指代当前代码所在的工作表 ' 判断对应年份的工作表是否存在,存在则取值,否则赋值0 If WorksheetExists(selectYear) Then Me.Range("K3").Value = ThisWorkbook.Worksheets(selectYear).Range("E12").Value Else Me.Range("K3").Value = "0" End If ExitSub: ' 无论是否出错,都要重新打开事件触发,否则后续Excel事件都会失效 Application.EnableEvents = True Exit Sub ErrHandler: ' 出错时也赋值为0,可根据需要修改为提示信息 Me.Range("K3").Value = "0" Resume ExitSub End Sub ' 辅助函数:判断工作表是否存在 Function WorksheetExists(shtName As String) As Boolean Dim sht As Worksheet On Error Resume Next Set sht = ThisWorkbook.Worksheets(shtName) On Error GoTo 0 WorksheetExists = Not sht Is Nothing End Function
代码说明
- 首先判断触发修改的单元格是否为下拉框所在的J2,无关单元格修改不会触发逻辑,大幅提升运行效率
- 执行逻辑前先关闭事件触发,修改完成后再恢复,从根源上解决递归循环导致的崩溃问题
- 新增工作表存在性校验,就算选中的年份没有对应工作表也不会报错
- 无需硬编码年份,后续新增2018、2019等年份只要新建对应名称的工作表即可,不用修改代码
- 增加了错误捕获机制,哪怕出现其他异常也不会导致Excel崩溃
内容的提问来源于stack exchange,提问作者Ruben Janse van Vuuren
相关产品推荐
相关产品推荐

