简体   繁体   English

Excel UDF用于捕获字符内的数字

[英]Excel UDF for capturing numbers within characters

I have a variable text field sitting in cell A1 which contains the following: 我在单元格A1中有一个可变文本字段,其中包含以下内容:

Text;#Number;#Text;#Number 文字; #Number; #Text; #Number

  • This format can keep repeating, but the pattern is always Text;#Number. 该格式可以重复,但是模式始终为Text; #Number。
  • The numbers can vary from 1 digit to n digits (limit 7) 数字范围从1位数到n位数(上限7)

Example: 例:

Original Value 原始值

MyName;#123;#YourName;#3456;#HisName;#78

Required value: 要求值:

123, 3456, 78

The field is too variable for excel formulas from my understanding. 根据我的理解,该字段对于excel公式而言太可变了。

I tried using but I am a beginner when it comes to coding. 我尝试使用但是在编码方面我还是一个初学者。 if you can break down the code with some explanation text, it would be much appreciated. 如果您可以使用一些解释性文字来分解代码,将不胜感激。

I have tried some of the suggestions below and they work perfectly. 我尝试了下面的一些建议,它们运行良好。 One more question. 还有一个问题。

Now that I can split the numbers from the text, is there any way to utilize the code below and add another layer, where we split the numbers into x cells. 现在,我可以从文本中拆分数字了,有什么方法可以利用下面的代码并添加另一层,我们将这些数字拆分为x个单元格。

For example: once we run the function, if we get 1234, 567 in the same cell, the function would put 1234 in cell B2, and 567 in cell C2. 例如:一旦运行该函数,如果在同一单元格中获得1234、567,则该函数会将1234放入单元格B2,将567放入单元格C2。 This would keep updating all cells in the same row until the string has exhausted all of the numbers that are retrieved from the function. 这将继续更新同一行中的所有单元格,直到字符串用尽了从该函数检索到的所有数字为止。

Thanks 谢谢

This is the John Coleman's suggested method: 这是John Coleman建议的方法:

Public Function GetTheNumbers(st As String) As String
    ary = Split(st, ";#")
    GetTheNumbers = ""

    For Each a In ary
        If IsNumeric(a) Then
            If GetTheNumbers = "" Then
                GetTheNumbers = a
            Else
                GetTheNumbers = GetTheNumbers & ", " & a
            End If
        End If
    Next a
End Function

If the pattern is fixed, and the location of the numbers never changes, you can assume the numbers will be located in the even places in the string. 如果模式是固定的,并且数字的位置永远不变,则可以假定数字将位于字符串的偶数位置。 This means that in the array result of a split on the source string, you can use the odd indexes of the resulting array. 这意味着在源字符串拆分的数组结果中,可以使用结果数组的奇数索引。 For example in this string "Text;# Number ;#Text;# Number " array indexes 1, 3 would be the numbers ("Text(0);# Number(1) ;#Text(2);# Number(3) "). 例如,在此字符串“文本;# 数量 ; #Text;# 号码 ”数组索引1,3将是数字(“文本(0);# 号(1); #Text(2);# 号(3) ”)。 I think this method is easier and safer to use if the pattern is indeed fixed, as it avoids the need to verify data types. 我认为,如果模式确实是固定的,则此方法更容易使用,也更安全,因为它避免了验证数据类型的需要。

Public Function GetNums(src As String) As String
    Dim arr
    Dim i As Integer
    Dim result As String
    arr = Split(src, ";#") ' Split the string to an array.
    result = ""
    For i = 1 To UBound(arr) Step 2 ' Loop through the array, starting with the second item, and skipping one item (using Step 2).
        result = result & arr(i) & ", "
    Next
    If Len(result) > 2 Then
        GetNums = Left(result, Len(result) - 2) ' Remove the extra ", " at the end of the the result string.
    Else
        GetNums = ""
    End If
End Function

The numbers can vary from 1 digit to n digits ( limit 7 ) 数字可以从1位数到n位数不等( 限制为7

None of the other responses seems to take the provided parameters into consideration so I kludged together a true solution. 其他响应似乎都没有考虑到提供的参数,因此我将一个真正的解决方案合并在一起。

Option Explicit
Option Base 0    '<~~this is the default but I've included it because it has to be 0

Function numsOnly(str As String, _
                  Optional delim As String = ", ")
    Dim n As Long, nums() As Variant
    Static rgx As Object, cmat As Object

    'with rgx as static, it only has to be created once; beneficial when filling a long column with this UDF
    If rgx Is Nothing Then
        Set rgx = CreateObject("VBScript.RegExp")
    End If
    numsOnly = vbNullString

    With rgx
        .Global = True
        .MultiLine = False
        .Pattern = "[0-9]{1,7}"
        If .Test(str) Then
            Set cmat = .Execute(str)
            'resize the nums array to accept the matches
            ReDim nums(cmat.Count - 1)
            'populate the nums array with the matches
            For n = LBound(nums) To UBound(nums)
                nums(n) = cmat.Item(n)
            Next n
            'convert the nums array to a delimited string
            numsOnly = Join(nums, delim)
        End If
    End With
End Function

仅nums

Regexp option that uses Replace 使用Replace表达式选项

Sub Test()
Debug.Print StrOut("MyName;#123;#YourName;#3456;#HisName;#78")
End Sub

function 功能

Option Explicit
Function StrOut(strIn As String) As String
Dim objRegex As Object
Set objRegex = CreateObject("vbscript.regexp")
With objRegex
    .Pattern = "(^|.+?)(\d{1,7})"
    .Global = True
    If .Test(strIn) Then
        StrOut = .Replace(strIn, "$2, ")
        StrOut = Left$(StrOut, Len(StrOut) - 2)
    Else
        StrOut = "Nothing"
    End If
End With
End Function

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM