2017-06-01 277 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

相关问题