VBA代码运行缓慢求助:基于AT列值锁定单元格的事件代码优化
VBA代码提速方案:行级锁定优化
原代码核心卡顿原因
- 循环1999次期间反复执行工作表保护/取消保护,每次操作都会触发工作表重绘,这是最耗时的环节
- 错误地锁定/解锁整个
AM2:AS2000区域,而非目标行的对应列,做了大量无用功 SelectionChange事件每次点击单元格就触发全量遍历,完全没必要- 代码逻辑混乱,末尾重复取消保护导致前面的操作无效
优化后的代码
Private Sub Worksheet_SelectionChange(ByVal Target As Range) Dim ws As Worksheet Dim rngAT As Range, cell As Range Dim targetRow As Long Set ws = ThisWorkbook.Worksheets("XXX") Set rngAT = ws.Range("AT2:AT2000") ' 仅处理AT列所在行的单元格点击,减少无意义触发 If Intersect(Target, rngAT.EntireRow) Is Nothing Then Exit Sub ' 一次性取消保护,避免循环内反复操作 ws.Unprotect "123" ' 先统一解锁所有目标区域,再按需锁定 ws.Range("AM2:AS2000").Locked = False For Each cell In rngAT targetRow = cell.Row ' 用Select Case简化多条件判断,执行效率更高 Select Case CStr(cell.Value) Case "Accepted", "Rejected", "Not Processed" ' 精准锁定当前行的AM到AS列 ws.Range(ws.Cells(targetRow, "AM"), ws.Cells(targetRow, "AS")).Locked = True End Select Next cell ' 一次性设置保护,开启UserInterfaceOnly避免代码操作时反复解锁 ws.Protect Password:="123", UserInterfaceOnly:=True ws.EnableSelection = xlUnlockedCells End Sub
关键优化点
- 削减保护操作次数:仅在循环前后各执行一次保护/取消保护,直接消除1999次重复的重绘开销
- 精准操作目标行:不再锁定整个区域,只对符合条件的行锁定对应列,减少无效操作
- 简化条件判断:用
Select Case替代多个Or,代码更简洁且执行效率更高 - 过滤事件触发:判断点击区域是否在AT列的行范围内,不符合则直接退出,避免无意义遍历
- 统一初始化解锁:先解锁所有目标区域,再按需锁定,逻辑更清晰,省去重复判断锁定状态的步骤
额外提速建议
- 将事件从
SelectionChange改为Worksheet_Change,仅在AT列单元格值变化时触发,而非每次点击都执行 - 代码开头添加
Application.ScreenUpdating = False,结尾添加Application.ScreenUpdating = True,避免循环中频繁刷新屏幕
内容的提问来源于stack exchange,提问作者nlhy16
相关产品推荐
相关产品推荐

