从具有不同字符长度的单元格中提取数字

时间:2015-02-15 06:51:54

标签: excel excel-vba excel-formula excel-2010 vba

我有一组单元格,第一个字符串永远不会更改,它始终会(直到编码器更改它)20个字符(包含空格)。

然后我想从剩余的序列中提取3个数字(在某些情况下为2)。

The monthly cost is 2 silver, 1 copper and 40 iron.
The monthly cost is 1 silver, 94 copper and 40 iron.
The monthly cost is 1 silver and 75 copper.
The monthly cost is 8 silver and 40 copper.
The monthly cost is 1 silver.
The monthly cost is 99 silver, 99 copper and 99 iron.
The monthly cost is 1 gold.

在上面的示例中,您可以看到前20个字符后没有设定值。

1 or 99 silver 
1 or 99 copper
0, 1 or 99 iron  

我无法得到一个能让所有细胞都正确的序列,我尝试了以下内容:

=IF(J7<>1,(MID(TRIM(J7),FIND(" iron",TRIM(J7))-2,FIND(" iron",TRIM(J7))-FIND(" iron",TRIM(J7))+3)),"")    
results in:  #VALUE!  (when no iron)  

=TRIM(MID(J6,FIND(" silver",J6)-2,LEN(J6)-FIND(" silver",J6)-26))&TRIM(MID(J6,FIND(" copper",J6)-2,LEN(J6)-FIND(" copper",J6)-16))&TRIM(MID(J6,FIND(" iron",J6)-2,LEN(J6)-FIND(" iron",J6)-3))  
results in:  1 s9440   

=MID(J7,31,2-ISERR(MID(J7,21,1)+0))  
results in:  nd

如果我&将单元格作为计算的一部分,那么他们就不会在下一个数学步骤中计算,因为我必须在我的代码中允许spaces,在这种情况下可能有2位数字,而不是单数。

=MID(J5,SEARCH(" silver",J5,1)-2,2)&MID(J5,SEARCH(" copper",J5,1)-2,2)&MID(J5,SEARCH(" iron",J5,1)-2,2)  
results:   2 140
not:       2140

我最终需要的是:

2140  
19440  
175  
840  
1  
999999   

非常感谢提前。

4 个答案:

答案 0 :(得分:5)

这个公式适用于我的数据,假设单元格A1中的文本字符串

=IFERROR(MID(A1,SEARCH("silver",A1)-3,2)+0,"")&IFERROR(MID(A1,SEARCH("copper",A1)-3,2)+0,"")&IFERROR(MID(A1,SEARCH("iron",A1)-3,2)+0,"")

我认为你不想要&#34; Gold&#34;的价值?

答案 1 :(得分:2)

当谈到字符串中的模式匹配时,RegEx常常是要走的路。

在Excel中,这需要一个VBA解决方案,使用对“Microsoft VBScript Regular Expresions 5.5”的引用(如果您愿意,可以进入后期绑定)

这是一个针对您的案例的启动器,作为UDF

假设第一个原始数据位于=GetValues(A1),则将其用作A1之类的公式。根据需要向下复制多行

这将从字符串中提取最多3个值。

Function GetValues(r As Range) As Variant
    Dim re As RegExp
    Dim m As MatchCollection
    Dim v As Variant
    Dim i As Long
    Set re = New RegExp

    re.Pattern = "(\d+)\D+(\d+)\D+(\d+)"
    If re.test(r.Value) Then
        Set m = re.Execute(r.Value)
    Else
        re.Pattern = "(\d+)\D+(\d+)"
        If re.test(r.Value) Then
            Set m = re.Execute(r.Value)
        Else
            re.Pattern = "(\d+)"
            If re.test(r.Value) Then
                Set m = re.Execute(r.Value)
            End If
        End If
    End If
    If m Is Nothing Then
        GetValues = vbNullString
    Else
        For i = 0 To m.Item(0).SubMatches.Count - 1
            v = v & m.Item(0).SubMatches(i)
        Next
        GetValues = v
    End If
End Function

答案 2 :(得分:2)

由于你只是剥离数字,如果你想要VBA路线,你可以使用短的一次性RegExp

Function GetDigits(strIn As String) As String
Dim objRegex As Object
Set objRegex = CreateObject("vbscript.regexp")
With objRegex
    .Pattern = "[^\d]+"
    .Global = True
    GetDigits = .Replace(strIn, vbNullString)
End With
End Function

答案 3 :(得分:1)

这是另一种使用工作表公式的方法,用于返回字符串中的所有数字。很多年前,哈伦格罗夫就把它推到了那里。

首先定义一个名称(带有工作簿范围):

SEQ 指:= ROW(INDEX($ 1:$ 65536,1,1):INDEX($ 1:$ 65536,255,1))

然后,假设您的字符串在A1中,请使用以下数组输入公式。 (按 ctrl + shift 输入公式,同时按 Enter 。(如果执行此操作,Excel将在公式周围放置大括号{...}

=SUM(IF(ISNUMBER(1/(MID(A1,Seq,1)+1)),MID(A1,Seq,1)*10^MMULT(-(Seq<TRANSPOSE(Seq)),-ISNUMBER(1/(MID(A1,Seq,1)+1)))))