首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在q列有空单元格时加速删除行的vba代码

如何在q列有空单元格时加速删除行的vba代码
EN

Stack Overflow用户
提问于 2022-06-14 16:16:55
回答 3查看 285关注 0票数 1

我有一个将近100000行的工作表&A列到Q列,我有一个代码,如果Q列有空单元格,就删除整行。

我已经在4,000行上尝试了这段代码,它在3分钟内运行,但是当我使用100000行时,它只处理了几个小时。

如果有人帮助/指导我加速这段代码的话,我会非常充实的。

守则是:

代码语言:javascript
运行
复制
Sub DeleteBlank()
    
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual 
    
    Dim lo As ListObject
    set lo = sheets("BOM 6061").ListObjects(1)
    Sheets("BOM 6061").Activate
    
    lo.AutoFilter.ShowAllData
    lo.range.AutoFilter Field:=17, Criteria1:=""
    
    Application.DisplayAlerts = False
    Application.Calculation = xlCalculationAutomatic
    
    lo.DataBodyRange.SpecialCells(xlCellsTypeVisible).Delete
    
    Application.DisplayAlerts = True
    lo.AutoFilter.ShowAllData
End Sub
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2022-06-15 08:41:22

有效删除Excel表中的条件行

简而言之,如果不对“条件”列进行排序,删除行可能需要“永远”。下面的

  • 将这样做,保留其余行的初始顺序。

代码语言:javascript
运行
复制
Option Explicit

Sub DeleteBlankRows()
    
    Const wsName As String = "BOM 6061"
    Const tblIndex As Variant = 1
    Const CriteriaColumnNumber As Long = 17
    Const Criteria As String = ""
    
    ' Reference the table.
    Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
    Dim ws As Worksheet: Set ws = wb.Worksheets(wsName)
    Dim tbl As ListObject: Set tbl = ws.ListObjects(tblIndex)
    
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
    
    ' Remove any filters.
    If tbl.ShowAutoFilter Then
        If tbl.AutoFilter.FilterMode Then tbl.AutoFilter.ShowAllData
    Else
        tbl.ShowAutoFilter = True
    End If
    
    ' Add a helper column and write an ascending integer sequence to it.
    Dim lc As ListColumn: Set lc = tbl.ListColumns.Add
    lc.DataBodyRange.Value = _
        ws.Evaluate("ROW(1:" & lc.DataBodyRange.Rows.Count & ")")
    
    ' Sort the criteria column ascending.
    With tbl.Sort
        .SortFields.Clear
        .SortFields.Add2 tbl.ListColumns(CriteriaColumnNumber).Range, _
            Order:=xlAscending
        .Header = xlYes
        .Apply
    End With

    ' AutoFilter.
    tbl.Range.AutoFilter Field:=CriteriaColumnNumber, Criteria1:=Criteria
    
    ' Reference the filtered (visible) range.
    Dim svrg As Range
    On Error Resume Next
        Set svrg = tbl.DataBodyRange.SpecialCells(xlCellTypeVisible)
    On Error GoTo 0
    
    ' Remove the filter.
    tbl.AutoFilter.ShowAllData
  
    ' Delete the referenced filtered (visible) range.
    If Not svrg Is Nothing Then svrg.Delete
    
    ' Sort the helper column ascending.
    With tbl.Sort
        .SortFields.Clear
        .SortFields.Add2 lc.Range, Order:=xlAscending
        .Header = xlYes
        .Apply
        .SortFields.Clear
    End With
    
    ' Delete the helper column.
    lc.Delete
    
    Application.Calculation = xlCalculationAutomatic
    Application.ScreenUpdating = True
    
    ' Inform.
    MsgBox "Blanks deleted.", vbInformation
    
End Sub
票数 1
EN

Stack Overflow用户

发布于 2022-06-14 16:36:42

我有一个很简单的例子。高级过滤是在excel/vba中过滤或复制的最快方法。在高级筛选中,通常会在列/行中列出过滤器,并且可以根据需要使用>"“来筛选列上的空白,应该不会占用任何时间。在我的示例中,它可能是不同的,因为如果在过滤器中添加了任何内容,则可以将它与一起使用。

代码语言:javascript
运行
复制
Sub Advanced_Filtering_ModV2()

Dim rc As Long, crc As Long, trc As Long
Dim wb As Workbook, ws As Worksheet
Set wb = ActiveWorkbook: Set ws = wb.Worksheets("sheet1")

