EXCEL VBA, как использовать функции и разбить, чтобы извлечь целое число из строки

Я работаю над куском кода, чтобы извлечь номинальный размер конвейера из его тэга. Например: LP-50-00XX-0000-000. 50 - это номинальный размер (2"), который я хотел бы извлечь. Я знаю, что мог бы сделать это так:

TagnameArray() = Split("L-P-50-00XX-0000-000", "-")
DNSize = TagnameArray(2)

Но я бы хотел, чтобы это было функцией, потому что это небольшая часть моего макроса, и она мне не нужна для всех растений, над которыми я работаю, только для этого. Мой текущий код:

Sub WBDA_XXX()
Dim a As Range, b As Range
Dim TagnameArray() As String
Dim DNMaat As String
Dim DN As String

Set a = Selection

For Each b In a.Rows
    IntRow = b.Row
    TagnameArray() = Split(Cells(IntRow, 2).Value, "-")
    DN = DNMaat(IntRow, TagnameArray())
    Cells(IntRow, 3).Value = DN
Next b
End Sub



Function DNMaat(IntRow As Integer, TagnameArray() As String) As Integer
    For i = LBound(TagnameArray()) To UBound(TagnameArray())
        If IsNumeric(TagnameArray(i)) = True Then
            DNMaat = TagnameArray(i)
            Exit For
        End If
    Next i
End Function

Однако этот код дает мне матрицу ожидаемой ошибки, которую я не знаю, как ее устранить. Я также хотел бы использовать номинальный размер в дальнейших вычислениях, поэтому он должен быть преобразован в целое число после извлечения его из тэга. Кто-нибудь видит, где я допустил ошибку в своем коде?

2 ответа

Это достаточно легко сделать с помощью разделения и небольшой помощи из оценки "Мне нравится".

Немного фона "Like" - он вернет TRUE или FALSE в зависимости от того, соответствует ли входная переменная заданному шаблону. В шаблоне [A-Z] означает, что это может быть любая заглавная буква между A и Z, и # означает любое число.

Код:

' Function declared to return variant strictly for returning a Null string or a Long
Public Function PipeSize(ByVal TagName As String) As Variant
    ' If TagName doesn't meet the tag formatting requirements, return a null string
    If Not TagName Like "[A-Z]-[A-Z]-##-##[A-Z]-####-###" Then
        PipeSize = vbNullString
        Exit Function
    End If

    ' This will hold our split pipecodes
    Dim PipeCodes As Variant
    PipeCodes = Split(TagName, "-")

    ' Return the code in position 2 (Split returns a 0 based array by default)
    PipeSize = PipeCodes(2)
End Function

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

Вот реорганизованная версия вашего кода, которая находит только первый числовой тег. Я немного почистил твой код и, думаю, тоже нашел ошибку. Вы декларировали DNMAAT как String но и называя это как Function, Вероятно, это вызвало ошибку, ожидаемую вашим массивом.

Вот код:

' Don't use underscores '_' in names. These hold special value in VBA.
Sub WBDAXXX()
    Dim a As Range, b As Range
    Dim IntRow As Long

    Set a = Selection

    For Each b In a.Rows
        IntRow = b.Row
        ' No need to a middleman here. I directly pass the split values
        ' since the middleman was only used for the function. Same goes for cutting DN.
        ' Also, be sure to qualify these 'Cells' ranges. Relying on implicit
        ' Activesheet is dangerous and unpredictable.
        Cells(IntRow, 3).value = DNMaat(Split(Cells(IntRow, 2).value, "-"))

    Next b
End Sub

' By telling the function to expect a normal variant, we can input any
' value we like. This can be dangerous if you dont anticipate the errors
' caused by Variants. Thus, I check for Arrayness on the first line and 
' exit the function if an input value will cause an issue.
Function DNMaat(TagnameArray As Variant) As Long
    If Not IsArray(TagnameArray) Then Exit Function

    Dim i As Long
    For i = LBound(TagnameArray) To UBound(TagnameArray)
        If IsNumeric(TagnameArray(i)) = True Then
            DNMaat = TagnameArray(i)
            Exit Function
        End If
    Next i
End Function

Ошибка matrix expected генерируется компилятором, потому что вы определили DNMaat дважды: один раз как строковая переменная и один раз как функция. Удалить определение как переменную.

Другое дело: ваша функция будет возвращать целое число, но вы присваиваете его строке (и эта строка используется только для записи результата в ячейку). Избавиться от переменной DN и назначить его напрямую:

Cells(IntRow, 3).Value = DNMaat(IntRow, TagnameArray())

Плюс глобальный совет по использованию option explicit обеспечить определение всех используемых переменных и определить переменную, содержащую номер строки / столбца всегда как long а не как integer

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