【问题标题】:Delete Row Loop Optimization VBA删除行循环优化 VBA
【发布时间】:2013-03-19 04:29:08
【问题描述】:

下面的代码是作为随机样本生成器的一部分编写的。根据发生的总数,它计算样本量并将总体减少到样本量。现在我通过删除总数和样本量之间的差异来做到这一点。我想看看是否有更好的方法来解决这个问题。我在用户定义的列中获取每个值的样本并使用大型数据集,因此采样最终需要几分钟。

有没有办法一次删除我需要的行数,而不是像下面的循环中看到的那样一次删除一个,或者有更好的方法来解决这个问题?谢谢!

x = (Population - SampleSize)

    If Population > SampleSize Then
        Do Until x = 0
            Workbooks(SourceBook).Sheets(SampleSheet).Columns(StratCol) _
            .Find(What:=SubPop, After:=Cells(SampRows, StratCol), LookIn:=xlValues, _
                SearchOrder:=xlByRows, SearchDirection:=xlNext, _
                MatchCase:=False, SearchFormat:=False).EntireRow.Delete

        x = x - 1

        Loop

    End If

【问题讨论】:

  • 是的,但只能通过添加公式列,如How to delete multiple rows without a loop in Excel VBA - 请参阅我的答案以获取可能的解决方案
  • @ForrestA 请参考类似的帖子。 stackoverflow.com/questions/15375054/…
  • 是的,AUtoFilter/Advanced Filter 是另一个选项没有循环,其中不需要使用 SpecialCells
  • 澄清一下,我主要是为了更快地达到预期的结果。这是否是一个循环对我来说并不重要,尽管我确实欣赏解决这个问题的方法的多样性。另外,请记住,这是删除具有匹配条件的行的特定部分,而不是全部。非常感谢您的建议!当我有机会试一试时,我会告诉你哪一个最适合我。
  • @ForrestA 任何反馈>

标签: vba loops optimization excel


【解决方案1】:

您可以构建一个包含多个不连续行的范围,然后一次删除所有这些行。这可能会加快速度。

x = (Population - SampleSize)

dim MyRange as Range

If Population > SampleSize Then
    Do Until x = 0
        if MyRange Is Nothing Then
            Set MyRange = Workbooks(SourceBook).Sheets(SampleSheet).Columns(StratCol) _
                .Find(What:=SubPop, After:=Cells(SampRows, StratCol), LookIn:=xlValues, _
                SearchOrder:=xlByRows, SearchDirection:=xlNext, _
                MatchCase:=False, SearchFormat:=False).EntireRow
        Else
            Set MyRange = Application.Union(MyRange, Workbooks(SourceBook).Sheets(SampleSheet).Columns(StratCol) _
                .Find(What:=SubPop, After:=Cells(SampRows, StratCol), LookIn:=xlValues, _
                SearchOrder:=xlByRows, SearchDirection:=xlNext, _
                MatchCase:=False, SearchFormat:=False).EntireRow)
        End If
        x = x - 1
    Loop
    MyRange.Delete
End If

【讨论】:

    【解决方案2】:

    对于此解决方案,可以避免循环。

    只需添加一个额外的列,即可使用 SpecialCells 找到错误,如下所示:

    Range("IA1:IA" & Range("A65536").End(xlUp).Row).Formula = "=IF(A:A = """ & SubPop & """,NA(),"""") "
    

    然后你使用 SpecialCells 来识别匹配 SupPop 的行,并删除整行!

    Range("IA1:IA" & Range("A65536").end(xlup).row).specialcells(xlCellTypeFormulas, xlErrors).EntireRow.Delete shift:=xlup
    

    最后,清理/删除我们在开头添加的额外公式列:

    Range("IA1:IA" & Range("A65536").end(xlup).row).clear
    

    以下是对该技术的正确解释:How to delete multiple rows without a loop in Excel VBA

    我希望这有助于你开始

    这是上面的代码,急切要求:

    Sub deleteRows(ByVal strSubPop As String)
    ' pass in the string to match (SubPop)
    '
        Range("IA1:IA" & Range("A65536").End(xlUp).Row).Formula = "=IF(A:A = """ & strSubPop & """,NA(),"""") "
    '    
        ' for debugging and testing just select the rows where a match is found
        Range("IA1:IA" & Range("A65536").End(xlUp).Row).SpecialCells(xlCellTypeFormulas, xlErrors).EntireRow.Select
     '   
        ' when ready, UNCOMMENT the below line
       ' Selection.Delete shift:=xlUp
      '  
        ' after testing just use this line to select the rows and delete in one step:
        ' Range("IA1:IA" & Range("A65536").End(xlUp).Row).SpecialCells(xlCellTypeFormulas, xlErrors).EntireRow.Delete shift:=xlUp
       '  
        ' now clean up Column IA
        Range("IA1:IA" & Range("A65536").End(xlUp).Row).Clear
        Range("A1").Select
    '
    End Sub
    

    那段代码在做什么?

    首先您的要求是删除匹配 SubPop

    的行
    1. 第一行在 IA 列中添加了一个与找到的 SubPop 匹配的公式 在 A 列中
    2. 下一行查找所有这些行,然后将其删除
    3. 最后一行清理

    菲利普

    【讨论】:

    • 我猜大多数人都知道 SpecialCells。请根据值使用它并告诉我它是否有效。热切期待您的回复。
    • 上面的代码使用了值SubPop。如果在 A 列中找到,则公式在 IA 列的单元格中返回 NA# 错误代码。 SpecialCells 在 IA 列中搜索错误 (NA#),然后 range 命令返回采用 Delete 方法的整行!
    • @user2063626 抱歉,向 IA 列添加公式的行中存在错误,现已修复!
    • @ForrestA 虽然我会以错误的方式完成上述任务。
    • @user2063626 OP 要求解决方案避免循环。这不是一种解决方法,而是一种可能的解决方案。
    【解决方案3】:

    对于这种情况,循环是无法避免的。 试试下面的代码。

     Dim rng As Range
        x = (Population - SampleSize)
    
        If Population > SampleSize Then
            Do Until x = 0
    
                With Workbooks(SourceBook).Sheets(SampleSheet)
                    Set rng = .Columns(StratCol).Find(What:=SubPop, After:=Cells(SampRows, StratCol))
                    If Not rng Is Nothing Then
                        rng.EntireRow.Delete
                    End If
                End With
    
                x = x - 1
            Loop
        End If
    

    【讨论】:

    • 循环可以避免,看我的回答
    猜你喜欢
    • 2016-10-25
    • 2018-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-03
    • 2015-08-06
    • 1970-01-01
    相关资源
    最近更新 更多