Die Val-Funktion (in 'Microsoft.VisualBasic.Conversion') wandelt einen (Teil-) String in einen 'Double'-Wert, bzw. ein Einzelzeichen in einen Integer um. Obwohl es sich dabei um eine "klassische" Basic-Funktion handelt, ist ihr Gebrauch aufgrund des sehr speziellen Verhaltens KAUM ZU EMPFEHLEN. Bevorzugen sie die 'TryParse'-Methode, die bei den numerischen Datentypen enthalten ist, oder greifen Sie auf die Methoden von 'System.Convert' zurück. Die grundsätzlichen Unterschiede zu 'Val' besteht darin, dass die 'Numerics' aufgrund kulturspezifischer Kennungen gebildet werden und dass immer der gesamte String einbezogen wird. Die VB-Dokumentation der 'Val'-Funktion ist unvollständig, so dass es zu Mißverständnissen und in der Folge zu Fehlanwendungen kommen kann. Deshalb hier eine Übersicht über wichtige Eigenarten der Arbeitsweise von 'Val': Bei String-Parametern gilt:
Im einzelnen: Obwohl 'Val' unter bestimmten Bedingungen Ausnahmen auslöst, tut sie das in wichtigen Fällen nicht. Die Val-Funktion erkennt kulturspezifische Zeichen nicht und wertet sie deshalb als Abbruchkennung. Auch das in Deutschland übliche Dezimaltrennzeichen ',' wird von der 'Val'-Funktion als Abbruchkennung identifiziert. Die Strings zur Identifikation von IEEE-Sonderwerten (z. B. "n. def.") sind ebenfalls kulturspezifisch und werden deshalb von der 'Val'-Funktion nicht erkannt. Numerische Werte werden nach starren Regeln gebildet:
Wenn dem Exponent-Identifizierer kein gültiger numerischer Teilstring folgt, dient er als AbbruchKennung. Der Code Val("123E-W") liefert deshalb 123,0#. Ein Exponent-Überlauf führt aber zu einer Overflow-Exception. Im Exponentteil wird das Dezimaltrennzeichen ggf. als Abbruchkennung identifiziert. Der Aufruf Val("123E3.5") ergibt 123000.0#. Im 'visuellen' Basic sonst ungewohnt, wird als Exponentialdarstellung auch das Zeichen 'D' identifiziert. Die Konvertierung und Verarbeitung erfolgt immer im Datentyp 'Double'; das bedeutet auch, dass diese Zeichen im Ergebnis keine Exponentialdarstellung erzwingen können. Bei der Wiederholung eines der Numeric-Kenner im Parameter-String wird das zweite Auftreten als Abbruchkennung gewertet. Die oben genannten VB-Datentyp-Identifizierer werden von der 'Val'-Funktion ausgewertet, dienen aber zugleich als Abbruchkennung. Identifizierer können bei falscher Verwendung zur Auslösung von Ausnahmen führen:
Der Code Val("2.5123456789123!") wirft keine Ausnahme, führt aber ein Parsen im Datentyp 'Single' durch. Das Ergebnis wird dann in einen 'Double'-Wert konvertiert (Rückgabe: 2.5123457908630371 - nur 8 gültige Stellen!!). Der String "1E60!" führt deshalb zur Rückgabe des IEEE-Sonderwertes 'PositiveInfinity'. Die Literalzeichen für Datentypen (z.B. "D" oder "UL") werden nicht identifiziert, sondern wirken als Abbruchkennung. Obwohl die Funktion 'Double' zurückgibt, akzeptiert sie oktale und hexadezimale Zeichen, denen ein entsprechender Identifizierer vorangestellt ist. Der Code Val("&HFFF") liefert 4095.0# und entspricht somit der Rückgabe von CDbl(Convert.ToInt32("FFF", 16)). Der Code Val("&O111") ergibt 73.0# => CDbl(Convert.ToInt32("111", 8). Die Funktion akzeptiert als Eingabe nicht nur eine Stringvariable, sondern einen beliebigen Ausdruck (der freilich eine numerisch interpretierbare Zeichenfolge ERGEBEN muss.) Es ist z.B. nicht möglich, eine StringBuilder-Variable direkt als Argument zu verwenden - die Methode 'ToString' ist erforderlich. Der Code Val(1 + 7) ergibt - als Ergebnis eines Ausdrucks - 8.0#. Der Code Val("1+7") liefert 1.0#, weil innerhalb eines String das Additionszeichen als Abbruchkennung dient. Wenn der Nachkomma-Anteil in einem numerischen String zu 'lang' für 'Double' ist (Ziffernfolge), wird der Rest-String ignoriert. Wie viele Ziffern einbezogen werden, hängt von der jeweiligen Größe des Vorkomma-Wertes ab. Das Ignorieren von Tabulatoren und Zeilentrennern ist als besonders problematisch einzustufen. Der Code Val("12345." & vbTab & "678") liefert den Wert 12345,678. Beim Einlesen von Strings aus einer Datei ist Vorsicht geboten. In den aktuellen VB-Versionen gibt es die sogenannten 'White-Space'-Zeichen ('Leerraumzeichen'), die z.B. in der Dokumentation der Methode 'String.Trim' aufgelistet sind. Eine erweiterte Liste steht bei der Methode 'Char.IsWhiteSpace'. Dort findet sich auch der Verweis auf die 'UniCode'-Zeichenkategorien. (Der in der deutschen VB-Dokumentation verwendete Begriff 'Leerraumzeichen' ist irreführend. Es handelt sich um Zeichen, die bei bestimmten Funktionen als Identifizierer für spezielle Bearbeitungen - Separatoren, Vorschübe u.a. - interpretiert werden.) 'Val' eliminiert NUR einige der in BASIC ('Namespace: Microsoft.VisualBasic') definierten 'White-Space'-Zeichen: Leerzeichen (vBEmpty), Tabulator (vbTab), Zeilenvorschub (vbLf, vbNewLine) und Wagenrücklauf (vbCR). Andere in BASIC definierte Sonderzeichen werden von 'Val' NICHT entfernt, z.B. 'vbBack', 'vbFormFeed'. Diese Zeichen-Codes stammen noch aus der Zeit vor UNICODE. Die ersten 128 UNICODE-Zeichen entsprechen aber den ersten 128 ASCII-Zeichen. Vor den Aufruf von 'Val' sollte man im Einzelfall folgende Zeichenersetzungen in Erwägung ziehen: Dim Str as String = "irgendein numerischer String" Str.Trim ' White-Spaces am Anfang und Ende des Strings entfernen Str.Replace(",", ".") ' kulturspezifischer Dezimalpunkt --> Standard-Dezimalpunkt Str.Replace(vbCr, "X") ' Zeilen-Zusammenfassung vermeiden Str.Replace(vBLf, "X") Str.Replace(vbTab, "X") ' Feld-Zusammenfassung vermeiden Str.Replace(" ", "X") ' Leerzeichen als Abbruchkennung identifizierbar machen Str.Replace("%", "X") ' Short-Überlauf verhindern Str.Replace("&", "X") ' Integer-Überlauf verhindern Str.Replace("@", "X") ' Decimal-Überlauf verhindern Str.Replace("!", "X") ' Single-Überlauf verhindern Das nicht-numerische Zeichen "X" dient dabei als Abbruchkennung. Beachten Sie aber, dass sich durch die Ersetzung des Datentyp-Identifizierers der Parse-Vorgang ändert - er wird dann als 'Double' vorgenommen - so dass ein unterschiedliches Resultat zustande kommen kann: Val("2.5123456789123!") --> 2.5123457908630371 ' Single-Parser Val("2.5123456789123X") --> 2.5123456789123 ' Double-Parser Falls die kulturspezifischen 'Signs' vom Standard abweichen sollten, ist ebenfalls eine Ersetzung erforderlich. Um alle 'White-Space'-Character innerhalb des String zu entfernen (meist nicht empfehlenswert!) müssen Sie den String zunächst zeichenweise durch die Methode 'Char.IsWhiteSpace' analysieren. Als eine 'Umkehrfunktion' von 'Val' kann 'Str' eingestuft werden. Auch diese Routine arbeitet nicht mit den kulturspezifischen Zeichen. Es handelt sich bei beiden Funktionen um 'Überbleibsel' aus den Anfängen von BASIC. Hinweis für VB6-Umsteiger: Obwohl die 'Val'-Funktion dem klassischen BASIC entstammt, hat sie ihr Verhalten den Framework-Eigenarten anpassen müssen. Ausdrücke, die in VB6 zu einer Überlauf-Ausnahme führen - Val(199 / 0) - ergeben in VB2008 einen IEEE-Sonderwert. In VB6 ignoriert 'Val' den Typ-Identifizierer 'Single', parst immer im Datentyp 'Double'. Die oben angegebene Unterscheidung zwischen Single- und Double-Parser gibt es nicht. In VB6 akzeptiert 'Val' beim Datentyp-Identifizierer für 'Decimal' nur Ganzzahlen und löst sonst eine Ausnahme aus. Der Code Val("1.11111111@") liefert in VB2800 den Wert '1.11111111'. Bitte beachten Sie, dass ich die Unterschiede nur grob untersucht habe. Weitere Abweichungen sind durchaus möglich. Dieser Tipp wurde bereits 15.665 mal aufgerufen. Voriger Tipp | Zufälliger Tipp | Nächster Tipp
Anzeige
Diesen und auch alle anderen Tipps & Tricks finden Sie auch auf unserer aktuellen vb@rchiv Vol.6 Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv! - nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten - Symbol-Galerie mit mehr als 3.200 Icons im modernen Look Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m. |
vb@rchiv CD Vol.6 Geballtes Wissen aus mehr als 8 Jahren vb@rchiv! Online-Update-Funktion Entwickler-Vollversionen u.v.m. Tipp des Monats September 2024 Dieter Otter Übergabeparameter: String oder Array? Mit der IsArray-Funktion lässt sich prüfen, ob es sich bei einem Übergabeparameter an eine Prozedur um ein Array oder einer "einfachen" Variable handelt. Neu! sevEingabe 3.0 Einfach stark! Ein einziges Eingabe-Control für alle benötigten Eingabetypen und -formate, inkl. Kalender-, Taschenrechner und Floskelfunktion, mehrspaltige ComboBox mit DB-Anbindung, ImageComboBox u.v.m. |
||||||||||||||||
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein. |