当前位置:   article > 正文

VBA锁定单元格并记录单元格修改日志无bug篇_vba .locked

vba .locked

 先看效果: 

在模块中插入以下代码

  1. Type OldRng
  2. Formula As Variant '保存值
  3. Address As String '保存地址
  4. Locked As Boolean '是否锁定
  5. Changed As Boolean '是否被修改
  6. End Type
  7. Public iRng() As OldRng '用来锁定的单元格

在工作表sheet1中插入以下代码,新建一个sheet,在工程中将名字改为log如图:

然后在sheet2中A20单元格中输入2,表示从第二行开始写日志

  1. Option Explicit
  2. Private iRngFull As Boolean 'iRng是否为nothing
  3. Private Sub Worksheet_SelectionChange(ByVal Target As Range)
  4. 'Application.ScreenUpdating = False
  5. 'Application.Calculation = xlCalculationManual
  6. Dim i As Long
  7. Dim logLine As Long
  8. Dim flashFlag As Boolean 'true:被锁定的单元格值被修改了;false:被锁定的单元格值没有修改
  9. Dim valueChangeFlag As Boolean 'true:没有锁定的单元格值被修改了;false:没有锁定的单元格值没有修改
  10. '判断首次改变单元格
  11. If Not iRngFull Then
  12. '首次改变选中的单元格则保存本次选中单元格为下次改变选中作准备
  13. saveIRng Target, False
  14. '退出sub
  15. Exit Sub
  16. End If
  17. Application.StatusBar = False
  18. For i = 1 To UBound(iRng)
  19. '判断值改变
  20. If Range(iRng(i).Address).Formula <> iRng(i).Formula Then
  21. If iRng(i).Locked Then
  22. '如果改变标记flashFlag
  23. flashFlag = True
  24. '存放锁定的单元格序列在iRng中,将要还原的值
  25. iRng(i).Changed = True
  26. 'i = UBound(iRng)
  27. Else
  28. With log
  29. logLine = .Cells(1, 20)
  30. .Cells(logLine, 1) = Now
  31. .Cells(logLine, 2) = iRng(i).Address
  32. .Cells(logLine, 3).NumberFormatLocal = "@"
  33. .Cells(logLine, 3) = iRng(i).Formula
  34. .Cells(logLine, 4) = Range(iRng(i).Address)
  35. .Cells(1, 20) = logLine + 1
  36. End With
  37. '存放没有锁定的单元格序列在iRng中,也就是被修改了的值
  38. valueChangeFlag = True
  39. '标记没有锁定单元格的改变状态
  40. iRng(i).Changed = True
  41. End If
  42. End If
  43. Next i
  44. If flashFlag Or valueChangeFlag Then
  45. Application.StatusBar = iRng(0).Address & "__中有已应用锁定的单元格"
  46. If flashFlag Then
  47. '运行到这里就说明单元格的值被修改了,下面是处理还原的代码
  48. '应用手动计算,提高效率,没有关闭屏幕刷新是为了让用户看到值被还原的过程
  49. Application.Calculation = xlCalculationManual
  50. For i = 1 To UBound(iRng)
  51. If Range(iRng(i).Address).Column < 26 And iRng(i).Locked Then
  52. Range(iRng(i).Address).Formula = iRng(i).Formula
  53. End If
  54. Next i
  55. '还原完成,如果公式是手动计算则应用公式自动计算
  56. Application.Calculation = xlCalculationAutomatic
  57. End If
  58. '如果没有被锁定的单元格值被修改了,则注入撤消功能
  59. End If
  60. '单元格的值没有被修改,保存本次选中的单元格到iRng中
  61. saveIRng Target, valueChangeFlag
  62. 'Application.ScreenUpdating = True
  63. 'Application.Calculation = xlCalculationAutomatic
  64. End Sub
  65. Private Sub saveIRng(ByVal Target As Range, valueChangeFlag As Boolean)
  66. Dim rngOne
  67. Dim tgRow As Long
  68. Dim tgColumn As Long
  69. Dim useRngRow As Long
  70. Dim useRngColumn As Long
  71. Dim i As Long
  72. Dim k As Long
  73. k = 0
  74. i = 1
  75. tgRow = Target.Row + Target.Rows.Count '选中区域的最高行
  76. useRngRow = UsedRange.Row + UsedRange.Rows.Count '选中区域的最大列
  77. tgColumn = Target.Column + Target.Columns.Count '已使用区域的最高行
  78. useRngColumn = UsedRange.Column + UsedRange.Columns.Count ''已使用区域的最大列
  79. If tgRow > useRngRow Or tgColumn > useRngColumn Then
  80. Application.StatusBar = "超出已使用区域, 超出的单元格保护不会生效"
  81. Set Target = Range(Cells(Target.Row, Target.Column), Cells(useRngRow, useRngColumn))
  82. End If
  83. ReDim iRng(Target.Count)
  84. iRng(0).Address = Target.Address
  85. If Target.Count > 65535 Then Exit Sub
  86. For Each rngOne In Target
  87. iRng(i).Address = rngOne.Address
  88. iRng(i).Locked = CBool(Cells(rngOne.Row, 26))
  89. If iRng(i).Locked Then
  90. k = k + 1
  91. End If
  92. iRng(i).Formula = rngOne.Formula
  93. i = i + 1
  94. Next rngOne
  95. iRngFull = True
  96. Application.StatusBar = k / Target.Columns.Count & "行被锁定"
  97. End Sub

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/170424
推荐阅读
相关标签
  

闽ICP备14008679号