我试图将存储在文本中的数字转换为多个工作表上的数字。我的问题是,我拼凑在一起的代码似乎花费了过多的时间。我使用For Each语句循环遍历必要的工作表和范围。它不会使Excel崩溃,它只是看起来永远在运行。
Sub ConvertTextToNumber()
Application.ScreenUpdating = False
Dim WshtNames As Variant
Dim WshtNameCrnt As Variant
Dim r As Range
WshtNames = Array("Financial Data", "Site Data ", "Org Data", "Program Data")
For Each WshtNameCrnt In WshtNames
On Error Resume Next
For Each r In Worksheets(WshtNameCrnt).UsedRange.SpecialCells(xlCellTypeConstants)
If IsNumeric(r) Then r.Value = Val(r.Value)
Next
Next
Application.ScreenUpdating = False
End Sub
当我停止运行脚本并单击Debug时,它似乎陷入了第一个Next语句。我认为我用来转换值的方法只是比必要的时间更长,因此在多张纸上运行它更糟糕。
我愿意接受任何和所有建议,以使这一过程更快地运行。提前谢谢!
答案 0 :(得分:1)
尝试以下代码。我使用索引号而不是尝试使用变量遍历数组。我可能错了,但我认为For Each只适用于收藏品。如果我弄错了,请有人纠正我。 (编辑:我确实错了。因为每个人在这里工作得很好。)
无论如何,数组上的索引号是最佳实践。
我还删除了你的Resume Next并妥善处理它。我强烈建议不要使用Resume Next。我不能想到任何事件,Resume Next不能被良好的逻辑所取代。
Sub ConvertTextToNumber()
Application.ScreenUpdating = False
' These two statements should further improve processing time.
' The first prevents formulas from calculating. The second prevents
' any background events from firing (mostly for Event triggered macros).
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
Dim WshtNames As Variant
Dim i as Long
Dim r As Range
WshtNames = Array("Financial Data", "Site Data ", "Org Data", "Program Data")
' When looping over an array use an index number.
' I this case, 'i' will go from the lowest range of the array
' all the way through to the highest range of the array.
For i = LBound(WshtNames) to Ubound(WshtNames)
'On Error Resume Next ' It is best to catch the errors, dont just skip them.
If Not Worksheets(WshtNames(i)) Is Nothing Then
For Each r In Worksheets(WshtNames(i)).UsedRange.SpecialCells(xlCellTypeConstants)
' No need to check for an empty string here since
' IsNumeric() will return false for non-numbers.
If IsNumeric(r) Then r.Value = Val(r.Value)
Next
Else
' Put your error handling in here, or you can just skip it
' I tend to use debug.print just to keep track.
Debug.Print WshtNames(i) & " doesn't exist."
End If
Next
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
End Sub
答案 1 :(得分:1)
我最初使用Brandon的答案,但根据他的建议,我调查了使用数组来存储值并在内存中进行更改。以下是我现在使用的更新代码:
Sub ConvertTextToNumber()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
Dim WshtNames As Variant
Dim DataRange As Variant
Dim r As Range
Dim i As Long
Dim lrow As Long
Dim lcol As Integer
Dim MyVar
WshtNames = Array("Financial Data", "Site Data ", "Org Data", "Program Data")
DataRange = Range("A1:FZ6000").Formula
For lrow = 1 To 6000
For lcol = 1 To 156
MyVar = DataRange(lrow, lcol)
If IsNumeric(MyVar) Then
MyVar = Val(MyVar)
DataRange(lrow, lcol) = MyVar
End If
Next lcol
Next lrow
Range("A1:FZ6000").Formula = DataRange
Application.ScreenUpdating = False
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
End Sub
这对我有用,因为我知道根据数据的性质,我的表格永远不会超出我选择的范围。这有效地将我的计算时间缩短到约2秒。感谢大家的投入和快乐的编码!
答案 2 :(得分:0)
这是因为你的循环实际上是通过每个单元格。最好对空白值进行一些检查
IF r.Value <> "" or r.value <> vbnullstring then