Получение отдельных чисел из строки

Я хочу извлечь отдельные числа из строки. Таким образом, для:

x = "    99                1.2           99.25       "

Я хочу получить три отдельных номера: 99, 1.2, а также 99.25,

Вот мой текущий код. Он извлекает первое встречающееся число, но я не знаю, как использовать циклы для получения трех отдельных чисел.

Sub ExtractNumber()
Dim rng As Range
Dim TestChar As String
Dim IsNumber As Boolean
Dim i, StartChar, LastChar, NumChars As Integer
For Each rng In Selection
    IsNumber = False
    i = 1
    Do While IsNumber = False And i <= Len(rng)
        TestChar = Mid(rng, i, 1)
        If IsNumeric(TestChar) = True Then
            StartChar = i
            IsNumber = True
        End If
        i = i + 1
    Loop
    IsNumber = False
    Do While IsNumber = False And i <= Len(rng)
        TestChar = Mid(rng, i, 1)
        If IsNumeric(TestChar) = False Or i = Len(rng) Then
            If i = Len(rng) Then
                LastChar = i
            Else
                LastChar = i - 1
            End If
            IsNumber = True
        End If
        i = i + 1
    Loop
    NumChars = LastChar - StartChar + 1
    rng.Offset(0, 1).Value = Mid(rng, StartChar, NumChars)
    Next rng
End Sub

Моя предыдущая попытка (вход хранится в ячейке A6):

Dim x, y, z As String

x = Range("A6")
y = Len(x)

For i = 1 To Len(x)
    If IsNumeric(Mid(x, i, 1)) Then
        z = z & Mid(x, i, 1)
    End If
Next i

MsgBox z

2 ответа

Если скорость не является проблемой (если задача не интенсивна и т. Д.), Вы можете использовать это

Public Sub splitme()

Dim a As Variant
Dim x As String
Dim i, j As Integer

Dim b() As Double

x = "1.2 9.0  0.8"
a = Split(x, " ")

j = 0
ReDim b(100)

For i = 0 To UBound(a)
If (a(i) <> "") Then
    b(j) = CDbl(a(i))
    j = j + 1
End If

Next i


ReDim Preserve b(j - 1)
End Sub

Проверка ошибок должна быть включена для b(100), чтобы удовлетворить ваши конкретные потребности - и с CDbl,

Если это будет использоваться как часть цикла, или для большого x - или оба, рассмотрите другие варианты, такие как RegEx (предыдущий ответ) - как повторные вызовы ReDim Preserve как правило, лучше избегать.

Вместо того, чтобы писать собственный код для извлечения чисел, почему бы не попробовать использовать регулярные выражения? Этот сайт имеет много полезной информации и учебных пособий по регулярным выражениям. Сначала это может быть немного непонятно, но как только вы освоитесь, это очень мощный инструмент для решения проблем такого типа.

Ниже приведен пример извлечения информации, которую вы используете после использования объекта регулярного выражения.

Public Sub ExtractNumbers()
    'Regular Expression Objects
    Dim objRegEx As Object
    Dim objMatches As Object
    Dim Match As Object

    'String variable for source string
    Dim strSource As String

    'Iteration variable
    Dim i As Integer

    'Create Regular Expression Object
    Set objRegEx = CreateObject("VBScript.RegExp")

    'Set objRegEx properties
    objRegEx.Global = True '<~~ We want to find all matches
    objRegEx.MultiLine = True '<~~ Allow line breaks in source string
    objRegEx.IgnoreCase = False '<~~ Not strictly necessary for this example

    'Below pattern matches an integer or decimal number 'word' within a string
    '   \b matches the start of the word
    '   [+-]? optionally matches a + or - symbol
    '   [0-9]+ matches one or more digits in sequence
    '   (\.[0-9]+)? optionally matches a period/decimal point followed by one or more digits
    '   \b matches the end of the word
    objRegEx.Pattern = "\b[+-]?[0-9]+(\.[0-9]+)?\b"

    'Example String
    strSource = "x=  99     10.1    20.6  Aardvark"

    'Ensure that at least one match exists
    If objRegEx.Test(strSource) Then

        'Capture all matches in objMatches
        Set objMatches = objRegEx.Execute(strSource)

        'TODO: Do what you want to do with them
        'In this example I'm just printing them to the Immediate Window

        'Print using Match object and For..Each
        For Each Match In objMatches
            Debug.Print Match.Value
        Next Match

        'Print using numeric iteration (objMatches.Items is a 0-based collection)
        For i = 0 To (objMatches.Count - 1)
            Debug.Print objMatches.Item(i)
        Next i

    End If
End Sub

Оба варианта печати, показанные в этом примере, будут выводить следующий вывод в окно Immediate

99
10.1
20.6
Другие вопросы по тегам