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