【问题标题】:Convert 10M rows of Text with letters To Number将 10M 行带有字母的文本转换为数字
【发布时间】:2020-11-13 16:30:23
【问题描述】:

我需要将“文本数字”转换为数字。文本编号如下所示:32,23B 或 242,23M。

我需要删除字母并乘以 1,000 ; 1,000,000;等等,取决于字母。
下面的代码有效,但由于我需要转换 10M 行,所以需要很长时间。

有什么巧妙的办法吗?

For shIndex = startSheet To lastSheet
    LastRowF = Sheets(shIndex).Range("F" & Rows.Count).End(xlUp).Row
        
    For i = 3 To LastRowF
        
        Mul = Right(Sheets(shIndex).Range("F" & i), 1)
            
        Select Case Mul
            Case "K"
                Multiplier = 1
            Case "M"
                Multiplier = 1000
            Case "B"
                Multiplier = 1000000
            Case "T"
                Multiplier = 1000000000
            Case Else
                Multiplier = False
        End Select
            
        If Multiplier Then
            With Sheets(shIndex)
                .Range("F" & i) = CSng(Left(Sheets(shIndex).Range("F" & i), Len(Sheets(shIndex).Range("F" & i)) - 1) * Multiplier)
                .Range("F" & i).NumberFormat = "#,##0"
            End With
        End If
    Next i
Next shIndex

【问题讨论】:

  • 您是否关闭了屏幕更新和计算功能?如果从他的结果输出中计算出任何可能会挂起宏的东西
  • 将数据加载到Variant数组中并在内存中进行转换,然后写回工作表。
  • @BigBen 哦,不,我忘了怎么做。希望看到你解决这个问题,这样我才能记住;)
  • 为什么不直接使用内置的“搜索和替换”功能,我认为这里不需要 VBA

标签: excel vba data-conversion


【解决方案1】:

使用Variant 数组,在内存中进行转换,然后将整个数组写回工作表:

For shIndex = startSheet To lastSheet
    LastRowF = Sheets(shIndex).Range("F" & Rows.Count).End(xlUp).Row

    Dim data() As Variant
    data = Sheets(shIndex).Range("F3:F" & LastRowF).Value

    Dim i As Long
    For i = LBound(data, 1) to UBound(data, 1)
        Mul = Right(data(i, 1), 1)

        Select Case Mul
            Case "K"
                Multiplier = 1
            Case "M"
                Multiplier = 1000
            Case "B"
                Multiplier = 1000000
            Case "T"
                Multiplier = 1000000000
            Case Else
                Multiplier = False
        End Select

        If CBool(Multiplier) Then
            data(i, 1) = Left(data(i,1), Len(data(i, 1)) - 1) * Multiplier
        End 

        With Sheets(shIndex).Range("F3:F" & LastRowF)
           .Value = data
           .NumberFormat = "#,##0"
        End With 
     
    Next
Next

【讨论】:

  • 很遗憾看到自己忘记了 VBA :( - 新工作对它的需求要低得多,现在主要使用 sql。感谢您的复习 :)
  • @urdearboy - 实际上这可能是一个奖励。我不情愿地继续使用 VBA,但它已经过时了。
  • 使用If CBool而不是If Multiplier有什么好处?
  • 真的没有好处。只是更明确。也许我应该把CSng(或CDbl)也放回去。
【解决方案2】:

修改数字格式

  • 实现一个数组可能会解决问题。

守则

Option Explicit

Sub modifyValues()
    
    Const FirstCell As String = "F3"
    Const startSheet As Long = 1
    Const lastSheet As Long = 1
    
    Dim wb As Workbook
    Set wb = ThisWorkbook
    
    Dim ws As Worksheet
    Dim rng As Range
    Dim Data As Variant
    Dim Current As Variant
    Dim Multiplier As Variant
    Dim Mul As String
    Dim shIndex As Long
    Dim LastRow As Long
    Dim i As Long
    
    For shIndex = startSheet To lastSheet
        With wb.Worksheets(shIndex).Range(FirstCell)
            LastRow = .Parent.Cells(.Parent.Rows.Count, .Column).End(xlUp).Row
            Set rng = .Resize(LastRow - .Row + 1)
        End With
        Data = rng.Value
        For i = 1 To UBound(Data, 1)
            Current = Data(i, 1)
            Mul = Right(Current, 1)
            Select Case Mul
                Case "K"
                    Multiplier = 1
                Case "M"
                    Multiplier = 1000
                Case "B"
                    Multiplier = 1000000
                Case "T"
                    Multiplier = 1000000000
                Case Else
                    Multiplier = False
            End Select
            If Multiplier Then
                Data(i, 1) = CSng(Left(Current, Len(Current) - 1) * Multiplier)
            End If
        Next i
        rng.Value = Data
        rng.NumberFormat = "#,##0"
    Next shIndex

End Sub

【讨论】:

  • 非常感谢,这个解决方案比我的好。我已为您的答案投票,但由于我的声誉低下,我无法被视为...
猜你喜欢
  • 1970-01-01
  • 2019-01-24
  • 2022-11-10
  • 2016-07-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多