撤消变量后如何保持相交值

时间:2019-08-30 12:08:24

标签: excel vba

我想将相交函数的结果保存在表单更改时的变量中。然后使用相交函数撤消记录相同位置的旧值,以便在变量中包含新旧值

我试图将结果保存到全局变量中,但它没有任何改变

Dim oldValues As Variant
Dim vNew As Variant

Private Sub Worksheet_Change(ByVal Targets As Range)
    'vNew = "new value"
    Set vNew = Intersect(Targets, Targets.Parent.UsedRange)
    Application.EnableEvents = False
    'MsgBox return the new value
    MsgBox vNew(1)
    Application.Undo
    'MsgBox return the old value when I want to save the new for later and I 
    'haven't reassigned my variable
    MsgBox "Vnew After undo " & vNew(1)
    Set vOld = Intersect(Targets, Targets.Parent.UsedRange)

    Application.EnableEvents = True
End Sub

当前,变量vNew被撤消后的旧值修改。虽然我没有重新分配变量。我认为这是因为在调用变量时,Intersect函数会重新启动。请问如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

2件事情:仔细处理Worksheets_Change事件,因为您可以轻松地创建无限循环。其次,在模块开头使用“显式选项”。未声明vOld(是否应该在您的“ oldValues”变量中使用它?)。

这是一个实现您想要的目标的想法: 1.将工作表中的所有值保存在全局词典中 2.随时更改值(并根据需要与旧值交互)

使用此代码创建模块

Public dicOldValues As New Scripting.Dictionary

Private Sub InitializeValues()

    Dim rngCell As Range

    ' Save all values of non empty cells
    For Each rngCell In ThisWorkbook.Worksheets("DataTable")
        If rngCell.Value <> "" Then
            dicOldValues.Add rngCell.Address, rngCell.Value
        End If
    Next rngCell

End Sub

Public Sub UpdateValue(rngTargets As Range)

    Dim rngSelected As Range

    ' Get selected cell
    Set rngSelected = Intersect(rngTargets, rngTargets.Parent.UsedRange)

    'MsgBox return the new value
    MsgBox "New value: " & rngSelected.Value

    ' Print out old value if it exists
    If dicOldValues.Exists(rngSelected.Address) Then
        MsgBox "Old value for this cell: " & dicOldValues.Item(rngSelected.Address)
        ' Save new value
        dicOldValues.Item(rngSelected.Address) = rngSelected.Value
    Else
        dicOldValues.Add rngSelected.Address, rngSelected.Value
    End If

End Sub

打开工作簿时(或在您认为必要时),获取所有初始值:

Private Sub Workbook_Open()
    Call Modul2.InitializeValues
End Sub

在工作表更改事件上调用更新功能

Private Sub Worksheet_Change(ByVal Targets As Range)

    Call Modul2.UpdateValue(Targets)

End Sub

可能仍然存在一些问题(一个问题,取决于工作表的大小和对全局变量的可怕使用,这可能会占用大量内存),但它应该使您满意。

编辑:要使用scripting.dictionary,必须检查对Microsoft.Scripting.Runtime库的引用。或者,您可以使用     CreateObject(“ Scripting.Dictionary”)