【问题标题】:Extract numbers from cells of varying lengths/formats从不同长度/格式的单元格中提取数字
【发布时间】:2018-09-16 16:46:24
【问题描述】:

我正在寻找从 A 列中提取数字的公式。我遇到的问题是长度和格式不同。我正在根据下面的期望结果列寻求解决方案。

B 列中的公式:

=IFERROR(INT(LEFT(REPLACE(SUBSTITUTE(A4,"-"," "),1,MIN(FIND({0,1,2,3,4,5,6,7,8,9},A4&1/17))-1,""),5)),INT(LEFT(REPLACE(SUBSTITUTE(A4,"-"," "),1,MIN(FIND({0,1,2,3,4,5,6,7,8,9},A4&1/17))-1,""),4)))

工作簿:

谢谢!

【问题讨论】:

  • 你怎么知道想要的结果是什么,它总是单元格中的最后一个数字吗?
  • 是的,但是单元格的格式和字符不同,因此很难生成左右函数。
  • 哦,是的,这是可行的。逻辑是从右边读取并找到第一个数字字符(获取该字符的索引),然后继续直到找到下一个 NOT 数字(获取该字符的索引),然后提取带有MID 函数的这些索引之间的文本。使用单个单元格公式很繁琐,但可以做到。我建议将中间计算步骤吐出到其他单元格中,然后再研究如何组合成单个单元格公式。

标签: excel excel-formula formula min


【解决方案1】:

试试下面的用户定义函数:

Public Function LastNumber(s As String) As Variant
    Dim L As Long, i As Long, temp As String, arr
    Dim CH As String

    L = Len(s)
    temp = ""
    For i = 1 To L
        CH = Mid(s, i, 1)
        If CH Like "[0-9]" Then
            temp = temp & CH
        Else
            temp = temp & " "
        End If
    Next i

    arr = Split(Application.WorksheetFunction.Trim(temp), " ")
    For i = UBound(arr) To LBound(arr) Step -1
        If IsNumeric(arr(i)) Then
            LastNumber = CLng(arr(i))
            Exit Function
        End If
    Next i
    LastNumber = ""

End Function

它将返回字符串中的最后一个数字(一组数字)

用户定义函数 (UDF) 非常易于安装和使用:

  1. ALT-F11 调出 VBE 窗口
  2. ALT-I ALT-M 打开一个新模块
  3. 粘贴内容并关闭 VBE 窗口

如果您保存工作簿,UDF 将与它一起保存。 如果您使用的是 2003 年以后的 Excel 版本,则必须保存 文件为 .xlsm 而不是 .xlsx

要删除 UDF:

  1. 如上所示打开 VBE 窗口
  2. 清除代码
  3. 关闭 VBE 窗口

要使用 Excel 中的 UDF:

=myfunction(A1)

要了解有关宏的更多信息,请参阅:

http://www.mvps.org/dmcritchie/excel/getstarted.htm

http://msdn.microsoft.com/en-us/library/ee814735(v=office.14).aspx

有关 UDF 的详细信息,请参阅:

http://www.cpearson.com/excel/WritingFunctionsInVBA.aspx

必须启用宏才能正常工作!

【讨论】:

  • 很棒的解决方案 - 我注意到的唯一问题是最后一个数字(在极少数情况下)是否有前导零(例如,Z.ACE.3700.0111.USA 将返回 111)。可能是一个罕见的情况,但我不确定他在上面试图解析什么。
  • @dwirony 如果海报需要数字作为字符串(保留前导零),这是一个简单的更改。
【解决方案2】:

在标准的公共模块代码表中尝试这个用户定义的函数。

function lastNumber(str as string)
    dim i as long, tmp as string

    tmp = str

    for i=len(tmp) to 1 step-1
        if asc(right(tmp, 1))<48 or asc(right(tmp, 1))>57 then
            tmp = left(tmp, len(tmp)-1)
        else
            exit for
        end if
    next i

    for i=len(tmp) to 1 step-1
        if asc(mid(tmp, i))<48 or asc(mid(tmp, i))>57 then
            exit for
        end if
    next i

    lastNumber = mid(tmp, i+1)
end function

【讨论】:

  • 我正在努力以某种方式破解这段代码,但我不能>:[干得好
【解决方案3】:

您可以使用 Regex,它需要参考 Microsoft VBScript 正则表达式:

Public Function GetLastNum(str As String) As String
    Dim numRegEx As RegExp
    Set numRegEx = New RegExp

    Dim matchColl As MatchCollection
    Dim retStr As String
    With numRegEx
        .Global = True
        .Pattern = "[0-9]+"
        Set matchColl = .Execute(str)
        If matchColl.Count > 0 Then
            GetLastNum = matchColl.Item(matchColl.Count - 1)
            Exit Function
        End If
    End With
End Function

【讨论】:

    猜你喜欢
    • 2020-10-11
    • 2017-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-14
    • 1970-01-01
    • 2012-10-29
    • 1970-01-01
    相关资源
    最近更新 更多