将存储为文本的数字转换为包含每个语句的数字

时间:2017-03-22 15:55:44

标签: excel vba excel-vba

我试图将存储在文本中的数字转换为多个工作表上的数字。我的问题是,我拼凑在一起的代码似乎花费了过多的时间。我使用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语句。我认为我用来转换值的方法只是比必要的时间更长,因此在多张纸上运行它更糟糕。

我愿意接受任何和所有建议,以使这一过程更快地运行。提前谢谢!

3 个答案:

答案 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