【问题标题】:VBA Worksheet_Change Only Working For One CellVBA Worksheet_Change 仅适用于一个单元格
【发布时间】:2020-03-18 05:27:36
【问题描述】:

我想先说我是 VBA 的新手,所以希望这是一个简单的解决方法。 我正在尝试使以下 VBA 代码适用于具有公式的多个单元格。效果是单元格中有一个幻影值,用户可以覆盖然后再次查看他们是否删除了它们的值。我可以让一个单元按我想要的方式工作,但第二个(以及第三个和第四个等)不起作用。如何重复同一行代码,以使效果在具有不同公式的多个单元格中重复出现?

工作:

Private Sub Worksheet_Change(ByVal Target As Excel.Range)    
    With Target
      If .Address(False, False) = "F7" Then
        If IsEmpty(.Value) Then
          Application.EnableEvents = False
          .Formula = "=IFERROR(INDEX(DATABASE!$D$2:$AG$3222,MATCH('Pricing Grid'!$B$11,DATABASE!$E$2:$E$3222,0),10),0)"
          Application.EnableEvents = True
        End If
      End If
    End With    
End Sub

我的尝试(顶部工作,底部不):

Private Sub Worksheet_Change(ByVal Target As Excel.Range)
  With Target
    If .Address(False, False) = "F7" Then
      If IsEmpty(.Value) Then
        Application.EnableEvents = False
        .Formula = "=IFERROR(INDEX(DATABASE!$D$2:$AG$3222,MATCH('Pricing Grid'!$B$11,DATABASE!$E$2:$E$3222,0),10),0)"
        Application.EnableEvents = True
      End If
    End If
  End With
End Sub

Private Sub Worksheet_Change1(ByVal Target As Excel.Range)
  With Target
    If .Address(False, False) = "F8" Then
      If IsEmpty(.Value) Then
        Application.EnableEvents = False
        .Formula = "=IFERROR(INDEX(DATABASE!$D$2:$AG$3222,MATCH('Pricing Grid'!$B$11,DATABASE!$E$2:$E$3222,0),9),0)"
        Application.EnableEvents = True
      End If
    End If
  End With
End Sub

【问题讨论】:

  • 另外,有人可以建议一种将数组公式合并到 .Formula = "~~~~" 部分的方法吗?我随后的尝试引发了错误。 .ArrayFormula = "=IFERROR(INDEX(DATABASE!$D$2:$AG$3222,MATCH(1,($B$11=DATABASE!$E$2:$E$3222) * (H3=DATABASE!$T$2:$T $3222) * (H4=DATABASE!U2:U3222),0),26),"")"
  • 公式末尾的10 vs 9背后的逻辑是什么?
  • 它从数据数组中绘制不同的变量以显示在电子表格的不同单元格中。
  • 每个工作表只有一个 Worksheet_Change 事件。您不能仅通过类似地命名过程来添加更多内容。您的所有逻辑都必须来自一个事件,就像蒂姆的回答所展示的那样。
  • 由于您正在处理Worksheet_Change 事件,THIS 值得一读。

标签: excel vba


【解决方案1】:

试试这个...

Private Sub Worksheet_Change(ByVal Target As Range)
  Dim i&, j&, v, t
  v = Target.Value2
  If Not IsArray(v) Then t = v: ReDim v(1 To 1, 1 To 1): v(1, 1) = t
  Application.EnableEvents = False
  For i = 1 To UBound(v)
    For j = 1 To UBound(v, 2)
      If Len(v(i, j)) = 0 Then
        With Target(i, j)
            Select Case .Address(0, 0)
                Case "A1": .Formula = "=""Excel"""
                Case "A2": .Formula = "=""Hero"""
            End Select
        End With
      End If
    Next
  Next
  Application.EnableEvents = True
End Sub

当然,用你的公式和范围代替我的。


更新

上述方法效果很好,但这样更快/更好......

Private Sub Worksheet_Change(ByVal Target As Range)
  Dim i&, v
  DoEvents
  ReDim v(1 To 3, 1 To 2)
  v(1, 1) = "A1": v(1, 2) = "=""This"""
  v(2, 1) = "A2": v(2, 2) = "=""Works"""
  v(3, 1) = "A2": v(3, 2) = "=""Great!"""
  Application.EnableEvents = False
  For i = 1 To UBound(v)
    With Range(v(i, 1))
      If Not Intersect(Target, .Cells) Is Nothing Then
        If Len(.Value2) = 0 Then
          .Formula = v(i, 2)
        End If
      End If
    End With
  Next
  Application.EnableEvents = True
End Sub

上述两种方法都适用于单单元格删除,也适用于清除和删除大范围,包括整列和整行,第二种方法在所有这些情况下都特别快。

【讨论】:

  • 这正是我要找的!寻找最后一个相关的事情......如果属于“This”“Works”Great"引号的公式是一个数组公式,我该如何让它工作?
  • 在循环中间,将.Formula =更改为.FormulaArray =
  • 如果我的 if 公式的值 if false 是字符串 ("") 我应该更改什么?一旦工作,电子表格将完成!谢谢大家的帮助
  • Excel Hero 是一个合适的用户名
  • 我不明白你对 IF 公式的问题。
【解决方案2】:

你可以这样做:

Private Sub Worksheet_Change(ByVal Target As Excel.Range)

    'only handle single cells
    If Target.Cells.CountLarge > 1 Then Exit Sub
    If IsError(Target.Value) Then Exit Sub  '<< edit: added
    'only handle empty cells
    If Len(Target.Value) > 0 Or Len(Target.Formula) > 0 Then Exit Sub

    On Error Goto haveError
    Application.EnableEvents = False
    Select Case Target.Address(False, False)
        Case "F7": Target.Formula = "=IFERROR(INDEX(DATABASE!$D$2:$AG$3222,MATCH('Pricing Grid'!$B$11,DATABASE!$E$2:$E$3222,0),10),0)"
        Case "F8": Target.Formula = "=IFERROR(INDEX(DATABASE!$D$2:$AG$3222,MATCH('Pricing Grid'!$B$11,DATABASE!$E$2:$E$3222,0),9),0)"
    End Select

haveError:
    'ensure events are re-enabled
    Application.EnableEvents = True
End Sub

【讨论】:

  • 我认为您的意思是 Application.EnableEvents = True 在 End Sub 上方。
  • 这与初始工作代码的结果相同。单元格 F7 反应正常,但单元格 F8 没有。有什么建议么?并感谢您的帮助!
  • 调试器捕捉到这行代码: If Len(Target.Value) > 0 Or Len(Target.Formula) > 0 Then Cell F8 的美元金额为 $0.00-$10.00(如果这意味着什么)跨度>
  • 添加了一行来捕获错误值并退出(如果你愿意,你可以决定对这些值做一些不同的事情)
猜你喜欢
  • 1970-01-01
  • 2017-11-01
  • 2021-05-26
  • 1970-01-01
  • 2018-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多