使用 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(" & rng.Address & "),)")
您介意解释一下评估如何迭代或扩展多单元格范围吗?我想这将是“评估”内部工作的一部分。无论如何,您的答案是一个完全的救生员(即插即用)。您可以用活动选择替换范围并变成一个按钮。【参考方案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 个)的更快方法的主要内容,如果未能解决你的问题,请参考以下文章