简体   繁体   English

vba堆栈空间不足(错误28)-递归过程

[英]vba Out of stack space (Error 28) - recursive procedures

I am newbie in the theme VBA. 我是主题VBA的新手。

I want to made an IP range to a regular expression. 我想将IP范围设为正则表达式。 This bit of Code should made the start (a) and end (b) of an number range to a regular expression, for instance a=111, b=114, result=(1(1[1-4])). 代码的此位应使数字范围的开始(a)和结束(b)成为正则表达式,例如a = 111,b = 114,result =(1(1 [1-4]))。

Function IPAll(a As String, b As String) As String
    Dim Dot1%, Dot2%, Dot3%
    Dim LowIP(3) As Variant
    Dot1 = InStr(1, a, ".")
    Dot2 = InStr(Dot1 + 1, a, ".")
    Dot3 = InStr(Dot2 + 1, a, ".")

    If Dot1 <> 0 Then
        LowIP(0) = Mid(a, 1, Dot1 - 1)
        If Dot2 <> 0 Then
            LowIP(1) = Mid(a, Dot1 + 1, Dot2 - Dot1 - 1)
            If Dot3 <> 0 Then
                LowIP(2) = Mid(a, Dot2 + 1, Dot3 - Dot2 - 1)
                LowIP(3) = Mid(a, Dot3 + 1, Dot3 - 1)
            Else
                LowIP(2) = Mid(a, Dot2 + 1, Dot2 - 1)
            End If
        Else
            LowIP(1) = Mid(a, Dot1 + 1, Dot1 - 1)
            If LowIP(1) = "" Then                   'Fehler bei "" *1 abfangen
                LowIP(1) = 0
            End If
        End If
    Else
        LowIP(0) = a
        LowIP(1) = 0
    End If


    Dim HighIP(3) As Variant
    Dot1 = InStr(1, b, ".")
    Dot2 = InStr(Dot1 + 1, b, ".")
    Dot3 = InStr(Dot2 + 1, b, ".")

    If Dot1 <> 0 Then
        HighIP(0) = Mid(b, 1, Dot1 - 1)
        If Dot2 <> 0 Then
            HighIP(1) = Mid(b, Dot1 + 1, Dot2 - Dot1 - 1)
            If Dot3 <> 0 Then
                HighIP(2) = Mid(b, Dot2 + 1, Dot3 - Dot2 - 1)
                HighIP(3) = Mid(b, Dot3 + 1, Dot3 - 1)
            Else
                HighIP(2) = Mid(b, Dot2 + 1, Dot2 - 1)
            End If
        Else
            HighIP(1) = Mid(b, Dot1 + 1, Dot1 - 1)
             If HighIP(1) = "" Then
                HighIP(1) = 0
            End If
        End If
    Else
        HighIP(0) = b
        HighIP(1) = 0
    End If

    Dim splita As Variant: splita = LowIP
    Dim splitb As Variant: splitb = HighIP

    Dim zeros$: zeros = ""
    Dim twofivefives$: twofivefives = ""
    Dim j%
    Dim len_splita%: len_splita = (UBound(Split(a, ".")) + 1)
    For j = 0 To len_splita                  'je nach länge von a wird zeros zu z.B. 0.0.0.0. und twofivefives zu z.B 255.255.255.255.
        zeros = zeros & "0."
        twofivefives = twofivefives & "255."
    Next j
    zeros = Mid(zeros, 1, Len(zeros) - 1)       'wegnehmen des letzten Punktes
    twofivefives = Mid(twofivefives, 1, Len(twofivefives) - 1)



    If splita(0) = splitb(0) And len_splita = 1 Then                                                                                    'wenn erste Zahl gleich und Länge beider =1
        IPAll = splita(0)                                                                                                                   'return: erste Zahl
    ElseIf splita(0) = splitb(0) Then                                                                                                   'wenn erste Zahl gleich
        IPAll = splita(0) & "\." & IPAll(Mid(a, InStr(a, ".") + 1, Len(a)), Mid(b, InStr(b, ".") + 1, Len(b)))                              'return: erste Zahl, "\." IPAll( rest von a, rest von b)
    ElseIf len_splita = 1 Then                                                                                                          'wenn a nur eine Zahl
        IPAll = "(" & IPGen(a, b) & ")"                                                                                                     'return: "(", IPGen(a, b), ")"
    ElseIf splita(1) = 0 And splitb(1) = 255 Then                                                                                       'wenn zweite Zahl a =0 und zweite zahl b =255
        IPAll = "(" & IPGen(splita(0), splitb(0)) & ")\." & IPAll(Mid(a, InStr(a, ".") + 1, Len(a)), Mid(b, InStr(b, ".") + 1, Len(b)))     'return: "(", IPGen(erste Zahl a, erste Zahl b), ")\.", IPAll(alles nach ersten . aus a, alles nach ersten . aus b)
    ElseIf splita(1) <> 0 And splitb(1) <> 255 And (splita(1) * 1 + 1) = (splitb(1) * 1) Then                                           'wenn zweite zahl a !=0 und zweite zahl b != 255 und (zweite zahl a) +1 gleich zweite zahl b
        IPAll = "(" & splita(0) & "\." & IPAll(Mid(a, InStr(a, ".") + 1, Len(a)), twofivefives)                                             'return: "(", erste zahl a, "\.", IPAll(alles nach ersten . aus a, twofivefives)
        IPAll = IPAll & "|" & splitb(0) & "\." & IPAll(CStr(zeroes), Mid(b, InStr(b, ".") + 1, Len(b))) & ")"                               'return: "|", erste zahl a, "\.", IPAll(zeroes, alles nach ersten . aus b), ")"
    ElseIf splita(1) <> 0 And splitb(1) <> 255 Then                                                                                     'wenn zweite zahl a !=0 und zweite zahl b !=255
        IPAll = "(" & splita(0) & "\." & IPAll(Mid(a, InStr(a, ".") + 1, Len(a)), twofivefives)                                             'return: "(", erste zahl a, "\.", IPAll(alles nach ersten . aus a, twofivefives)
        IPAll = IPAll & "|(" & IPAll((splita(0) * 1 + 1) & "." & zeroes, (splitb(0) * 1 - 1) & "." & twofivefives) & ")"                    'return: "|(", IPAll(erste Zahl a +1 und "." und zeroes, erste zahl b -1 und "." und twofivefives), ")"
        IPAll = IPAll & "|" & splitb(0) & "\." & IPAll(CStr(zeroes), Mid(b, InStr(b, ".") + 1, Len(b))) & ")"                               'return: "|", erste Zahl b, "\.", IPAll(zeroes, alles nach ersten . aus b), ")"
    ElseIf splita(1) <> 0 Then                                                                                                          'wenn zweite zahl a !=0
        IPAll = "(" & splita(0) & "\." & IPAll(Mid(a, InStr(a, ".") + 1, Len(a)), twofivefives)                                             'return: "(", erste zahl, "\.", IPAll(alles nach ersten . aus a, twofivefives)
        IPAll = IPAll & "|" & IPAll((splita(0) * 1 + 1) & "." & zeroes, (splitb(0) * 1) & "." & twofivefives) & ")"                         'return: "|", IPAll(erste zahl a +1 und "." und zeroes, erste zahl b und "." und twofivefives), ")"         <-warum nicht b -1 ?
    ElseIf splitb(1) <> 255 Then                                                                                                        'wenn zweite zahl b !=255
        IPAll = "(" & IPAll(splita(0) & "." & zeros, (splitb(0) * 1 - 1) & "." & twofivefives)                                              'return: "(", IPAll(erste zahl a und "." und zeroes, erste zahl b -1 und "." und twofivefives)
        IPAll = IPAll & "|" & splitb(0) & "\." & IPAll(CStr(zeroes), Mid(b, InStr(b, ".") + 1, Len(b))) & ")"                               'return: "|", erste zahl b, "\.", IPAll(zeroes, alles nach ersten . aus b), ")"
    End If

