[英]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.