Rubrik: Variablen/Strings | VB-Versionen: VB2008 | 21.07.08 |
Zeichenfolgen fester Länge Extension Methods, die Zeichenfolge bei der Zuweisung auf eine vorgegebene Länge einrichten (für String- und StringBuilder-Variablen) | ||
Autor: Manfred Bohn | Bewertung: | Views: 18.085 |
ohne Homepage | System: Win2k, WinXP, Win7, Win8, Win10, Win11 | Beispielprojekt auf CD |
Strings fester Länge sind String-Variable, die bei der Zuweisung einer Zeichenfolge dafür sorgen, dass eine vorgegebene Länge eingehalten wird. Zu kurze Zeichenfolgen werden bei der Zuweisung durch Leerzeichen ergänzt, zu lange Zeichenfolgen werden hinten abgeschnitten.
Einen Variablentyp, der diese Aufgabe automatisch erledigt, gibt es in VB 2008 nicht.
Relativ einfach ist es, eine Erweiterungsmethode zu erstellen, die bei der Zuweisung die Länge der zugewiesenen Zeichenfolge (auf eine 'gewöhnliche' Stringvariable) gemäß der Vorgabe einrichtet. Die Routine 'FixL' muss, um als 'Extension' zu funktionieren, in ein Standardmodul eingetragen werden.
In VB gibt es neben String-Variablen auch die Klasse StringBuilder. Instanzen dieser Klasse bewahren eine Zeichenfolge auf und stellen einige Bearbeitungsmethoden zur Verfügung. Sie sind immer dann vorzuziehen, wenn im Programm viele Zeichenfolgen-Manipulationen vorgenommen werden, weil sie einen festen Speicherbereich verwalten, der nur bei Bedarf erweitert wird. String-Variablen beherrschen das nicht. Bei ihnen muss nach jeder Änderung die enthaltene Zeichenfolge in einem neuen Speicherbereich erstellt werden.
Zu beachten ist auch, dass Stringbuilder-Variable Instanzen einer Klasse sind; d.h. als Parameter werden sie immer 'By Reference' übergeben - also als Zeiger auf den aktuell zugeordneten Speicherbereich. (Die Verwendung des 'Default'-Schlüsselworts 'ByVal' hat in diesem Fall keine Auswirkungen). Anders verhalten sich String-Variable. Die gelten zwar auch als Referenztypen ('spezielle Verwaltung'), können aber durch 'ByVal'-Übergabe im rufenden Code vor dem Überschreiben geschützt werden.
Das Modul 'modStringFix' enthält 'Extensions' für String und StringBuilder-Variablen und ermöglicht wechselseitige Zeichenfolgen-Zuweisungen - als 'Function' und als 'Sub' unter Beachtung einer als Parameter vorgegebenen Länge.
Die Routine 'Demo_StringFix' demonstriert die Anwendung.
Man beachte, dass 'Extensions' auch dann aufgerufen werden können, wenn die Variable auf 'Nothing' zeigt.
Module modStringFix Public Sub demo_stringfix() Const TheString As String = "teststring-und mehr" ' fixe Länge der Ziel-Strings Const FL As Integer = 10 ' String-Variable (Quelle und Ziel) Dim qs As String = TheString Dim zs As String = "" ' StringBuilder-Variable (Quelle und Ziel) Dim qstb As New System.Text.StringBuilder(TheString) Dim zstb As System.Text.StringBuilder ' String --> String (FixL) zs = Nothing zs.FixL(qs, FL) zs = Nothing zs = qs.FixL(FL) ' StringBuilder --> StringBuilder (FixL) zstb = qstb.FixL(FL) zstb.FixL(qstb, FL) ' StringBuilder --> String (FixS) zs.FixS(qstb, FL) zs = qstb.FixS(FL) ' String --> StringBuilder (FixS) zstb = qs.FixS(FL) zstb.FixS(qs, FL) ' Die Quell-Variablen dürfen nicht verändert sein If qs <> TheString Then Stop If qstb.ToString <> TheString Then Stop End Sub
''' <summary> ''' Zuweisung eines Strings fester Länge ''' </summary> ''' <param name="str">Der zuzuweisende String</param> ''' <param name="FixLength">Länge des String</param> ''' <returns>String fester Länge</returns> <System.Runtime.CompilerServices.Extension()> _ Public Function FixL(ByVal str As String, _ Optional ByVal FixLength As Integer = 15) As String If FixLength < 1 Or FixLength > 1024 Then Throw New ArgumentException End If Dim Add As Integer = FixLength - Microsoft.VisualBasic.Len(str) If Add > 0 Then Return str & Microsoft.VisualBasic.Space(Add) Else Return Microsoft.VisualBasic.Left(str, FixLength) End If End Function
''' <summary> ''' Zuweisung eines Strings fester Länge ''' </summary> ''' <param name="str">Der zuzuweisende String</param> ''' <param name="FixLength">Länge des String</param> ''' <returns>String fester Länge</returns> <System.Runtime.CompilerServices.Extension()> _ Public Function FixS(ByVal str As String, _ Optional ByVal FixLength As Integer = 15) As System.Text.StringBuilder If FixLength < 1 Or FixLength > 1024 Then Throw New ArgumentException End If Dim Add As Integer = FixLength - Microsoft.VisualBasic.Len(str) If Add > 0 Then str &= Microsoft.VisualBasic.Space(Add) Else str = Microsoft.VisualBasic.Left(str, FixLength) End If Return New System.Text.StringBuilder(str) End Function
''' <summary> ''' Zuweisung eines Strings fester Länge ''' </summary> ''' <param name="stb">Der zuzuweisende String</param> ''' <param name="FixLength">Länge des String</param> ''' <returns>String fester Länge</returns> <System.Runtime.CompilerServices.Extension()> _ Public Function FixL(ByVal stb As System.Text.StringBuilder, _ Optional ByVal FixLength As Integer = 15) As System.Text.StringBuilder Dim ret As New System.Text.StringBuilder If FixLength < 1 Or FixLength > 1024 Then Throw New ArgumentException End If Dim l As Integer = 0 If Not IsNothing(stb) Then ret = New System.Text.StringBuilder( _ stb.ToString, 0, stb.Length, FixLength) Else ret = New System.Text.StringBuilder(FixLength) End If Dim Add As Integer = FixLength - ret.Length If Add > 0 Then ret.Append(Microsoft.VisualBasic.Space(Add)) Else ret.Length = FixLength End If Return ret End Function
''' <summary> ''' Zuweisung eines Strings fester Länge ''' </summary> ''' <param name="stb">Der zuzuweisende String</param> ''' <param name="FixLength">Länge des String</param> ''' <returns>String fester Länge</returns> <System.Runtime.CompilerServices.Extension()> _ Public Function FixS(ByVal stb As System.Text.StringBuilder, _ Optional ByVal FixLength As Integer = 15) As String If FixLength < 1 Or FixLength > 1024 Then Throw New ArgumentException End If Dim ret As String Dim l As Integer = 0 If Not IsNothing(stb) Then l = stb.Length ret = stb.ToString Else ret = "" End If Dim Add As Integer = FixLength - l If Add > 0 Then Return ret & Microsoft.VisualBasic.Space(Add) Else Return Microsoft.VisualBasic.Left(ret, FixLength) End If End Function
''' <summary> ''' Zuweisung eines Strings fester Länge ''' </summary> ''' <param name="str">Die Stringvariable, auf die zugewiesen wird</param> ''' <param name="val">Die zuzuweisende Zeichenfolge</param> ''' <param name="FixLength">geforderte Länge der Zeichenfolge</param> <System.Runtime.CompilerServices.Extension()> _ Public Sub FixL(ByRef str As String, _ ByVal val As String, _ Optional ByVal FixLength As Integer = 15) If FixLength < 1 Or FixLength > 1024 Then Throw New ArgumentException End If Dim Add As Integer = FixLength - Microsoft.VisualBasic.Len(val) If Add > 0 Then str = val & Microsoft.VisualBasic.Space(Add) Else str = Microsoft.VisualBasic.Left(val, FixLength) End If End Sub
''' <summary> ''' Zuweisung eines Strings fester Länge ''' </summary> ''' <param name="str">Die Stringvariable, auf die zugewiesen wird</param> ''' <param name="val">Die zuzuweisende Zeichenfolge</param> ''' <param name="FixLength">Länge des String</param> <System.Runtime.CompilerServices.Extension()> _ Public Sub FixS(ByRef str As String, _ ByVal val As System.Text.StringBuilder, _ Optional ByVal FixLength As Integer = 15) If FixLength < 1 Or FixLength > 1024 Then Throw New ArgumentException End If str = "" Dim Add As Integer = FixLength - val.Length If Add > 0 Then val.Append(Microsoft.VisualBasic.Space(Add)) str = val.ToString Else str = Microsoft.VisualBasic.Left( _ val.ToString, FixLength) End If End Sub
''' <summary> ''' Zuweisung eines Strings fester Länge ''' </summary> ''' <param name="stb">Die Stringbuilder-Variable, ''' auf die zugewiesen wird</param> ''' <param name="val">Die zuzuweisende Zeichenfolge</param> ''' <param name="FixLength">Länge des String</param> <System.Runtime.CompilerServices.Extension()> _ Public Sub FixL(ByRef stb As System.Text.StringBuilder, _ ByVal val As System.Text.StringBuilder, _ Optional ByVal FixLength As Integer = 15) If FixLength < 1 Or FixLength > 1024 Then Throw New ArgumentException End If Dim l As Integer = 0 If Not IsNothing(val) Then l = val.Length stb = New System.Text.StringBuilder(val.ToString) Else stb = New System.Text.StringBuilder(FixLength) End If Dim Add As Integer = FixLength - l If Add > 0 Then stb.Append(Microsoft.VisualBasic.Space(Add)) Else stb.Length = FixLength End If End Sub
''' <summary> ''' Zuweisung eines Strings fester Länge ''' </summary> ''' <param name="stb">Die Stringbuilder-Variable, ''' auf die zugewiesen wird</param> ''' <param name="val">Die zuzuweisende Zeichenfolge</param> ''' <param name="FixLength">Länge des String</param> <System.Runtime.CompilerServices.Extension()> _ Public Sub FixS(ByRef stb As System.Text.StringBuilder, _ ByVal val As String, _ Optional ByVal FixLength As Integer = 15) If FixLength < 1 Or FixLength > 1024 Then Throw New ArgumentException End If Dim l As Integer = 0 If Not IsNothing(val) Then l = Len(val) stb = New System.Text.StringBuilder(val) Else stb = New System.Text.StringBuilder(FixLength) End If Dim Add As Integer = FixLength - l If Add > 0 Then stb.Append(Microsoft.VisualBasic.Space(Add)) Else stb.Length = FixLength End If End Sub
End Module
Hinweis für VB6-Umsteiger:
Wenn Sie sich jetzt wundern, liegen Sie richtig. Es ist auch noch folgendes zu beachten:
- Die in String-Variablen enthaltenen Zeichenfolgen sind in den aktuellen VB-Versionen grundsätzlich 'unveränderlich'. Jedes Anhängen, Verkürzen oder Überschreiben führt dazu, dass eine neue Zeichenfolge im Speicher erstellt wird.
- Programme, die zahl- und umfangreiche String-Operationen durchführen, müssen deshalb nach der Umstellung auf VB 2008 eventuell überarbeitet werden (Verwendung der StringBuilder-Klasse).
- Die vom Upgrade-Assistenten vorgenommene Umstellung der Strings fester Länge auf Instanzen der Kompatibilitäts-Klasse 'FixedLengthString' macht speziell in benutzerdefinierten Datentypen (umgestellt zu: Structures) Probleme. Sie müssen jetzt nach der Definition einer Struktur explizit initialisiert werden.
- Es kann im Einzelfall günstig sein, die Variablen des Typs 'String fester Länge' auf String- oder StringBuilder-Variablen umzustellen und dann bei den Zuweisungen die 'FixL'-Methode einzusetzen. Die Notwendigkeit der Initialisierung entfällt dann.
Das unterschiedliche Verhalten im Einzelnen:
Structure StrucTest ' Konstanten sind in Structures "shared" Public Const Length As Integer = 13 Dim Ordinärer_String As String Dim Fixed_String As VB6.FixedLengthString End Structure Public Sub demo_strucfix() Dim aaa As New StrucTest ' Eine einfache String-Variable muss nicht ' initialisiert werden, benötigt aber Längenangabe aaa.Ordinärer_String.FixL("Zeichenfolge, aber zu lang", StrucTest.Length) ' Eine Klassen-Instanz muss zunächst initialisiert werden aaa.Fixed_String = New VB6.FixedLengthString(StrucTest.Length) aaa.Fixed_String.Value = "netter String, aber zu lang" ' Zuweisung auf eine zweite Instanz der Struktur Dim bbb As StrucTest bbb = aaa ' Neuzuweisung einer Zeichenfolge auf 'bbb'-Member ' Bei einer einfachen Stringvariable wird die ' Referenz auf 'aaa'-Member bei Neuzuweisung aufgelöst bbb.Ordinärer_String.FixL("neue Zeichen", StrucTest.Length) ' Da FixedStringLength eine Klasse ist, ' handelt es sich um eine Referenz ' (---> 'aaa'-Member wird ebenfalls geändert) bbb.Fixed_String.Value = "neue Zeichen" End Sub