根据另一个通过公式填充的单元格自动插入今天的日期

时间:2018-07-11 08:31:21

标签: excel vba excel-vba

使用MS Excel,如果使用公式=IF(B4<>"","2018-CI-"&ROWS(A$4:A4),"")来使B列中的单元格不为空白,并且可以正常工作,则可以使(列A)中的单元格自动生成(作为ID)。

我想做的是,当我在A1列的单元格中生成代码时,要自动将数据输入的日期插入D列同一行的单元格中。

因此,当用户在Col.B中写入新的项目名称时,除了在Col.D中自动生成的输入日期外,还将在Col.A中自动生成代码。 (我想将日期设为静态,因此如果更改项目名称,则日期不会更改,因为ID不会更改。)

我正在使用此VBA代码:

Private Sub Worksheet_Change(ByVal Target As Range)
Dim xCellColumn As Integer
Dim xTimeColumn As Integer
Dim xRow, xCol As Integer
xCellColumn = 1
xTimeColumn = 4
xRow = Target.Row
xCol = Target.Column
If Target.Text <> "" Then
    If xCol = xCellColumn Then
       Cells(xRow, xTimeColumn) = Format(Now, "mm/dd/yyyy HH:mm:ss")
    End If
End If
End Sub

但是,在Col.D的单元格中什么都没有影响,如果我将xCellColumn = 1更改为xCellColumn = 2,即Col.B(表中的项目名称),则代码可以正常工作。

这张在excel上的表格图片:enter image description here

我做错什么了吗?请问你能帮帮我吗?

2 个答案:

答案 0 :(得分:1)

根据Format()函数的MDN文档:

  

说明返回包含表达式的变量(字符串)   根据格式表达式中包含的指令进行了格式化。   语法格式(表达式[,格式[,年的firstdayof周[,年的firstweekof   ]]])

这不是您要实现的目标,但不必担心,Excel已经具有一个内置函数来返回当前日期-它的名称也很直观-如果需要日期,则date()。如果您还想跟踪时间,请改用now()

经测试可正常工作

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Range(Cells(1, 2), Cells(Rows.Count, 2)), Target) Is Nothing Then

                If IsEmpty(Target.Offset(0, 2)) Then
                    Target.Offset(0, 2).Value2 = Now
                    Target.Offset(0, 2).NumberFormat = "mm/dd/yyyy HH:mm:ss"
                End If
    End If

End Sub

尽管我可能会推荐@PEH的实现,因为它还可以跟踪我在答案中未考虑的多个条目

答案 1 :(得分:1)

诀窍是检查日期是否已经写入,而不要再次写入。因此,仅在您第一次在B列中添加项目名称时添加它。

Private Sub Worksheet_Change(ByVal Target As Range)

    Const TimeColumn = "D"

    If Not Intersect(Target, Range("B:B")) Is Nothing Then 'only trigger on column B

        Dim TargetRow As Range
        For Each TargetRow In Target.Rows 'needed if multiple rows are filled at once eg (copy/paste in col B)
            If Cells(TargetRow.Row, TimeColumn).Value = vbNullString Then 'test if there is already a date
                With Cells(TargetRow.Row, TimeColumn)
                    .Value = Now() 'write the value
                    .NumberFormat = "mm/dd/yyyy HH:mm:ss" 'format it
                End With
            End If
        Next TargetRow

    End If

End Sub

您可能希望将Range("B:B")更改为计划输入Range("B4:B" & Rows.Count)这样的数据的范围,以免在标题中触发。

还请注意,可能会在B列中插入多行,例如通过复制粘贴。这就是为什么我们需要循环For Each TargetRow In Target.Rows以便每个添加的行都记录其日期。

还要注意,我们需要使用.NumberFormat来格式化单元格中的值。 Format(Now, "mm/dd/yyyy HH:mm:ss")不起作用,因为它将日期添加为文本(字符串),但未添加为日期值(您可以用计算得出)。