gpt4 book ai didi

vba - 基于列表在VBA中删除行

转载 作者:行者123 更新时间:2023-12-02 19:13:57 24 4
gpt4 key购买 nike

我的电子表格中有两个选项卡(报告和假期)。在“假期”选项卡的 A 列中,有一个日期列表(手动更新),我想将其从“报告”选项卡中排除(E 列包含日期)。

我找到了一个代码,它可以完成所需的操作,但当行数约为 100-200k 时需要一些时间:

Sub Holidays()
Application.DisplayAlerts = False
Dim d As Object, e, rws&, cls&, i&, j&
Set d = CreateObject("scripting.dictionary")
For Each e In Sheets("Holidays").Range("A1").CurrentRegion
d(e.Value) = 1
Next e
Sheets("Report").Activate
rws = Cells.Find("*", After:=[a1], SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious).Row
cls = Cells.Find("*", After:=[a1], SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious).Column
For i = rws To 1 Step -1
For j = 1 To cls
If d(Range("A1").Resize(rws, cls)(i, j).Value) = 1 Then _
Cells.Rows(i).Delete: Exit For
Next j, i
Application.DisplayAlerts = True
End Sub

有没有办法加快该宏的速度?理想情况下,运行仅需​​几秒钟。

预先感谢您的帮助。

最佳答案

这应该会在 30 秒内从 200 K 行中删除大约 10 K 行

下面的代码假设两张纸上的 UsedRange 都从 A1 开始,并且

  • 工作表 Holidays 仅包含列 A(在连续行中)
  • 工作表报告包含要在E列(在连续行中)中删除的日期
  • 两张表上的日期格式均为“m/d/yyyy”
<小时/>
Option Explicit

Public Sub RemoveHolidaysFromReportFilterUnion()
Const WS_NAME = "Report"
Dim wsH As Worksheet: Set wsH = ThisWorkbook.Worksheets("Holidays")
Dim wsR As Worksheet: Set wsR = ThisWorkbook.Worksheets(WS_NAME)

Dim del As Range, wsNew As Worksheet

Application.ScreenUpdating = False
Set del = GetRowsToDelete(wsH, wsR)
If del.Cells.Count > 1 Then
del.EntireRow.Hidden = True
Set wsNew = ThisWorkbook.Worksheets.Add(After:=wsR)
wsR.UsedRange.SpecialCells(xlCellTypeVisible).EntireRow.Copy
With wsNew.Cells(1)
.PasteSpecial xlPasteColumnWidths
.PasteSpecial xlPasteAll
.Select
End With
Application.DisplayAlerts = False
wsR.Delete
Application.DisplayAlerts = True
wsNew.Name = WS_NAME
End If
Application.ScreenUpdating = True
End Sub
<小时/>
Private Function GetRowsToDelete(ByRef wsH As Worksheet, ByRef wsR As Worksheet) As Range
Const HOLIDAYS_COL = "A"
Const REPORT_COL = "E"
Dim arr As Variant, i As Long, itm As Variant

ReDim arr(1 To wsH.UsedRange.Rows.Count - 1)
i = 1
For Each itm In wsH.UsedRange.Columns(HOLIDAYS_COL).Offset(1).Cells
If Len(itm) > 0 Then
arr(i) = itm.Text 'Create AutoFilter Array (dates as strings)
i = i + 1
End If
Next

Dim ur As Range, del As Range, lr As Long, fc As Range

With wsR.UsedRange
Set ur = .Resize(.Rows.Count - 1, 1).Offset(1)
Set del = wsR.Cells(.Rows.Count + 1, REPORT_COL)
End With

lr = wsR.UsedRange.Rows.Count
Set fc = wsR.Range(wsR.Cells(1, REPORT_COL), wsR.Cells(lr, REPORT_COL))
fc.AutoFilter Field:=1, Criteria1:=arr, Operator:=xlFilterValues
If fc.SpecialCells(xlCellTypeVisible).Cells.Count > 1 Then
Set del = Union(del, ur.SpecialCells(xlCellTypeVisible))
End If
fc.AutoFilter
Set GetRowsToDelete = del
End Function
<小时/>

性能 - 从总共 100K 行中删除了大约 5K 行

Sheet Report   - Rows: 100,011, Cols: 11   (Rows Left: 94,805 - Deleted: 5,206)
Sheet Holidays - Rows: 20, Cols: 1

Initial Sub - Holidays() - Time: 112.625 sec
RemoveHolidaysFromReportFilterUnion() - Time: 10.512 sec
<小时/>

测试数据

假期

Holidays

<小时/>

报告 - 之前

ReportBefore

报告 - 之后

ReportAfter

关于vba - 基于列表在VBA中删除行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50489113/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com