End Function

Function IPGen(a As Variant, b As Variant) As Variant
         If a = "" Then      'Fehler bei "" * 1 abfangen
        a = 0
    End If
    If a * 1 > b * 1 Then
        Dim temp%: temp = a
        a = b
        b = temp
    End If
    If a = b Then
        IPGen = a
    ElseIf Mid(a, 1, 1) = Mid(b, 1, 1) And Len(a) = Len(b) And Len(a) = 3 Then                                  'wenn erste Zahl gleich und Länge beider =3
        IPGen = Mid(a, 1, 1) & "(" & IPGen(Mid(a, 2, Len(a)), Mid(b, 2, Len(b))) & ")"                              'return: erste Zahl a, "(", IPGen(rest, rest), ")"
    ElseIf Len(a) = Len(b) And Len(a) = 3 Then                                                                  'wenn Länge beider gleich 3
        IPGen = Mid(a, 1, 1) & "(" & IPGen(Mid(a, 2, Len(a)), 99) & ")|" & IPGen((Mid(a, 1, 1) * 1 + 1) & "00", b)  'return: erste Zahl a, "(", IPGen(rest, 99), ")|", IPGen( erste Zahl +1 und "00", b)
    ElseIf Len(b) = 3 Then                                                                                      'wenn Länge a =3
        IPGen = IPGen(a, 99) & "|" & IPGen(100, b)                                                                  'return: IPGen(a, 99), "|", IPGen(100, b)
    ElseIf Mid(a, 1, 1) = Mid(b, 1, 1) And Len(a) = Len(b) And Len(a) = 2 Then                                  'wenn erste Zahl gleich und Länger beider gleich 2
        IPGen = Mid(a, 1, 1) & ip_range(Mid(a, 2, 1), Mid(b, 2, 1))                                                 'return: erste Zahl a, ip_range(zweite Zahl a, zweite Zahl b)
    ElseIf Len(a) = Len(b) And Mid(a, 2, 1) = 0 And Mid(b, 2, 1) = 9 And Len(a) = 2 Then                        'wenn zweite Zahl a =0, zweite Zahl b =9 und Länge beider =2
        IPGen = ip_range(Mid(a, 1, 1), Mid(b, 1, 1)) & ip_range(Mid(a, 2, 1), Mid(b, 2, 1))                         'return: ip_range(erste Zahl a, erste Zahl b + ip_range(zweite Zahl a, zweite Zahl b))
    ElseIf Len(a) = Len(b) And Mid(a, 2, 1) <> 0 And Len(a) = 2 Then                                            'wenn zweite Zahl ungleich 0 und Länge beider =2
        IPGen = IPGen(a, Mid(a, 1, 1) & "9") & "|" & IPGen(Mid(a, 1, 1) * 1 + 1 & "0", b)                           'return: IPGen(a, erste Zahl a und "9"), "|", IPGen(erste Zahl + 1 und "0", b)
    ElseIf Len(a) = Len(b) And Mid(b, 2, 1) <> 9 And Len(b) = 2 Then                                            'wenn zweite Zahl b ungleich 9 und Länge beider =2
        IPGen = IPGen(a, (Mid(b, 1, 1) * 1 - 1) & "9") & "|" & IPGen(Mid(b, 1, 1) & "0", b)                         'return: IPGen(a, erste Zahl b -1 und "9"), "|", IPGen(erste Zahl b und "0", b)
    ElseIf Len(a) = 1 And Len(b) = 1 Then                                                                       'wenn Länge beider =1
        IPGen = ip_range(a, b)                                                                                      'return: ip_range(a, b)
    ElseIf Len(a) = 1 Then                                                                                      'wenn Länge a =1
        IPGen = ip_range(a, 9) & "|" & IPGen(10, b)                                                                 'return: ip_range(a, 9), "|", IPGen(10, b)
    End If

