2017-06-01 63 views
0

我正在處理一段代碼以從其標記名中提取管道的標稱大小。例如:L-P-50-00XX-0000-000。 。50將是它的標稱尺寸(2" ),我想提取我知道我能做到這一點是這樣的:EXCEL VBA如何使用函數和分割從字符串中提取整數

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 

但是這個代碼給了我一個矩陣預期的錯誤,我不知道如何我還想在進一步的計算中使用名義大小,所以在從標記名中提取它之後,必須將它轉換爲整數。有沒有人看到我在代碼中犯了錯誤?

+0

所以'DNMaat'應該原封不動地返回第一個數字標籤?該函數主要是有缺陷的,因爲'ExceptionArray'沒有在任何地方定義。你應該真的使用'Option Explicit'來防止這樣的基本錯誤。 –

+1

我很抱歉錯過了。我在原始代碼中使用了ExceptionArray(),因爲我回收它形成了我的宏的另一部分,它處理法律分類規則的異常。由於可能的困惑,只是將stackArray上的ExceptionArray更改爲TagnameArray。但是對於DNMaat(DNSize),它應該返回第一個數字標籤。 – vanBeijnhem

回答

0

這很容易做到分裂,並從'喜歡'評估一點幫助。

上「喜歡」一點背景 - 將基於輸入變量是否一個給定的模式匹配返回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 

您將要考慮改變根據您的需求函數的返回類型。如果輸入標籤不匹配模式,它將返回一個空字符串,否則返回一個長(數字)。如果需要,您可以將其更改爲返回字符串,或者您可以編寫第二個函數來將該數字解釋爲長度。

下面是您的代碼的重構版本,它只查找第一個數字標記。我清理了一下你的代碼,我想我也發現了這個bug。你被宣佈DNMAATString,但也要求它作爲一個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 
+0

謝謝你的回覆。這段代碼不會像我的文章中的第一個代碼一樣提供嗎?通過在我的「PipeCodes」中搜索第一個數字標籤,我希望能夠製作一個更通用的解決方案,以便在pipecodes中搜索大小。使用你的方法,大小總是必須是第三個值。我希望能找到一個解決方案,只需要搜索第一個,第二個或第十個值的第一個數字標籤。 – vanBeijnhem

+0

如果你問它是否會返回相同的當前功能:種。不同之處在於,如果標籤處於預期格式,它將僅返回一個長整型值,並且它將以Long類型(您應該使用整數)返回值。 –

+0

如果你只想返回第一個數字值,那麼你會想要採取你已經採取的方法(循環通過每個元素來找到第一個數字)。這個問題雖然是,你必須檢查所有可能的輸入,以確保第一個數值始終是大小。如果沒有,你會遇到一個你返回一個* size *的實例,這個實際上是別的。理想的做法是創建一個函數來識別所有可能的輸入模式,並決定如何進行相應的處理。 –

0

錯誤matrix expected由編譯器拋出,因爲你已經定義DNMaat兩次:作爲一個功能一旦作爲字符串變量和一次。將定義作爲變量移除。

另一件事:你的函數會返回一個整數,但是你把它分配給一個字符串(這個字符串用來只是把結果寫入到一個細胞)。擺脫可變DN,並直接分配給它:

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

加上全球建議使用option explicit強制所有使用的變量的定義,定義一個變量總是抱着一個行/列數long而不是integer

+0

是的!這正是我所期待的。通過刪除變量,錯誤消失。我也擺脫了DN,這只是我用來嘗試自己解決問題的一個額外步驟。至於你的全球建議謝謝你,我會從現在開始使用這些建議。猜猜我的問題已解決! – vanBeijnhem