我希望在复制单个单元格并将其粘贴到多个单元格时获取以前的单元格值。 How can I determine new & previous cell value on SheetChange event in Excel?足以检测单个单元格的先前值。但是,当我尝试复制一个单元格(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
}
}
答案 0 :(得分:1)
我害怕实现你的目标,监控所有的单元格:
制作"镜像"整个" base"的副本片
每个单元格将引用" base"中的相应单元格。表格(即"镜像"表格A1单元格将具有" =" baseSheetName!A1"公式"等等)
在更改" base"之前设置Application.Calculation = xlCalculationManual
工作表(可能在工作簿开头时将其设置为工作簿的默认配置)
使用Worksheet_SelectionChange()事件处理程序的Target
参数来选择相应的"镜像"由于Application.Calculation = xlCalculationManual
设置,表单单元格仍具有上一个值
如果你关注的是数量有限的" base"单元格,你可以以类似的方式继续,但保持"镜像" " base"中的细胞表单本身
在后一种情况下,这里有一个处理它的代码(注意:VBA代码,但您可以轻松地在C#和#34中翻译;)
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
你必须在你的" base"中设置一个命名范围(我称之为" sensitiveRange")包含必须跟踪的所有单元格的工作表
答案 1 :(得分:1)
您可以在运行Undo
之前获取所选内容,并在流程结束时将其恢复。
注意:如果工作表未处于活动状态(如果工作表正在按代码更新),则最后的选择将失败,因此您可能需要检查该工作表。
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