End Function

Function ip_range(a As Variant, b As Variant) As Variant
    ip_range = "[" & a & "-" & b & "]"
End Function

But MS Ecel don't like recursive procedures and if I use the function MsgBox IPAll("10.6.24.1", "10.6.25.254") it says: "Out of stack space (Error 28)". 但是MS Ecel不喜欢递归过程,如果我使用MsgBox IPAll("10.6.24.1", "10.6.25.254")函数MsgBox IPAll("10.6.24.1", "10.6.25.254")它会说:“栈空间不足(错误28)”。 What can I do? 我能做什么? How can I solve it? 我该如何解决?

Edited: it works with subnet mask 26, but I get the error if use a 22 subnet for an ip range. 编辑:它适用于子网掩码26,但如果将22子网用于ip范围,则会出现错误。 Could I edit the space of the stack space? 我可以编辑堆栈空间的空间吗?

King regards. 国王的问候。

for a = "abc", Mid(a,1) returns "abc" I suspect you are wanting Mid(a,1,1) which would return "a" 对于a =“ abc”,Mid(a,1)返回“ abc”我怀疑您想要的Mid(a,1,1)将返回“ a”

for example 例如

ElseIf Mid(a, 1, 1) = Mid(b, 1, 1) And Len(a) = Len(b) And Len(a) = 3 Then                                  'wenn erste Zahl gleich und Länge beider =3
        Debug.Print a, b, "|a| = |b| = 3; a(1)=b(1) "
        aa = Mid(a, 2, Len(a))
        bb = Mid(b, 2, Len(b))
        IPGen = Mid(a, 1, 1) & "(" & IPGen(aa, bb) & ")"                           'return: erste Zahl, "(", IPGen(rest, rest), ")"

