我在C2中有一个公式,比如=A2+B2
。每当C2改变值(实际值,而不是公式)时,我希望在D2中更新当前日期和时间。
我尝试了很多VBA代码和技巧,如果在C2中输入公式,它们都不起作用。但是如果我在C2中手动输入值,则会根据需要更新日期和时间。这当然是因为输入/更改了实际值 - 公式保持不变,可以这么说。
问题: 当C2中的公式结果发生变化时,是否可以创建更新D2的VBA代码(或其他内容)?
如果可能,我需要将其激活为单元格C2:C30(+ D2:D30表示日期+时间)
使用Excel 2010。
答案 0 :(得分:10)
您可以通过用户定义函数(VBA宏函数)填充dependend单元格(D2),该函数将C2-Cell的值作为输入参数,将当前日期作为输出返回。
在D2中将C2作为UDF的输入参数告诉Excel每次C2更改时都需要重新评估D2(即如果为工作簿打开公式的自动计算)。
修改强>
以下是一些代码:
对于UDF:
Public Function UDF_Date(ByVal data) As Date
UDF_Date = Now()
End Function
作为D2中的公式:
=UDF_Date(C2)
您必须为D2-Cell提供日期时间格式,否则它将显示日期值的数字表示。
如果将C2参考保留在D2公式相对值中,则可以通过拖动来扩展所需范围内的公式。
注意:强> 这仍然可能不是理想的解决方案,因为每次Excel重新计算工作簿时,D2中的日期将重置为当前值。 为了使D2仅反映C2最后一次更改,必须对C2的过去值进行某种跟踪。 例如,这可以通过在输入参数的值旁边提供地址,将输入参数存储在隐藏表中,并在每次调用UDF时将它们与先前的值进行比较来在UDF中实现。
<强>附录:强>
以下是UDF的示例实现,它跟踪单元格值的更改并返回检测到上次更改时的日期时间。 使用时请注意:
UDF的用法与上述相同。
UDF仅适用于单个单元格输入范围。
通过存储单元格的最后一个值来跟踪单元格值 在文档属性中检测到更改的日期时间 工作簿。如果公式用于大型数据集的大小 对于跟踪的每个单元格,文件可能会显着增加 存储要求增加的公式(单元格的最后一个值+ 最后一次更改的日期。)此外,Excel可能无法处理 非常大量的文档属性和代码可能会制动 某一点。
如果更改了工作表的名称,则其中包含的单元格的所有跟踪信息都将丢失。
代码可能会为转换为字符串的单元格值进行制动。
以下代码为未经过测试,仅作为证明 概念。 使用它需要您自担风险。
Public Function UDF_Date(ByVal inData As Range) As Date
Dim wb As Workbook
Dim dProps As DocumentProperties
Dim pValue As DocumentProperty
Dim pDate As DocumentProperty
Dim sName As String
Dim sNameDate As String
Dim bDate As Boolean
Dim bValue As Boolean
Dim bChanged As Boolean
bDate = True
bValue = True
bChanged = False
Dim sVal As String
Dim dDate As Date
sName = inData.Address & "_" & inData.Worksheet.Name
sNameDate = sName & "_dat"
sVal = CStr(inData.Value)
dDate = Now()
Set wb = inData.Worksheet.Parent
Set dProps = wb.CustomDocumentProperties
On Error Resume Next
Set pValue = dProps.Item(sName)
If Err.Number <> 0 Then
bValue = False
Err.Clear
End If
On Error GoTo 0
If Not bValue Then
bChanged = True
Set pValue = dProps.Add(sName, False, msoPropertyTypeString, sVal)
Else
bChanged = pValue.Value <> sVal
If bChanged Then
pValue.Value = sVal
End If
End If
On Error Resume Next
Set pDate = dProps.Item(sNameDate)
If Err.Number <> 0 Then
bDate = False
Err.Clear
End If
On Error GoTo 0
If Not bDate Then
Set pDate = dProps.Add(sNameDate, False, msoPropertyTypeDate, dDate)
End If
If bChanged Then
pDate.Value = dDate
Else
dDate = pDate.Value
End If
UDF_Date = dDate
End Function
答案 1 :(得分:4)
以范围为条件插入日期。
这样做的好处是不更改日期,除非更改单元格的内容,并且它在C2:C2范围内,即使关闭并保存工作表,除非相邻单元格发生更改,否则不会重新计算
改编自this tip和@Paul S回答
Private Sub Worksheet_Change(ByVal Target As Range)
Dim R1 As Range
Dim R2 As Range
Dim InRange As Boolean
Set R1 = Range(Target.Address)
Set R2 = Range("C2:C20")
Set InterSectRange = Application.Intersect(R1, R2)
InRange = Not InterSectRange Is Nothing
Set InterSectRange = Nothing
If InRange = True Then
R1.Offset(0, 1).Value = Now()
End If
Set R1 = Nothing
Set R2 = Nothing
End Sub
答案 2 :(得分:0)
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$C$2" Then
ActiveSheet.Range("D2").Value = Now()
End If
End Sub
答案 3 :(得分:0)
最简单的方法是添加=IF(B3="","Not Allocated",Now())
并将列的格式更改为所需的日期和时间格式。但是,如果编辑了B列,则需要更新的相应列的日期和时间将自动更新所有列,因为不检查旧值。但如果能够获得当前时间,这很容易使用。