【问题标题】:How to run multiple macros on multiple cell change events in a single worksheet by calling multiple macro functions如何通过调用多个宏函数在单个工作表中的多个单元格更改事件上运行多个宏
【发布时间】:2022-09-25 03:48:15
【问题描述】:

我有一个工作表,我想在多个单元格更改事件和单元格上调用多个 subs。

在此工作表中,Range(\"K3\")Range(\"K32\") 是公式单元格,我想为 Range(\"K3\") 调用 calculation() 和为 Range(\"K32\") 调用 calculation1()

请指导。谢谢

Private Sub Worksheet_Calculate()
Static MyOldVal
Static MyOldVal1
If Range(\"K3\").Value <> MyOldVal Then
Call calculation

Else
If Cells(32, 11).Value <> MyOldVal1 Then Call calculation1

MyOldVal = Range(\"K3\").Value
MyOldVal1 = Range(\"K32\").Value

End If
End Sub

Private Sub calculation()
Cells(4, 10) = (Cells(11, 8) + Cells(16, 8) + Cells(28, 7) + (351 * Cells(25, 3))) / 0.9 / 0.7 * 1.2
Cells(5, 10) = (Cells(11, 8) + Cells(16, 8) + Cells(28, 7) + (351 * Cells(25, 3))) / 0.7 / 0.7 * 1.2
End Sub

Private Sub calculation1()
Cells(33, 10) = (Cells(40, 8) + Cells(45, 8) + Cells(57, 7) + (351 * Cells(54, 3))) / 0.9 / 0.7 * 1.2
Cells(34, 10) = (Cells(40, 8) + Cells(45, 8) + Cells(57, 7) + (351 * Cells(54, 3))) / 0.7 / 0.7 * 1.2
End Sub
  • worksheet_change 事件?

标签: excel vba


【解决方案1】:

例如,您可以这样做:

Private Sub Worksheet_Calculate()
    Static dict As Object   'stored cell addresses and associated cell values
    Dim arrRanges, addr, v
    
    arrRanges = Array("K3", "K32") 'the cells to be monitored

    If dict Is Nothing Then        'first call?  Set up ranges and values
        Set dict = CreateObject("scripting.dictionary")
        For Each addr In arrRanges
            dict(addr) = Me.Range(addr).Value 'initial values
        Next addr
    Else              'not the first call: compare old vs. new values
        On Error Goto haveError
        Application.EnableEvents = False 'disable events
        For Each addr In arrRanges
            v = Me.Range(addr).Value
            If dict(addr) <> v Then      'value has changed ?
                Debug.Print addr, "old:" & dict(addr), "new:" & v
                Select Case addr         'which cell has changed?
                    Case "K3": calculation
                    Case "K32": calculation1
                End Select
                dict(addr) = v           'store new value?
            End If
        Next addr
    End If
haveError:
    Application.EnableEvents = True 're-enable events

End Sub

编辑: 这是一个使用隐藏表的版本

Private Sub Worksheet_Calculate()
    Dim arrRanges, addr, v, wsStore As Worksheet, cStore As Range, vOld
    
    Set wsStore = ThisWorkbook.Sheets("Store") 'hidden sheet
    arrRanges = Array("K3", "K32") 'the cells to be monitored
    
    On Error GoTo haveError
    Application.EnableEvents = False 'disable events
    For Each addr In arrRanges
        v = Me.Range(addr).Value
        Set cStore = wsStore.Range(addr)
        vOld = cStore.Value
        If v <> vOld Then 'value has changed ?
            Debug.Print addr, "old:" & vOld, "new:" & v
            Select Case addr         'which cell has changed?
                Case "K3": Calculation
                Case "K32": calculation1
            End Select
            cStore.Value = v        'store new value
        End If
    Next addr
    
haveError:
    Application.EnableEvents = True 're-enable events
End Sub

【讨论】:

  • 我曾尝试运行这个,当我更改“K3”的值时,calculation() 工作正常,但是当我尝试为calculation1() 更改“K32”时,它显示“运行时错误”的错误28';堆栈空间不足”。需要亲切的指导。
  • 我的错误 - 尝试上面的编辑。更新工作表可能会触发另一个计算,因此您需要避免陷入无限循环。
  • 谢谢,它现在工作得很好。您能否建议有关If dict Is Nothing Then 的解决方案,因为每当用户打开Excel 工作表并更改值时,private sub calculation 不会立即触发,直到用户必须更改值 2 到 3 次。
  • 如果要在会话之间存储值,则可以执行诸如将它们写入隐藏工作表上的单元格之类的操作,否则无法避免第一次计算需要填充字典。
  • 好的。假设我有另一个名为“hidden”的隐藏工作表并在单元格“J1”中写入一个随机值“54”,那么如何添加代码以便每次重新打开工作簿时它都不会填充字典?或者请提出一个解决方案,以便用户无需将值输入 3 到 4 次即可在主表中获得反映的值。合作将不胜感激。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-02-12
  • 2022-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多