Forum Allplan

VBScript und Umgang mit Arrays


Hallo Zusammen!

In letzter Zeit haben wir uns im Büro mit dem VBScripting in Allplan auseinandergesetzt. Die erste Aufgabe, die wir uns vorgenommen haben, war eine einfache Funktion zu schreiben, die aus einer Zeichenfolge mit Trennzeichen (z.B. "_") eine Sub-Zeichenfolge extrahiert. Kompliziert, deshalb hier ein Beispiel:

Syntax der Funktion:

ExtractString(txt as String , SplittSign as String , index as Integer)

Beispiel:

ExtractString("abc_def_ghi" , "_" , 1) -> "abc"
ExtractString("abc_def_ghi" , "_" , 2) -> "def"
ExtractString("abc_def_ghi" , "_" , 3) -> "ghi"

Der erste Code sah so aus:

Function ExtractString(txt, SplittSign, index)
   
   index = CInt(index)
   
   StringArray = Split(txt, SplittSign)
   
   If index - 1 > UBound(StringArray) Then
      ExtractString = ""
   Else
      ExtractString = StringArray(index - 1)
   End If

End Function  

Und das hat wunderbar und zuverlässig sowohl in Excel, als auch in dem kleinen Testprogramm "VB-Script Tester" von @Nemo funktioniert(siehe Link). Leider in Allplan gab es viele Probleme und Abstürze. Es kam vor, dass die Funktion bei einer Zeichenfolge mit 3 Trennzeichen funktioniert hat, mit 4 Trennzeichen aber nicht mehr. Oder wenn der Text zwischen den Trennzeichen mal zu kurz oder zu lang war. Beim Absturz kam in Protokoll-Fenster die Meldung:

ErrorAllplanUnhandledExceptionFilter

Exception nr E06D7363 -INTERN ERROR e06d7363
is occured at 00007FFB3C623E49

Damit konnten wir natürlich nichts anfangen. Wir haben die Funktion komplett umgeschrieben, so dass sie mit Arrays gar nicht zu tun hat. Der Code sieht jetzt so aus (falls vielleicht jemand das gleiche Problem hat):

Function ExtractString(txt, SplittSign, i)
   
   i = CInt(i)
   start = 0
   j = 1
   found_at = 0
   ExtractString = txt
   
   Do
      found_at = InStr(start + 1, txt, SplittSign)
    
      If found_at = 0 Then
         found_at = Len(txt) + 1
      End If
      
      If j = i And Start < Len(txt) Then
         ExtractString = Mid(txt, start + 1, found_at - start - 1)
      End If
      
      start = found_at
      j = j + 1
      
   Loop Until j > i

End Function

Jetzt die Frage an die Allgemeinheit: habt Ihr schon ähnliches Problem? Oder auch andere Probleme, die irgendwie umgegangen werden müssten, weil der Allplan interner Compiler damit nicht klar gekommen ist?

Und hier gleich eine Bitte an Allplan: schaut Euch bitte diese Problematik mit den Arrays an. Ich glaube, hier gibt es Versbesserungsbedarf.

Show most helpful answer Hide most helpful answer

1. Ich würde immer lokal benutzte Variablen vor Benutzung deklarieren
2. StringArray könnte ein Schlüsselwort sein, sollte man lieber meiden
3. Allplan hat Probleme beim Rückgabewert String als Variant.
Alles was im VB-Script ankommt (Funktionsparameter) ist erst mal so ein Variant!
Wenn man so ein Variant zurückgibt, weiss allplan manchmal nicht, ob es das nun in einen String umwandeln soll, oder nicht!
Und wenn, wird dieser wird manchmal nicht korrekt terminiert! (daher vermutlich der Absturz)
Bei mir hat da immer geholfen, ein paar Leerzeichen dranzuhängen, also z.B
ExtractString = StringArray(index - 1) & " " Damit istr es klar, das es ein String sein soll!
...oder den Result-Wert erst mal in einer deklarierten, typisierten Variable abzulegen, und dann zuzuweisen.

1. Ich würde immer lokal benutzte Variablen vor Benutzung deklarieren
2. StringArray könnte ein Schlüsselwort sein, sollte man lieber meiden
3. Allplan hat Probleme beim Rückgabewert String als Variant.
Alles was im VB-Script ankommt (Funktionsparameter) ist erst mal so ein Variant!
Wenn man so ein Variant zurückgibt, weiss allplan manchmal nicht, ob es das nun in einen String umwandeln soll, oder nicht!
Und wenn, wird dieser wird manchmal nicht korrekt terminiert! (daher vermutlich der Absturz)
Bei mir hat da immer geholfen, ein paar Leerzeichen dranzuhängen, also z.B
ExtractString = StringArray(index - 1) & " " Damit istr es klar, das es ein String sein soll!
...oder den Result-Wert erst mal in einer deklarierten, typisierten Variable abzulegen, und dann zuzuweisen.

Also, Ich habe die Variablen vorab dimensioniert, die Funktionsparameter noch sicherheitshalber in entsprechenden Variablentyp konvertiert und der Ausgabewert vor der Ausgabe in der Variable "txt" (Typ String) zwischengespeichert, um sicherzustellen, das wirklich ein String zurückgegeben wird. Der Code sieht jetzt so aus:

Function ExtractString_2(txt, SplittingSign, i)
   
   Dim StringArray
   
   i = CInt(i)
   txt = CStr(txt)
   SplittingSign = CStr(SplittingSign)
   
   StringArray = Split(txt, SplittingSign)
   
   If i - 1 > UBound(StringArray) Then
      txt = "error"
   Else
      txt = StringArray(i-1)
   End If

ExtractString_2 = txt
   
End Function

Das Ganze funktioniert jetzt deutlich besser. Ich glaube, dass folgende Aussage war hier entscheidend:

Alles was im VB-Script ankommt (Funktionsparameter) ist erst mal so ein Variant!

Darüber wissen wahrscheinlich nur wenige. Tatsächlich überspringt man den Variablentyp bei der Funktionsdefinition in VBScript. Man definiert:
Function ExtractString_2(txt, SplittingSign, i)
Anstatt:
Function ExtractString_2(txt As String, SplittingSign As String, i As Integer) As String
was das ganze eindeutig machen würde. Sogar bei der Variablendimensionierung gibt man den Variablentyp nicht an - das finde ich etwas komisch. Der Sinn der Deklaration ist entsprechend viel Speicher für den Variablen zu reservieren. Wenn ich den Typ nicht deklariere, kann das System eher den Speicher in der richtigen Größe nicht reservieren, oder?

Jedenfalls vielen Dank für den Hinweis! Mein Script funktioniert wieder. Vielleicht nutzt das auch noch jemandem.


https://connect.allplan.com/ utilizza cookies  -  Maggiori informazioni

Accetta