学习Excel技术,关注微信公众号:
excelperfect
标签:
AI
,
大模型
,
deepseek
,
VBA
今天试试看
deepseek
对
VBA
代码优化能力如何。我使用前面推送的一篇文章(详见:
使用
VBA
快速删除间隔行
)中的示例,我对
deepseek
提问如下:
在
Excel
中,因为行重复或者空行等原因,我需要每间隔一行删除一行。下面是我编写的
VBA
代码:
Sub
DeleteAlternateRowsWithHeader()
Set rng = Application.InputBox("
选择源数据区域
:", Type:=8)
MsgBox "
没有选择任何区域
.", vbExclamation
'
从第
3
行开始每隔一行删除一行
(
标题行位于第一行
)
For i = rng.Rows.Count To 3 Step -1
rng.Rows(i).EntireRow.Delete
deleteCount = deleteCount + 1
keepCount = keepCount + 1
keepCount = keepCount + 2
MsgBox "
删除的行数
: " & deleteCount & vbCrLf & "
保留的行数
: " &
keepCount, vbInformation
deepseek
首先阅读了这段代码,然后给出了自己对这段代码的理解,并分析了代码存在的一些缺陷,例如可能会导致的错误、代码效率不高等,分析了要考虑的各种情形,并给出了优化点。最后,
deepseek
给出了优化后的代码如下:
Sub DeleteAlternateRowsWithHeader()
Dim ws As Worksheet
Dim rng As Range
Dim deleteRng As Range
Dim startRow As Long
Dim i As Long
Dim totalRows As Long
Dim deleteCount As Long
' 设置错误处理
On Error Resume Next
Set rng = Application.InputBox("请选择数据区域(包含标题行):", "区域选择", Type:=8)
On Error GoTo 0
' 检查用户是否取消选择
If rng Is Nothing Then
MsgBox "操作已取消。", vbInformation
Exit Sub
End If
' 初始化参数
Set ws = rng.Parent
startRow = 3 ' 从区域内的第三行开始处理(跳过标题行和第二行)
totalRows = rng.Rows.Count
Application.ScreenUpdating = False
' 从下往上遍历,收集需要删除的行
For i = totalRows To startRow Step -1
If (i - startRow) Mod 2 = 0 Then ' 数学优化:直接计算间隔行
If deleteRng Is Nothing Then
Set deleteRng = rng.Rows(i)
Else
Set deleteRng = Union(deleteRng, rng.Rows(i))
End If
End If
Next i
deleteCount = deleteRng.Rows.Count
' 一次性删除所有目标行
If Not deleteRng Is Nothing Then
deleteRng.EntireRow.Delete
' deleteCount = deleteRng.Rows.Count
End If
' 恢复屏幕更新
Application.ScreenUpdating = True
' 显示统计信息(包含标题行和第二行)
MsgBox "原始总行数: " & totalRows & vbCrLf & _
"删除的行数: " & deleteCount & vbCrLf & _
"保留的行数: " & totalRows - deleteCount, _
vbInformation, "操作完成"
End Sub
但是,还是存在一个瑕疵,我稍微调整了一个,就是将循环中的语句:
deleteCount
= deleteRng.Rows.Count
使用
Union
收集所有待删除行后一次性删除,相比逐行删除效率提升
90%+
禁用屏幕刷新(
Application.ScreenUpdating
= False
)避免闪烁
使用数学公式
(i - startRow)
Mod 2 = 0
精准定位间隔行
直接通过区域操作(
rng.Rows
)确保处理位置准确
删除行数通过
deleteRng.Rows.Count
精确统计
保留行数
=
总行数
-
删除行数(自动包含标题行和第二行)
数据格式:确保没有合并单元格,否则可能影响删除准确性
大型数据集:处理
10
万行数据仅需约
2
秒(原代码需约
20
秒)
还提示:如果需要处理动态区域,可进一步优化为自动检测数据范围。您是否需要这个功能的扩展实现?
以下是针对动态区域处理的增强版
VBA
代码,支持自动识别数据范围并优化删除效率:
Sub DeleteAlternateRowsDynamic()
Dim ws As Worksheet
Dim dataRng As Range
Dim deleteRng As Range
Dim startRow As Long
Dim lastRow As Long
Dim lastCol As Long
Dim totalRows As Long
Dim deleteCount As Long
Dim
i As Long
Set ws = ActiveSheet
Application.ScreenUpdating = False
' 动态查找数据范围
On Error Resume Next
With ws
' 查找最后一个非空单元格
lastRow = .Cells.Find("*", .Cells(.Rows.Count, .Columns.Count), _
SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
lastCol = .Cells.Find("*", .Cells(.Rows.Count, .Columns.Count), _
SearchOrder:=xlByColumns, SearchDirection:=xlPrevious).Column
End With
' 验证数据有效性
If lastRow < 2 Then
MsgBox "未发现有效数据区域", vbExclamation
Exit Sub
End If
Set dataRng = ws.Range(ws.Cells(1, 1), ws.Cells(lastRow, lastCol))
totalRows = dataRng.Rows.Count
startRow = 3 ' 保留标题行(第1行)和第2行
' 集合操作删除行
For i = totalRows To startRow Step -1
If (i - startRow) Mod 2 = 0 Then
If deleteRng Is Nothing Then
Set deleteRng = dataRng.Rows(i)
Else
Set deleteRng = Union(deleteRng, dataRng.Rows(i))
End If
End If
Next i
' 执行批量删除
If Not deleteRng Is Nothing Then
deleteRng.EntireRow.Delete
deleteCount = deleteRng.Rows.Count
End If
Application.ScreenUpdating = True
' 显示智能统计结果
MsgBox "数据区域: " & dataRng.Address & vbCrLf & _
"原始总行数: " & totalRows & vbCrLf & _
"删除行数: " & deleteCount & vbCrLf & _
"保留行数: " & totalRows - deleteCount, _
vbInformation, "动态删除完成"
End Sub
使用
Find
方法精准定位数据边界(支持非连续数据)
自动识别真实数据范围(即使存在空单元格或格式干扰)
lastRow = .Cells.Find("*", , xlFormulas, , xlByRows, xlPrevious).Row
lastCol = .Cells.Find("*", , xlFormulas, , xlByColumns, xlPrevious).Column
集合操作效率比原代码提升约
40%
(通过减少
Union
调用次数)
For i = totalRows To startRow Step -2 ' 直接间隔遍历
If deleteRng Is Nothing Then
Set deleteRng = dataRng.Rows(i)
Else
Set deleteRng = Union(deleteRng, dataRng.Rows(i))
End If
Next i
If dataRng.Rows(i).Hidden = False Then ' 可选:跳过隐藏行
' 删除逻辑
End If
MsgBox "数据区域: " & dataRng.Address & ...
' 可选功能:删除前创建备份
If MsgBox("是否创建数据备份?", vbYesNo) = vbYes Then
ws.Copy After:=Sheets(Sheets.Count)
ActiveSheet.Name = "备份_" & Format(Now, "yyyymmdd_hhmm")
End If
' 可选功能:保留特殊标记行(如黄色填充行)
For i = totalRows To startRow Step -1
If dataRng.Rows(i).Interior.Color <> vbYellow Then
' 正常删除逻辑
End If
Next i
' 可选功能:进度条显示
Application.StatusBar = "正在处理行:" & i & " (" & Format(i/totalRows, "0%") & ")"
但是,运行后发觉,上面代码中的
deleteCount
值不正确,于是接着向
deepseek
提问:
“
上面的代码中,
deleteCount
的值不正确,应该进一步处理
”
deepseek
很快查到了原因并对代码进行了修复:
感谢指出问题!
deleteCount
的值不正确是因为在
Union
操作后,直接使用
deleteRng.Rows.Count
统计行数时可能会忽略某些特殊情况(例如非连续区域)。我们需要在收集删除行时单独统计
deleteCount
的值。
以下是修正后的代码,确保
deleteCount
统计准确:
Sub DeleteAlternateRowsDynamic()
Dim ws As Worksheet
Dim dataRng As Range
Dim deleteRng As Range
Dim startRow As Long
Dim lastRow As Long
Dim lastCol As Long
Dim totalRows As Long
Dim deleteCount As Long
Dim i As Long