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
的变量,稍后您可能会因此而受苦。声明它 rngCell
或 myCell
或任何其他不属于 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.ScreenUpdating
或 Application.Calculation
。漂亮又简单!
如果您仍然担心任何响应,请在循环体中放置一个 DoEvents
。
我在 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
的变量,稍后您可能会因此而受苦。声明它 rngCell
或 myCell
或任何其他不属于 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.ScreenUpdating
或 Application.Calculation
。漂亮又简单!
如果您仍然担心任何响应,请在循环体中放置一个 DoEvents
。