【问题标题】:Need suggestions on how to speed up this bit of code [duplicate]需要有关如何加快这段代码的建议[重复]
【发布时间】:2015-02-02 07:35:28
【问题描述】:

我有一个电子表格,可以从 3 种不同类型的文件中导入大量数据。它对其进行格式化,以便所有三个的输出都相同,在一种情况下,它需要根据该行的单元格中的内容删除行。问题在于,与格式化其他文件(没有梯级删除的文件)所需的几秒钟相比,这大约需要 1.5 到 2 分钟。工作表从大约 4000 行开始,删除了大约 1600 行。我目前的做法很好,一切正常,但有没有一种运行速度更快的方法?

rw = 1
Lastrow = 2600
NewRow = 0

NxtChk2:
    If (Worksheets("ARCSRT.CND").Cells(rw, "c") >= "0") And (Worksheets("ARCSRT.CND").Cells(rw, "d") = "") Then
        Worksheets("ARCSRT.CND").Rows(rw).EntireRow.Delete
        rw = rw - 1
    End If
    If (Worksheets("ARCSRT.CND").Cells(rw, "b") = "0.0") And (Worksheets("ARCSRT.CND").Cells(rw, "c") = "") Then
        Worksheets("ARCSRT.CND").Rows(rw).EntireRow.Delete
        rw = rw - 1
    End If
    If rw = Lastrow Then GoTo LATER
    rw = rw + 1
GoTo NxtChk2

【问题讨论】:

  • 首先,关闭屏幕更新,将计算设置为手动,并禁用事件。如果这还不够快,请尝试使用数组和集合在 VBA 中完成所有工作,以避免对工作表进行多次读/写。请参阅 Chip Pearson 的网站,了解如何一步读取数组并将其写入范围。
  • 一切都已关闭,这就是其他两种文件类型运行速度足够快的原因。我还没有尝试过阵列,将查看 Chips 网站。谢谢。
  • 大卫,我看不出您的链接或下面的答案与我的问题有什么关系。我在问如何加快 Excel 中梯级的删除,而不是替换 Word 中的单词。除非我遗漏了什么,否则我不知道你们两个在说什么。
  • 特别注意Sids method:将所有要删除的行收集到一个范围内,一次性删除。

标签: excel vba


【解决方案1】:

如果列表的排序是一个选项,而不是逐行删除,只需用“标志”标记它们,即在单独的列中使用字母“X”,一旦循环完成,让您的代码对数据进行排序该列并一次删除整批标记的行,它将执行一次删除操作,而不是 1600 次。

【讨论】:

  • 很有意思,我还是要逐行使用代码来判断该行是否需要删除并标记。这比直接删除行更快吗? (在单元格中放置 X 是否比删除行更快处理?)我无法在删除行后不按相同顺序放回数据的情况下对数据进行排序,因为我需要维护其他两个文件的格式。我的另一个想法是如何一次删除 1600 个不相邻的行?感谢您的意见!
  • 英里更快。它类似于删除数百行过滤掉某些条件之间的比较,这是不连续的,与删除同一行但首先按过滤条件排序的比较。附言我试图尝试建立一个需要删除的所有行的联合,但它不会包含那么多要删除的行,粗略计算,它会达到 100 个顶部。 P.P.S 反过来做循环怎么样:从下往上删除行也更快?
  • 实际上尝试以下操作,dim rng as Rangeset rng = nothing,然后尝试以下操作而不是行删除:If rng = Nothing Then rng = Cells(rw, "A") Else rng = Union(rng, Cells(rw, "A")) End If ,然后在整个循环运行后执行此操作:rng.EntireRow.Delete 请注意我是不确定它如何在 1600 个非连续范围上工作,所以在备份文件上做 PS嗯,我真的应该弄清楚如何用换行符以更好的方式做 cmets,将在一秒钟内将代码发布在单独的答案中
【解决方案2】:

根据我的评论,尝试以下操作
这要在循环之前进行:
Dim rng As Range

Set rng = Nothing

在循环而不是行删除中这样做:

If rng = Nothing Then
rng = Cells(rw, "A")
Else
rng = Union(rng, Cells(rw, "A"))
End If

然后在循环结束后:

rng.EntireRow.Delete

请记住,我不确定它将如何在 1600 个非连续行上运行,在备份副本上运行

【讨论】:

  • 我最终使用了您的答案和 Chris Neilsen 提供的答案的变体。您在标记线然后将其添加到范围中是正确的,然后一次性删除整个范围会更快。我知道根据我现有的标准标记我的行,然后使用 Siddharth Rout 的答案中的代码来设置和删除范围。我运行宏的周期时间已降至约 1 分钟。感谢您的帮助。
猜你喜欢
  • 2017-06-18
  • 1970-01-01
  • 2015-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
  • 2023-04-04
相关资源
最近更新 更多