在两个工作簿上的公式结果更改中触发宏

时间:2017-06-23 10:29:29

标签: excel vba excel-vba

我的问题很简单:我有两本工作簿(假设它们是wb1和wb2)。

在wb2的ws2上,我在Range("A1")上有='[wb1.xlsm]ws1'B1之类的公式。因此,当wb1的ws1上的B1发生变化时,wb2的ws2上的A1也会发生变化(这就是目标)。

我的问题是当ws2上的A1值发生变化时如何触发宏? Worksheet_Change不会触发,Workbook_SheetChange在这种情况下不适合......

编辑顺便说一下,Worksheet_Calculate也不合适。实际上,我不知道ws2的价值会在哪里发生变化。

1 个答案:

答案 0 :(得分:1)

在回答您的问题之前,我不得不强调有很多really good reasons可以避免链接的工作簿。它总是以痛苦,痛苦,数据丢失以及试图将数据追溯到其来源所花费的长时间浪费而结束。重要的是,你可以忽略我的建议。

此代码使用VBA collection对象,这非常垃圾。 VBScript包含更好的dictionary object,您可以在VBA中使用它。我强烈建议进一步调查......

代码分为两部分。第一个元素运行一次。它找到并开始跟踪给定工作表中的每个外部参考。

' Find all formulas that point to external workbook.
' Store current value.
Sub Initialise()
    Dim c As Range      ' Used to loop over all cells, looking for external.

    ' Ready collection for use.
    Set ExternalFormula = New Collection

    For Each c In [Sheet1].UsedRange

        ' Check if external, will start: =[
        If c.HasFormula And c.Formula Like "=[[]*" Then

            ' Value added to collection contains key, for later use.
            ' Collections cannot return keys.
            ' Dictionaries are better, but require an external reference.
            ExternalFormula.Add c.address & "~~~" & c.Value, c.address
        End If
    Next
End Sub

下一部分包含在Calculate事件中。 Calculate未提供更新的单元格地址。但是使用ExternalFormula集合,我们可以确定哪个单元格已更新。

' Check external formula for changes.
Private Sub Worksheet_Calculate()
    Dim c As Integer            ' Used to loop over forumla.
    Dim address As String      ' A1 style address of current forumla.
    Dim oldValue As String      ' Value before any updates.

    ' Loop over stored values, looking for change.
    If ExternalFormula.Count > 0 Then
        For c = 1 To ExternalFormula.Count

            ' Extract address and old value.
            address = Split(ExternalFormula.Item(c), "~~~")(0)
            oldValue = Split(ExternalFormula.Item(c), "~~~")(1)

            ' Check for changes.
            If [Sheet1].Range(address).Value <> oldValue Then

                ' Change found.
                MsgBox address & " updated", vbInformation

                ' Update stored value.
                ExternalFormula.Remove address
                ExternalFormula.Add address & "~~~" & [Sheet1].Range(address).Value, address
            End If
        Next
    End If
End Sub

使用字典对象会大大减少该函数中的代码行数。

不要忘记在工作簿或工作表级别声明ExternalFormula

Private ExternalFormula As Collection       ' Stores all external forumulas.