3

Я создал формулу в Excel VBA. который извлекает строку, содержащую число из ячейки. например, строка содержит: "121A Nariman Street", она извлечет "121A"

Ниже код

Function DoorNo(ADRESS)

Dim AddressArray() As String
AddressArray = Split(ADRESS)
Dim i As Integer
For i = 0 To UBound(AddressArray)
    Dim iCnt As Integer
    For iCnt = 1 To Len(AddressArray(i))
        If IsNumeric(Mid(AddressArray(i), iCnt, 1)) Then
            DoorNo = AddressArray(i)

    Next iCnt
Next i

End Function

но когда в строке два числа, он возвращает второе, например, возвращает «121A Nariman Street, 12th Block», возвращает "12th"

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

Я очень новичок в Excel VBA.

3 ответа3

2

Ваш вопрос касается выбора, когда вы впервые сталкиваетесь с чем-то, где IsNumeric() возвращает true

Эта обновленная версия должна сделать это

Option Explicit
Sub doIt()
    Dim dn As String
    dn = DoorNo("12A Street 12th")
End Sub

Function DoorNo(addy As String) As String

Dim door As String
Dim AddressArray() As String
AddressArray = Split(addy)
Dim i As Integer
For i = 0 To UBound(AddressArray)

    Dim iCnt As Integer
    For iCnt = 1 To Len(AddressArray(i))    'why are you looping here?
        If IsNumeric(Mid(AddressArray(i), iCnt, 1)) Then
            door = AddressArray(i)
        End If
    Next iCnt

    If Not IsEmpty(DoorNo) Or Not DoorNo = Null Then
        DoorNo = door
        Exit For
    End If
Next i

End Function

Игнорируя все остальные вещи неправильно (и сохраняя существующую текущую логику, где это возможно), вы могли бы использовать логику Exit For (а также закрытие оператора IF ).

Exit For выйдет из цикла For . Вы делаете это после того, как первое слово было проанализировано и создано.

Затем вы просто проверяете, имеет ли новое первое слово (DoorNo) значение или нет. Если это так, назначьте его и выйдите из цикла

Кроме того, поскольку ваша функция возвращает что-то, вы должны сделать это явно, используя As

Однако это не имеет смысла, поскольку вся ваша текущая логика проверяет, является ли какой-либо символ в строке числовым, и возвращает его, если так! Это означает, что адрес a12 (если он будет существовать) никогда не будет поднят. Где, как мой бизнес, который не имеет номера, но имеет глупое имя 5tars C3entre будет принят по вашей логике

Не зная ситуацию, вашу логику, тип ценностей, которые вы получаете (например, 12 Дом, Двенадцать Дом, 12а Дом, Дом, Другое и т.д.), Трудно помочь больше, но это должно заставить вас работать

1

Если все адреса начинаются с цифры, вы можете вернуть первый элемент:

Public Function DoorNo1(ByVal address As String) As String

    DoorNo1 = Split(address)(0)

End Function

иначе выйдите из функции, когда будет найдена первая цифра:

Public Function DoorNo2(ByVal address As String) As String
    Dim addressArray() As String, i As Long, j As Long

    addressArray = Split(address)

    For i = 0 To UBound(addressArray)
        For j = 1 To Len(addressArray(i))
            If IsNumeric(Mid(addressArray(i), j, 1)) Then
                DoorNo2 = addressArray(i)
                Exit Function
            End If
        Next
    Next
End Function
-2

Вам даже не нужно использовать VBA для этого.

Я использую надстройку поиска / замены RegEx, чтобы получить функциональность регулярных выражений в Excel.
(Я не связан с этой надстройкой или ее автором, я просто энтузиаст.)

При этом вы можете просто использовать эту формулу:
=RegExFind(A1,"\d+[a-zA-Z]*")


Что касается вашего кода:

быстрое решение, вы должны выйти из внешнего цикла For только вы нашли число

больше исправить:

  • Я бы даже не использовал цикл for , do ... loop был бы более эффективным (или использовал бы регулярное выражение в вашем коде, если вы уверены, что пишете код)
  • не объявляйте переменную в цикле

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .