合并两个Private Sub Worksheet_Change时仅首个生效无报错如何解决
问题根因
你这段代码的核心问题出在第二段逻辑的触发条件写反了,除此之外还有几个容易引发异常的隐患:
- 第二段判断逻辑错误:你想要实现的是修改H列的内容时触发行移动逻辑,但是代码里写的是
If Intersect(Target, Range("H:H")) Is Nothing Then,也就是只有修改的单元格不在H列时,才会执行后续移动逻辑,自然你改H列的完成状态时完全不会触发第二段功能。 - 没有加事件防递归机制:第一段执行排序操作时会修改工作表内容,会再次触发
Worksheet_Change事件,不仅可能造成重复执行卡顿,极端情况下会引发栈溢出,也可能干扰后续逻辑运行。 - 无差别使用
On Error Resume Next会吞掉所有运行时报错,所以你调试的时候看不到任何异常提示,很难定位问题。
修正后代码
Private Sub Worksheet_Change(ByVal Target As Range) ' 先关闭事件防止操作工作表触发递归 Application.EnableEvents = False ' 错误捕获:不管执行是否出错,最后都要把事件打开,避免后续宏功能失效 On Error GoTo ErrHandler ' 功能1:修改截止日期时自动重排表格 Dim Table As ListObject Dim SortCol As Range Set Table = Me.ListObjects("Table1") ' 用Me代替ActiveSheet,避免切换工作表时出错 Set SortCol = Me.Range("Table1[Due Date]") If Not Intersect(Target, SortCol) Is Nothing Then With Table.Sort .SortFields.Clear .SortFields.Add Key:=SortCol, Order:=xlAscending .Header = xlYes .Apply End With End If ' 功能2:修改H列状态为Completed时移动行到对应工作表 Dim Z As Long ' 把判断条件反过来:只有修改的是H列的单元格才执行移动逻辑 If Not Intersect(Target, Me.Range("H:H")) Is Nothing Then For Z = 1 To Target.Count ' 这里可以根据你的实际需求调整判断条件,比如判断值等于"Completed" If Target(Z).Value = "Completed" Then Call MoveBasedOnValue End If Next End If ErrHandler: ' 无论是否报错都恢复事件触发 Application.EnableEvents = True ' 如果有错误可以把下面注释打开看报错信息 ' If Err.Number <> 0 Then MsgBox Err.Description End Sub
额外注意事项
- 要确保你调用的
MoveBasedOnValue过程本身没有逻辑错误,可以单独运行测试该过程是否能正常移动行 - 我把原来的
If Target(Z).Value > 0改成了判断值为Completed,如果你的判断逻辑不同可以自行调整 - 所有引用当前工作表的地方都用
Me代替了ActiveSheet,避免你手动切换到其他工作表时宏运行出错
内容的提问来源于stack exchange,提问作者Steeletc4
相关产品推荐
相关产品推荐

