VBA - Trim 功能:减少操作/冻结时间

VBA - Trim function : reduce time of operation / freezing

我在 VBA 中编写了代码,删除了字符之间的一些潜在空格。该代码运行良好,但当文件包含数千行时变得非常慢。我想知道是否可以改进它,以减少操作时间,但也主要是防止文件冻结。这是代码:

Sub Test()
  Dim cell as Range
  Dim sht As Worksheet
  Dim LastRow As Long
  Dim StartCell As Range
  Dim areaToTrim As Range
  Set sht = ThisWorkbook.Worksheets("SS upload")
  Set StartCell = sht.Range("A14")
  LastRow = sht.Cells(sht.Rows.Count, StartCell.Column).End(xlUp).Row
  Set areaToTrim = sht.Range("B14:B" & LastRow)
  For Each cell In areaToTrim
    cell.Value = Trim(cell.Value)
  Next cell
End Sub

像这样尝试,以减少屏幕更新。这是一段代码,我一直在使用,因此一些命令对于当前问题来说可能有点太多,但它们仍然有用。

作为第二点 - 不要声明名称为 Cell 的变量,稍后您可能会因此而受苦。声明它 rngCellmyCell 或任何其他不属于 VBE 变量的内容。

Public Sub TestMe()

    Call OnStart
    'YourCode
    Call OnEnd

End Sub    

Public Sub OnEnd()

    Application.ScreenUpdating = True
    Application.EnableEvents = True
    Application.AskToUpdateLinks = True
    Application.DisplayAlerts = True
    Application.Calculation = xlAutomatic
    ThisWorkbook.Date1904 = False

    Application.StatusBar = False

End Sub

Public Sub OnStart()

    Application.ScreenUpdating = False
    Application.EnableEvents = False
    Application.AskToUpdateLinks = False
    Application.DisplayAlerts = False
    Application.Calculation = xlAutomatic
    ThisWorkbook.Date1904 = False

    ActiveWindow.View = xlNormalView

End Sub

如果您愿意,可以将范围保存为数组并在那里进行trim 操作。但是,如果您不习惯使用数组,它可能会使您的代码过于复杂 - Trim Cells using VBA in Excel

在循环中插入 DoEvents 可以防止冻结。 然后执行它,每百次说一次。 这将使循环 运行 变慢一点,但允许用户同时使用 GUI。

...
Dim cnt As Integer
For Each cell In areaToTrim
    cell.Value = Trim(cell.Value)

    cnt=cnt + 1
    If cnt Mod 100 = 0 Then
        DoEvents
    End If
Next cell
...

您可以根据自己的需要对数字进行优化。

DoEvents 也带来了一些问题。关于 DoEvents 的一个很好的解释可以在 here.

找到

最快的方法是将范围读入一个数组,trim它在那里然后写回范围:

Sub Test()

  Dim sht As Worksheet
  Dim LastRow As Long
  Dim StartCell As Range
  Dim areaToTrim As Range
  Dim varArray() As Variant
  Dim i As Long

  Set sht = ThisWorkbook.Worksheets("SS upload")
  Set StartCell = sht.Range("A14")
  LastRow = sht.Cells(sht.Rows.Count, StartCell.Column).End(xlUp).Row
  Set areaToTrim = sht.Range("B14:B" & LastRow)
  varArray = areaToTrim ' Read range into array
  For i = LBound(varArray, 1) To UBound(varArray, 1)
    varArray(i, 1) = Trim(varArray(i, 1))
  Next i
  areaToTrim.Value = varArray ' Write array back to range

End Sub

无需担心 Application.ScreenUpdatingApplication.Calculation。漂亮又简单!

如果您仍然担心任何响应,请在循环体中放置一个 DoEvents