使用 VBA for Excel 从大量单元格中删除“额外”空格(超过 1 个)的更快方法

Posted

技术标签:

【中文标题】使用 VBA for Excel 从大量单元格中删除“额外”空格(超过 1 个)的更快方法【英文标题】:Faster way to remove 'extra' spaces (more than 1) from a large range of cells using VBA for Excel 【发布时间】:2015-08-26 09:32:55 【问题描述】:

如何更快地从包含文本字符串的大量单元格中删除多余的空格?

假设有 5000 多个细胞。

我尝试过的一些方法包括:

For Each c In range
    c.Value = Trim(c.Value)
Next c

For Each c In range
    c = WorksheetFunction.Trim(c)
Next c

For Each c In range
    c.Value = Replace(c.Value, "     ", " ")
Next c

有什么提高速度的想法吗?

【问题讨论】:

你必须使用VBA吗?您可以通过使用 .Net、Python、Perl 等在外部对电子表格进行操作来提高性能。 为什么不在电子表格上直接使用修剪功能呢?应该明显更快。 【参考方案1】:

聚会迟到了,但是……

不需要遍历单元格/值,也不需要递归函数来搜索和替换范围内的多个空格。

Application.Trim 实际上会处理单词之间的多个空格(并且会修剪前导/尾随空格),而单词之间的单个空格会保持不变。

它的好处在于,您可以为函数提供一个完整的范围(或数组),以便一次扫描完成此操作!


Sub Test()

Dim rng As Range
Set rng = Sheets("Sheet1").Range("A1:A3")
rng.Value = Application.Trim(rng)

End Sub


要考虑的一件事是,这样您将用其值覆盖目标范围内的任何公式。但根据您的问题,您使用的是包含文本值的 Range 对象。只是不需要迭代 =)

【讨论】:

从 VBA Trim() 函数中,我永远不会猜到 Application.Trim 函数会以不同的方式工作。谢谢你:) :+) 展示了一种几乎被忽视的方式@JvdV ++ 是的,同意@T.M 我很少看到有人使用它。 :) 我可能遇到了这种方法的错误。在我的一个工作表中,我使用 Ctrl + 单击选择了多个单元格。 Excel 清除了所有内容并返回了#VALUE!现在所有数据都消失了:( @HuyTruong。您可能回复了错误的主题。【参考方案2】:

循环正在杀死你。这将一次性删除整列中的空格:

Sub SpaceKiller()
   Worksheets("Sheet1").Columns("A").Replace _
      What:=" ", _
      Replacement:="", _
      SearchOrder:=xlByColumns, _
      MatchCase:=True
End Sub

调整范围以适应。如果要删除 个空格,则:

Sub SpaceKiller()
   Worksheets("Sheet1").Columns("A").Replace _
      What:="  ", _
      Replacement:=" ", _
      SearchOrder:=xlByColumns, _
      MatchCase:=True
End Sub

编辑#1:

这个版本会用单打代替双打,然后检查是否还有双打!

Sub SpaceKiller3()
   Worksheets("Sheet1").Columns("A").Replace _
      What:="  ", _
      Replacement:=" ", _
      SearchOrder:=xlByColumns, _
      MatchCase:=True

   Set r = Worksheets("Sheet1").Columns("A").Find(What:="  ")
   If r Is Nothing Then
      MsgBox "done"
   Else
      MsgBox "please run again"
   End If
End Sub

您可以重新运行直到看到完成

编辑#2:

根据 Don Donoghue 的评论,此版本将递归地运行,直到所有双精度都转换为单精度:

Sub SpaceKiller3()
   Worksheets("Sheet1").Columns("A").Replace _
      What:="  ", _
      Replacement:=" ", _
      SearchOrder:=xlByColumns, _
      MatchCase:=True

   Set r = Worksheets("Sheet1").Columns("A").Find(What:="  ")
   If r Is Nothing Then
      MsgBox "done"
   Else
      Call SpaceKiller3
   End If
End Sub

【讨论】:

Gary - 这很棒,但我希望有一个可以删除所有额外的空间并将其带到一个空间。 2比1、3比1。就像excel里面的trim函数一样。 非常好!我也可以使用“do while”来自动化吗? 将 MsgBox "please run again" 改为 SpaceKiller3,它会一直运行到没有为止。 @DanDonoghue 你是个天才!我忘了递归地做! 这是一个快速解决方案,我可能会使用 Do 直到 r 与自我引用相比,对于最终解决方案来说什么都不是,这只是个人意见,但我不喜欢自称的潜艇。很棒的代码 BTW Gary 的学生,我没想过使用替换功能:)。另外在旁注中,您不需要“呼叫”,只需子名称就足够了:)。【参考方案3】:

当涉及到大范围时,我通常使用 Evaluate 而不是循环。这个函数有很多用处,这里不再赘述。

'change the row count as deemed necessary..
Set rng = Range("C1:C" & Row.Count)

   rng.value = Evaluate("IF(" & rng.Address & "<>"""", _
               TRIM(" & rng.Address & "),"""")")

Set rng = Nothing

【讨论】:

这应该是最快的,但是 Worksheet.Evaluate 比 Application.Evaluate 快一点rng = rng.Worksheet.Evaluate("index(trim(" &amp; rng.Address &amp; "),)") 您介意解释一下评估如何迭代或扩展多单元格范围吗?我想这将是“评估”内部工作的一部分。无论如何,您的答案是一个完全的救生员(即插即用)。您可以用活动选择替换范围并变成一个按钮。【参考方案4】:

它可能取决于很多东西,但在我的情况下,最快的是一次在数组中获取所有值:

' Dim range As Range, r As Long, c As Long, a
a = range
For r = 1 To UBound(a)
    For c = 1 To UBound(a, 2)
        a(r, c) = Trim(a(r, c))
    Next
Next
range = a

【讨论】:

【参考方案5】:

你旁边有空栏吗?

Range("B1:B" & Range("A" & Rows.Count).End(xlUp).Row).Formula = "=Trim(A1)"
Columns(2).copy
Range("B1").PasteSpecial xlPasteValues
Columns(1).delete

【讨论】:

@dan_Donoghue 这实际上适用于需要删除之后的所有空格以及中间的额外空格。也非常有用。谢谢

以上是关于使用 VBA for Excel 从大量单元格中删除“额外”空格(超过 1 个)的更快方法的主要内容,如果未能解决你的问题,请参考以下文章

在vba excel中保存大量字符串

从excel vba的列中的所有单元格中删除不需要的字符

如何使用 VBA 从单元格中获取一些字符

使用 VBA 在 Excel 单元格中运行 SQL 语句

Excel 2010 VBA:使用单元格中的值保存文件以确定路径和文件名

基于固定宽度的单元格中 MID/拆分文本的 Excel VBA 代码