【问题标题】:Extract 2 numbers from text (bulk list)从文本中提取 2 个数字(批量列表)
【发布时间】:2022-01-03 08:38:37
【问题描述】:

背景信息:

我列出了 5000 多条这种格式的错误消息:

“999999 16 901 F SMITH, Smith FT 1 1.0 额外休假时间 -4.0000 超出应享权利,按比例 -4.0000”

我已经能够使用宏对它们进行分类,例如“额外休假时间超过权利加按比例”。

我试图从那里提取这两个数字。

我可以使用这些公式手动完成:

=MID(J3,SEARCH("hours ",J3)+5,SEARCH("exceed",J3)-SEARCH("hours ",J3)-6)
   
=TRIM(RIGHT(SUBSTITUTE(J3," ",REPT(" ",LEN(J3))),LEN((J3))))

但这就是我被卡住的地方,将这个逻辑合并到宏中并让它遍历整个列表。

这是我的第一次尝试:

If InStr(myString, "Additional Leave hours ") > 0 And InStr(myString, "exceed entitlement plus pro-rata") Then

'set category
Cells(x, 6).Value = "Additional Leave hours exceed entitlement plus pro-rata"

'first number
Cells(x, 8).ForumlaR1C1 = "=MID(RC[2],SEARCH(""hours "",RC[2])+5,SEARCH(""exceed"",RC[2])-SEARCH(""hours "",RC[2])-6"

'second number
Cells(x, 9).FormulaR1C1 = "=TRIM(RIGHT(SUBSTITUTE(RC[2],"" "",REPT("" "",LEN(RC[2]))),LEN((RC[2]))))"

'first minus second
Cells(x, 7).FormulaR1C1 = "=SUM(RC[2]-RC[1]"
    
End If

从那里我已经能够使用 .Select 和 .Active 单元格,它可以工作但效率不高:

'first number
Cells(x, 8).Select
        
ActiveCell.FormulaR1C1 = "=MID(RC[2],SEARCH(""hours"",RC[2])+5,SEARCH(""exceed"",RC[2])SEARCH(""hours "",RC[2])-6)"

任何帮助将不胜感激,在此先感谢。

【问题讨论】:

  • 你在宏里试过什么?
  • 我尝试过使用 .FormulaR1C1,但这给了我在引号处的预期语句结束错误。让我抓一张我第一次尝试的截图
  • 刚刚将我最初的尝试添加到主帖中,我猜我需要学习使用不同的功能,但我只是不知道我在寻找什么
  • 您是否必须在电子表格中包含公式,或者您可以添加所需的输出 - 即 VBA 正在寻找答案,您只需将该值放入单元格中?
  • 很高兴阅读仅返回值的选项,这些公式是我知道如何提取它们的唯一方法。谢谢 - 格伦

标签: excel vba text numbers extract


【解决方案1】:

想法是处理数组中的所有字符串(这样更快,与逐个写入/读取单元格相比),使用 RegExp 将 2 个数字提取到一个数组中,该数组将用于粘贴到前 2 个列。最后将 SUM 公式插入到之前的列中:

Sub Test()
    Const inputStartRow As Long = 1
    Const inputCol As String = "J"
    Const regexPattern As String = "Additional Leave hours ([-\d.]{1,}) exceed entitlement plus pro-rata ([-\d.]{1,})"
    
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Worksheets("Sheet1") 'Change name accordingly
    
    Dim regex As Object
    Set regex = CreateObject("VBScript.RegExp")
    With regex
        .Pattern = regexPattern
        .Global = False
    End With
    
    '==== Get last row of the input column and set to range
    Dim inputLastRow As Long
    inputLastRow = ws.Cells(ws.Rows.Count, inputCol).End(xlUp).Row
        
    Dim inputRng As Range
    Set inputRng = ws.Range(ws.Cells(inputStartRow, inputCol), ws.Cells(inputLastRow, inputCol))
    
    '==== Populate the array with the input range's value
    Dim inputArr As Variant
    inputArr = inputRng.Value
        
    Dim outputArr() As String
    ReDim outputArr(1 To UBound(inputArr, 1), 1 To 2) As String
    
    '==== Loop through the array and extract the 2 numbers
    Dim i As Long
    For i = 1 To UBound(inputArr, 1)
        If InStr(inputArr(i, 1), "Additional Leave hours ") > 0 And InStr(inputArr(i, 1), "exceed entitlement plus pro-rata") Then
            If regex.Test(inputArr(i, 1)) Then
                Dim regexMatch As Object
                Set regexMatch = regex.Execute(inputArr(i, 1))(0)
                                
                outputArr(i, 1) = regexMatch.SubMatches(0)
                outputArr(i, 2) = regexMatch.SubMatches(1)
            End If
        End If
    Next i
    
    '==== Insert the extraction @ Input column - 1/ -2
    Dim outputRng As Range
    Set outputRng = inputRng.Offset(, -2).Resize(, 2)
    outputRng.Value = outputArr
    
    Set outputRng = Nothing
    
    '==== Add in SUM formula @ Input Column - 3
    Dim sumRng As Range
    Set sumRng = inputRng.Offset(, -3)
    sumRng.Formula = "=SUM(" & ws.Cells(inputStartRow, sumRng.Column + 1).Address(RowAbsolute:=False) & "-" & ws.Cells(inputStartRow, sumRng.Column + 2).Address(RowAbsolute:=False) & ")"
    
    Set sumRng = Nothing
End Sub

【讨论】:

  • 感谢 Raymond 的回复,我明天试试。然后将其分解并尝试了解 RegExp。
  • 谢谢雷蒙德,效果很好。能够将其更改为我也有其他一些错误消息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多