2016-05-04 9 views
0

Ich bin ein Neuling im Thema VBA.Vba aus Stapelspeicher (Error 28) - rekursive Verfahren

Ich möchte einen IP-Bereich zu einem regulären Ausdruck gemacht werden. Dieses Code-Bit sollte den Anfang (a) und das Ende (b) eines Zahlenbereichs auf einen regulären Ausdruck setzen, z. B. a = 111, b = 114, Ergebnis = (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 

Aber MS Ecel weiß nicht, wie rekursive Prozeduren und wenn ich die Funktion MsgBox IPAll("10.6.24.1", "10.6.25.254") es sagt verwenden: "Out of Stack-Speicher (Error 28)". Was kann ich tun? Wie kann ich es lösen?

Bearbeitet: Es funktioniert mit Subnetz-Maske 26, aber ich bekomme den Fehler, wenn ein 22-Subnetz für einen IP-Bereich verwenden. Kann ich den Speicherplatz im Stapelspeicherbereich bearbeiten?

König grüßt.

+0

eine Funktion mit dem Namen 'Range' machen ist bestenfalls zweifelhaft und wird zu Fehlern führen –

+0

Vielen Dank für diesen Tipp. – user4742258

+0

Ich sollte eine while-Schleife verwenden, um es zu beheben? Wie? – user4742258

Antwort

0

für a = "abc", Mid (a, 1) gibt "abc" Ich vermute, Sie wollen, Mid (a, 1,1), die zurückkehren würde "a"

zum Beispiel

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), ")" 
+0

Vielen Dank für die Lösung des ersten Fehlers, aber mit einem höheren IP-Bereich bekomme ich auch den Fehler. – user4742258

+0

Dies löste Ihr Stack-Überlaufproblem. verursacht durch einen Fehler in Ihrer Recurse-Methode. Wenn Sie ein Problem in Ihrem Algorithmus haben.?IPGen(1,256) [1-9] | [1-9] [0-9] | 1 ([0-9] [0-9]) | 2 ([0 -4] [0-9] | 5 [0-6]) ? IPGen (22,256) 2 [2-9] | [3-9] [0-9] | 1 ([0-9] [0 -9]) | 2 ([0-4] [0-9] | 5 [0-6]) ? IPGen (22,26) 2 [2-6]. Können Sie einen bestimmten Methodenaufruf angeben, der fehlschlägt? – Gareth

+0

Entschuldigung, ich habe vergessen, die andere Funktion hinzuzufügen ... – user4742258

0

Sie könnten dies auch neu schreiben, so dass keine Rekursion verwendet wird. Das Endergebnis ist vielleicht nicht so elegant, aber ohne Zweifel schneller und wird eine Arbeits regulären Ausdruck erzeugen:


Beispiel Verwendung:MsgBox GenIP(122, 223)
Produziert:       [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