You could also re-write this so that it doesn't use recursion. 您也可以重写它,以使其不使用递归。 The end result is perhaps not as elegant but no doubt faster and will produce a working regular expression: 最终结果可能不那么优雅,但无疑更快,并且将产生一个有效的正则表达式:


Example Use: MsgBox GenIP(122, 223) 使用示例: MsgBox GenIP(122, 223)
Produces: [12][0-9][0-9] 产生: [12][0-9][0-9]


Function GenIP(a As Byte, b As Byte) As String

    Dim strA As String * 3
    Dim strB As String * 3
    Dim retV(1 To 3) As String

    strA = Format$(a, "000")
    strB = Format$(b, "000")

    If a = b Then
        GenIP = strA
    Else
        With WorksheetFunction
            retV(1) = Left$(IIf(.Min(a, b) = a, strA, strB), 1)
            retV(2) = Mid$(IIf(.Min(a, b) = a, strA, strB), 2, 1)
            retV(3) = Right$(IIf(.Min(a, b) = a, strA, strB), 1)

            For i = .Min(a, b) To .Max(a, b)
                If Right(retV(1), 1) <> Left$(Format$(i, "000"), 1) And Len(retV(1)) < 3 Then
                    retV(1) = retV(1) & Left$(Format$(i, "000"), 1)
                End If
                If Right(retV(2), 1) <> Mid$(Format$(i, "000"), 2, 1) And Len(retV(2)) < 10 Then
                    retV(2) = retV(2) & Mid$(Format$(i, "000"), 2, 1)
                End If
                If Right(retV(3), 1) <> Right$(Format$(i, "000"), 1) And Len(retV(3)) < 10 Then
                    retV(3) = retV(3) & Right$(Format$(i, "000"), 1)
                End If
            Next
        End With

        If Len(retV(1)) = 3 Then
            retV(1) = "0-2"
        End If
        If Len(retV(2)) = 10 Then
            retV(2) = "0-9"
        End If
        If Len(retV(3)) = 10 Then
            retV(3) = "0-9"
        End If

        GenIP = "[" & retV(1) & "][" & retV(2) & "][" & retV(3) & "]"
    End If

End Function

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM