Excel:来自范围的以前的值

当我复制单个单元格并将其粘贴到多个单元格时,我想获得以前的单元格值。 如何确定Excel中SheetChange事件的新的和以前的单元格值? 对于检测单个单元先前的值是足够好的。 但是,当我试图复制一个单元格(CTRL + V,拖动等),并将其应用于多个单元格,以前的值都检测不到。 相反,值的数组等于第一个单元格,这导致我得出的结论是单元格在SheetSelectionChange事件发生之前发生更改。 任何想法如何处理这个?

private void Application_SheetSelectionChange(object Sh, Excel.Range Target) { try { if (Target.Value2 != null) { foreach (Excel.Range range in Target) { // Each range in Target has same value as first value instead of previous value } } } catch (Exception ex) { // Log stuff } } 

您可以在运行“ Undo之前抓取select,并在过程结束时将其恢复。

注意:如果工作表未处于活动状态(例如在工作表由代码更新的情况下),则select在最后将失败,因此您可能需要检查。

 Private Sub Worksheet_Change(ByVal Target As Range) Dim Where As String, OldValue As Variant, NewValue As Variant Dim r As Long, c As Long, tmp Dim sel As Object '<<< current selection: not always a Range! Dim rngTrack As Range On Error GoTo haveError Application.EnableEvents = False Set sel = Selection '<<< capture the selection Where = Target.Address NewValue = Target.Value Application.Undo OldValue = Target.Value 'get the previous values Target.Value = NewValue Application.EnableEvents = True Set rngTrack = Sheets("Tracking").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0) 'set some limit for the size of change you want to track If Target.Cells.CountLarge < 1000 Then 'convert single-cell values to array... If Target.Cells.CountLarge = 1 Then OldValue = ToArray(OldValue) NewValue = ToArray(NewValue) End If 'multi-cell: treat as arrays For r = 1 To UBound(OldValue, 1) For c = 1 To UBound(OldValue, 2) If OldValue(r, c) <> NewValue(r, c) Then rngTrack.Resize(1, 3).Value = _ Array(Target.Cells(r, c).Address, OldValue(r, c), NewValue(r, c)) Set rngTrack = rngTrack.Offset(1, 0) End If Next c Next r End If sel.Select '<<< reset the selection Exit Sub haveError: Application.EnableEvents = True End Sub 'utility function Private Function ToArray(v) Dim rv(1 To 1, 1 To 1) rv(1, 1) = v ToArray = rv End Function 

我害怕实现你的目标监控你必须的所有工作表单元:

  • 制作整个“基本”表的“镜像”副本

    其中的每个单元格将具有对“基本”表单中相应单元格的引用(即“镜像”表单A1单元格将具有“=”baseSheetName!A1“公式”等等)

  • 设置Application.Calculation = xlCalculationManual之前,任何更改“基本”表(可能将其设置为您的工作簿在其打开时的默认configuration)

  • 使用Worksheet_SelectionChange()事件处理程序的Target参数来select相应的“Mirror”工作表单元格,这要感谢Application.Calculation = xlCalculationManual设置,它仍然具有以前的值

如果您的担心是关于有限数量的“基本”工作表单元格,则可以采用类似的方式继续,但在“基本”工作表本身中保留“镜像”单元格

在后一种情况下,这里有一个代码来处理它(注意:VBA代码,但你可以很容易地在C#中翻译)

 Private Sub Worksheet_SelectionChange(ByVal Target As Range) Dim sensitiveRange As Range Dim sensitiveRangeSelected As Range Set sensitiveRange = Range("sensitiveRange") Set sensitiveRangeSelected = Application.Intersect(sensitiveRange, Target) If sensitiveRangeSelected Is Nothing Then ' no 'sensitive' cells --> go ahead Else ' 'sensitive' cells !! -> add code to handle thier value or store it in some array End If End Sub 

你必须在你的“基本”表中设置一个命名的范围(我称之为“敏感范围”),并且必须跟踪其所有的单元格