Vba 使用For Each语句将存储为文本的数字转换为数字
我正在尝试将文本中存储的数字转换为多个工作表上的数字。我的问题是,我拼凑的代码似乎花费了过多的时间。我使用For-Each语句循环遍历必要的工作表和范围。它不会使Excel崩溃,它似乎永远都在运行Vba 使用For Each语句将存储为文本的数字转换为数字,vba,excel,Vba,Excel,我正在尝试将文本中存储的数字转换为多个工作表上的数字。我的问题是,我拼凑的代码似乎花费了过多的时间。我使用For-Each语句循环遍历必要的工作表和范围。它不会使Excel崩溃,它似乎永远都在运行 Sub ConvertTextToNumber() Application.ScreenUpdating = False Dim WshtNames As Variant Dim WshtNameCrnt As Variant Dim r As Range W
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时,它似乎在第一个下一个语句中被捕获。我认为我用来转换值的方法比必要的更耗时,因此在多个工作表上运行它更糟糕
我愿意接受任何和所有的建议,让这个过程运行得更快。提前谢谢 这是因为你的循环实际上是通过每个细胞的。最好检查一下空白值
IF r.Value <> "" or r.value <> vbnullstring then
如果r.Value“”或r.Value vbnullstring,则
这是因为你的循环实际上是通过每一个细胞。最好检查一下空白值
IF r.Value <> "" or r.value <> vbnullstring then
如果r.Value“”或r.Value vbnullstring,则
尝试下面的代码。我使用了一个索引号,而不是尝试使用变量在数组中循环。我可能错了,但我认为每一个都只适用于收藏。如果我错了,请有人纠正我。(编辑:我真的弄错了。在这里,每个作品都很好。)
在任何情况下,数组上的索引号都是最佳做法
我还删除了你的简历,并妥善处理了它。我强烈建议下一步不要使用简历。我想不出下一步的任何事件都不能被良好的逻辑所取代
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
请尝试下面的代码。我使用了一个索引号,而不是尝试使用变量在数组中循环。我可能错了,但我认为每一个都只适用于收藏。如果我错了,请有人纠正我。(编辑:我真的弄错了。在这里,每个作品都很好。) 在任何情况下,数组上的索引号都是最佳做法 我还删除了你的简历,并妥善处理了它。我强烈建议下一步不要使用简历。我想不出下一步的任何事件都不能被良好的逻辑所取代
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
我最初使用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秒。感谢大家的投入和愉快的编码 我最初使用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秒。感谢大家的投入和愉快的编码 “”和vbNullstring是相同的,因此最好使用“If r.Value vbNullstring then”。@BrandonBarney实际上不是。空值和空白是两件不同的事情,处理方式也不同。对于excel尤其如此。空白和“”是两种不同的东西。vbNullString是“”的常量表达式。您甚至可以使用即时窗口检查两者之间是否相等(Debug.Print”“=vbNullString返回True)。现在,空白字符是一个完全不同的故事,处理方式当然也不同,但“”不是空白。你可能对此感兴趣:。@BrandonBarney man,我正要发布一张照片来证明我的观点,你不得不走更高的路来破坏我的时刻。:)在这里,我实际上一直在阅读这篇文章,因为我一直在测试这两个提议的解决方案。“'”和“vbNullString”之间的区别当然很有趣。然而,对于我的困境来说,这个解决方案似乎和我的解决方案完全一样,实际上不需要花费更少的时间。我想我可能不得不跳过这个改变。谢谢你的努力!“”和vbNullstring是相同的,因此最好使用“If r.Value vbNullstring then”。@BrandonBarney实际上不是。空值和空白是两件不同的事情,处理方式也不同。对于excel尤其如此。空白和“”是两种不同的东西。vbNullString是“”的常量表达式。您甚至可以使用即时窗口检查两者之间是否相等(Debug.Print”“=vbNullString返回True)。现在,空白字符是一个完全不同的故事,处理方式当然也不同,但“”不是空白。你可能对此感兴趣:。@BrandonBarney man,我正要发布一张照片来证明我的观点,你不得不走更高的路来破坏我的时刻。:)在这里,我实际上一直在阅读这篇文章,因为我一直在测试这两个提议的解决方案。“'”和“vbNullString”之间的区别当然很有趣。然而,对于我的困境来说,这个解决方案似乎和我的解决方案完全一样,实际上不需要花费更少的时间。我想我可能不得不跳过这个改变。谢谢你的努力!查找最后使用的行和列,将所有内容加载到数组中,进行更改,然后将值放回。它会加快速度。因为它是你在每个细胞中循环测试和改变它。这将需要很长时间。阵列将以指数级的速度加速。这肯定会有助于我的想象。因为我知道我的数据不会超过某一点,所以我的更新对我来说是有效的。但是,如果我有时间,我将更新代码,只需找到最后一行和最后一列,并将其发布在这里。谢谢请不要把它放在问题里,而是把新的代码作为答案,因为它是这样的。对此感到抱歉!我是个新手,还没有机会提供自己的答案。谢谢你的提醒!看我