VBA智能记录指定列更新时间戳

实例需求:某公司产品统计表如下所示,为了便于追溯变更,如果用户修改了"厂家指导价"或者"供货价",那么"修改时间列"需要记录当前的时间。

这个需要似乎也并不复杂,使用Worksheet_Change事件判断变化发生的列,然后再时间戳即可。但是每个公司都有一些奇葩的用户(领导 ),他们会用尽毕生精力来折腾这个表,为了满足这些奇葩需求,此功能需要支持如下场景:

  • 用户可以在任意位置插入\删除列
  • 用户可以在表格之上或者左侧插入任意多行

效果如下。

实例代码如下:

vb 复制代码
Private Sub Worksheet_Change(ByVal Target As Range)
    Const KEY_COL = "厂家指导价|供货价"
    Const UPDATE_COL = "修改时间"
    Const TAB_NAME = "Tab_Product"
    With Target
        If .CountLarge > 1 Then Exit Sub
        Dim oTab As ListObject: Set oTab = .ListObject
        If oTab Is Nothing Then Exit Sub
        If UCase(oTab.Name) <> UCase(TAB_NAME) Then Exit Sub
        Dim r As Range: Set r = Application.Intersect(oTab.HeaderRowRange, Target)
        If Not r Is Nothing Then Exit Sub
        Set r = Application.Intersect(oTab.HeaderRowRange, .EntireColumn)
        If InStr(1, KEY_COL, r.Value) > 0 Then
            Dim updateCell As Range, iCol
            iCol = Application.Match(UPDATE_COL, oTab.HeaderRowRange, 0)
            If IsError(iCol) Then Exit Sub
            Set updateCell = Application.Intersect(oTab.ListColumns(iCol).Range, .EntireRow)
            Application.EnableEvents = False
            updateCell.Value = Format(Now(), "yyyy/MM/dd hh:mm:ss")
            Application.EnableEvents = True
        End If
    End With
End Sub

【代码解析】

第2行代码定义常量为监控列的标题行名称,以竖线分隔。

第3行代码定义常量为时间戳所在列标题名称。

第4行代码定义常量为表格(ListObject对象)名称。

第6行代码如果多个单元格发生变化,则终止代码执行。

第7行代码获取Target单元格所在的表格,如果对象不存在,说明Target不在表格中,则第8行代码终止代码执行。

如果Target在表格中,第9行代码判断表格名称是否为指导名称,如果不满足条件,则终止代码执行。

第10行代码获取Target和表格标题行的交叉区域,即判断Target是位于标题行中。

如果Target位于标题行中,第11行代码终止代码执行,即无需更新时间戳。

第12行代码获取Target所在列的标题行名称。

第13行代码判断标题行名称存在与监控列表中。

第14行代码调用工作表函数Match在表格标题行中查找时间戳列名称。

第15行代码如果返回结果为错误值(说明表格中不存在时间戳列),则终止代码执行。

第17行代码获取Target所在行和时间戳列的交叉位置单元格。

第18行代码禁用系统事件事件处理功能。

第19行代码更新时间戳。

第20行代码恢复系统事件处理功能。

相关推荐
极客代码4 天前
C语言时间戳处理完全解析:掌握高效日期和时间操作的关键
c语言·开发语言·时间·时间戳·time
HarlanC1 个月前
FFmpeg转码音视频时间戳设置分析
ffmpeg·音视频·时间戳
不喝水的鱼儿2 个月前
【LuatOS】修改LuatOS源码为PC模拟器添加高精度时间戳库timeplus
lua·时间戳·luatos
橘色的喵2 个月前
使用shell实现高精度时间日志记录与时间跳变检测
时间戳·timestamp·时间跳变·时间回退
Web极客码4 个月前
是否应该使用WordPress自动更新的功能
备份·wordpress·自动更新
tekin5 个月前
golang 转换时间戳到字符串函数 支持秒和毫秒时间戳 转换到自定字符串
开发语言·后端·golang·时间戳·time·format·时间戳转换为字符串
会篮球的程序猿5 个月前
php获取,昨,今,后天.... 本周,月,年...日期时间戳
php·时间戳·date·日期·strtotime·时间区间
云草桑6 个月前
WPF 程序 分布式 自动更新 登录 打包
wpf·自动更新
markely8 个月前
IOT系统上位机从OPC 服务器采集,时间戳的问题哪些现象?
物联网·iot·时间戳·opc