ws.Range("AA1").Value = ws.Range("Q1").Value: ws.Range("AA2").Value = ">"""""

On Error Resume Next
ws.ShowAllData: rc = ws.Range("A" & Rows.Count).End(xlUp).Row

ws.Range("A1:V" & rc).AdvancedFilter Action:=xlFilterInPlace, CriteriaRange:=ws.Range("AA1:AA2")
On Error GoTo 0

End Sub
票数 0
EN

Stack Overflow用户

发布于 2022-06-14 20:49:45

我不会在大型数据集上使用自动筛选器,因为在实际筛选数据之前,它们可能需要相当长的时间来枚举可用的选项。AutoFilter.ShowAllData所花费的时间也一样多。对于我的超级简单测试数据集(由26列1000000行组成),每一列的处理时间都是30+秒。

据我所知,您正在筛选列表,只显示空项,然后删除空白行。由于过滤是导致延迟的原因,我们可以循环遍历每一行,查看特定的列,如果是空白的,您只需删除它。下面是如何做到这一点的一个例子。

**编辑:经过测试,我发现这比你想要的要慢得多。看看下面的下一个例子,因为它非常快。

代码语言:javascript
运行
复制
Option Explicit

Sub DeleteBlank()

    Application.ScreenUpdating = False

    Dim calcType As Integer
    Dim rowCount, columnNumToCheck, currow, dataStartRow As Long
    Dim WkSht As String
    Dim lo As ListObject

    WkSht = "BOM 6061" 'The name of the worksheet where the table is located.
    columnNumToCheck = 17 'The column number to check for blank cells.

    calcType = Application.Calculation
    Application.Calculation = xlCalculationManual
    Set lo = Sheets(WkSht).ListObjects(1)
    rowCount = lo.ListRows.Count
    dataStartRow = (lo.DataBodyRange.Row - 1)

    For currow = rowCount To 1 Step -1
        If Sheets(WkSht).Cells((currow + dataStartRow), columnNumToCheck).Value = "" Then
            Call DeleteRows(WkSht, (currow + dataStartRow))
        End If
    Next currow

    Application.Calculation = calcType
    Application.ScreenUpdating = True

End Sub

Private Sub DeleteRows(sheetNameIn As String, startRow As Long, Optional optionalEndRow As Long)

    If IsNull(optionalEndRow) Or optionalEndRow = 0 Then
        optionalEndRow = startRow
    End If

    Worksheets(sheetNameIn).Range(startRow & ":" & optionalEndRow).Delete Shift:=xlUp

End Sub

如果您能够将空白单元格放在一起的数据排序,您可以使用下面的命令执行单个删除功能,同时将它们全部删除。这将在几秒钟内删除70000行。

代码语言:javascript
运行
复制
Sub DeleteBlankWithSort()

    'Application.ScreenUpdating = False

    Dim columnNumToCheck, tableLastRow, lrow As Long
    Dim calcType As Integer
    Dim WkSht As String
    Dim lo As ListObject

    WkSht = "BOM 6061" 'The name of the worksheet where the table is located.
    columnNumToCheck = 17 'The column number to check for blank cells.

    calcType = Application.Calculation
    Application.Calculation = xlCalculationManual
    Set lo = Sheets(WkSht).ListObjects(1)
                  
    tableLastRow = FindLastRow(WkSht, (columnNumToCheck))
    
    With lo.Sort
        .SortFields.Clear
        .SortFields.Add _
            Key:=Range("Table1[[#All],[q]]"), _
            SortOn:=xlSortOnValues, _
            Order:=xlDescending, _
            DataOption:=xlSortNormal
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
    
    lrow = FindLastRow(WkSht, (columnNumToCheck), (tableLastRow))
    Call DeleteRows(WkSht, (tableLastRow), (lrow + 1))

    Application.Calculation = calcType
    Application.ScreenUpdating = True

End Sub

Private Sub DeleteRows(sheetNameIn As String, startRow As Long, Optional optionalEndRow As Long)

    If IsNull(optionalEndRow) Or optionalEndRow = 0 Then
        optionalEndRow = startRow
    End If

    Worksheets(sheetNameIn).Range(startRow & ":" & optionalEndRow).Delete Shift:=xlUp

End Sub

Private Function FindLastRow(sheetNameIn As String, columnNum As Long, Optional optionalStartRow As Long) As Long
'finds the last row of the column passed in the sheetname passed in
    
    If IsNull(optionalStartRow) Or optionalStartRow = 0 Then
        optionalStartRow = 1048576
    End If
    
    FindLastRow = Worksheets(sheetNameIn).Range(Cells(optionalStartRow, columnNum).Address).End(xlUp).Row
    
End Function
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72620271

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档