【问题标题】:Replace empty by 0用 0 替换空
【发布时间】:2018-07-12 10:23:14
【问题描述】:

我想检查 D 到 O 列中的所有单元格。如果单元格为空,请将其替换为硬零。

我有这个代码:

Sub replace()
Dim rng As Range, cell As Range
Dim aantalrijen As Long

    With Worksheets("Schaduwblad")
        aantalrijen = .Range("A1", .Range("A1").End(xlDown)).Cells.Count - 1
        Set rng = .Range(.Cells(2, "D"), .Cells(aantalrijen, "O"))

        For Each cell In rng
            cell = WorksheetFunction.Substitute(cell, "", "0")
        Next
    End With
End Sub

此代码在处理过程中挂起。唯一的选择是按 Escape 键结束例程。

【问题讨论】:

  • 你不能使用查找和替换来完全避免循环吗?
  • 否,因为数据在隐藏的工作表上,并且每 4 周返回一次。

标签: excel vba substitution


【解决方案1】:

您不需要遍历所有单元格。让 Excel 用 .SpecialCells 查找空:

On Error Resume Next
rng.SpecialCells(xlCellTypeBlanks, xlCellTypeConstants).Value = 0
On Error GoTo 0

如果没有找到空单元格,则需要错误陷阱。


所以你的整个例程可以替换为:

Sub replace()

    On Error Resume Next

      With Worksheets("Schaduwblad")
            .Range(.Cells(2, "D"), .Cells(.Cells(.Rows.Count, 1).End(xlUp).Row, "O")) _
                .SpecialCells(xlCellTypeBlanks, xlCellTypeConstants).Value = 0
      End With

    On Error GoTo 0

End Sub

除了您在下面的评论之外,这里是相同代码的一个版本,但是是逐行工作的。为了测试这一点,我构建了一个 227,000 x 15 的数据块,然后使用随机数生成器在其中打了 100,000 个孔,清空这些单元格。然后我运行了下面的代码,用了 33 秒来填满这 100,000 个洞。

Sub replace()

Dim rangesection As Range

    On Error Resume Next

      With Worksheets("Schaduwblad")
        For Each rangesection In .Range(.Cells(2, "D"), .Cells(.Cells(.Rows.Count, 1).End(xlUp).Row, "O")).Rows
            rangesection.SpecialCells(xlCellTypeBlanks, xlCellTypeConstants).Value = 0
        Next
      End With

    On Error GoTo 0

End Sub

【讨论】:

  • 对于我的大多数模板,代码都能完美运行。但是,我现在遇到了另一个问题,在该例程完成之前需要花费大量时间。我想知道为什么。问题模板总共有 227850 行,而工作正常的模板有 87360 行。所以问题模板有大约 3 倍的行要检查,但我需要更多的时间来运行(我已经等待了至少 15 分钟,然后我取消了执行)
  • 我刚刚在一个 227,000 x 15 的单元格表上使用了上面的代码,其中大部分是空白的,不到 2 秒就将它们全部更改为 0
  • 如果您选择的答案更快,请告诉我,因为我想了解如何。
  • 延迟的原因是空单元格范围的构建。使这更快的唯一方法是了解空单元格的性质。他们是否可能单独存在,或者他们更有可能与其他空白坐在同一行或同一列中。他们是在大的连续街区中,还是在周围散布的单身人士中。基于它们是单打点(最坏的情况)和一个大约 10-15 个单元格宽的表格的假设,我建议一次在表格中运行宏 down 一行。我会补充我的答案。
  • 确实如此,但认为它可能与单元格的格式有关。单元格是空的,但我看到有格式。虽然我不知道确切的原因,但它产生了很大的不同。
【解决方案2】:

我从未使用过替代方法。我会通过使用IsEmpty() 函数检查单元格是否为空来做到这一点。

所以你可以交换

cell = WorksheetFunction.Substitute(cell, "", "0")

If IsEmpty(cell) Then cell.value = 0

完整代码:

Sub replace()
Dim rng As Range, cell As Range
Dim aantalrijen As Long

  With Application.ThisWorkbook.Worksheets("Schaduwblad")
        aantalrijen = .Range("A1", .Range("A1").End(xlDown)).Cells.Count - 1
        Set rng = .Range(.Cells(2, "D"), .Cells(aantalrijen, "O"))


    For Each cell In rng
        If IsEmpty(cell) Then cell.value = 0
    Next
  End With
End Sub

【讨论】:

  • 您的代码帮助我在很短的时间内将最大的数据文件的空单元格传输了 0。
  • @DutchArjo 很高兴我能帮上忙,如果您在开头没有Application.ScreenUpdating = False,然后在结尾没有Application.ScreenUpdating = True,您也许可以更快地运行它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-24
  • 2021-10-29
  • 1970-01-01
  • 1970-01-01
  • 2021-11-28
  • 1970-01-01
相关资源
最近更新 更多