Übersicht
0001 Deklarieren - aber richtig!
Ja, ja - ein altes Thema! Und dennoch: es gibt immer noch genügend Leute, die die Syntax der Variabeln-Deklaration nicht richtig verstanden haben: Beispiel: es sollen 3 Variabeln vom Typ String deklariert werden. Richtig: Dim a as String, b as String, c as String Falsch: Dim a, b, c as String In der Falsch-Variante werden die Variabeln a und b nicht als String-Werte sondern als Variant im Speicher angelegt. Die Anweisung Option Explicit am Anfang eines Moduls hilft da auch nicht weiter. Dadurch wird lediglich sichergestellt, dass die Variabeln deklariert sein müssen; eine Typenprüfung bei deren Benutzung findet aber nicht statt! | |
Autor: ralf schlegel |
0002 Immer ein gültiger String
Die folgende simple Funktion gibt immer einen "sicheren" String zurück und verhindert so Laufzeitfehler bei zum Beispiel noch nicht initialisierten Datenbankfeldern und leeren Variablen aus API-Rückgaben: ' Funktion: Public Function asString(ByVal s As Variant) As String On Local Error Resume Next If IsNull(s) Or IsEmpty(s) Then asString = "" Else asString = RTrim$(CStr(s)) End If End Function ' Aufrufbeispiel: myString = asString(Data1.Recordset!FeldName) | |
Autor: ralf schlegel |
0003 Speed it up mit $
Standard Stringfunktionen, wie Mid$, Left$ und Right$ lassen sich heute auch ohne das Dollar-Zeichen im Quelltext eingeben. Das sieht vielleicht schöner aus, ist aber langsamer: die Funktion Left$("C:\Windows", 2) liefert einen Rückgabewert vom Typ String während Left("C:\Windows", 2) den speicherfressenden Typ Variant zurückgibt, der bei Zuweisung auf eine String-Variabel erst wieder konvertiert werden muß. Das kostet unnötig Zeit und Speicherplatz - erst recht, wenn Funktionen wie Mid(...) in Schleifen benutzt werden. Hier eine Auflistung aller VB-Funktionen die mit $ genutzt werden sollten:
Erweiterung von Rudolf Wahlbrinck (11/2009): Bei den internen Konstanten gibt es auch die allgemeine (Variant) und die String-Version, also: vbCrLf$, vbCr$, vbLf$, vbNewLine$, vbTab$, vbBack$, vbFormFeed$ | |
Autor: ralf schlegel |
0004 Leer-String oder Null-String?
Was ist eigentlich der Unterschied zwischen einem leeren String (myString = "") und einem Nullstring (myString = vbNullString)? Nun - einfach gesagt erst einmal 6 Byte! Denn genau die werden durch myString = "" im Speicher belegt, wohingegen die Konstantenzuweisung myString = vbNullString den String im Speicher tatsächlich löscht. Vielleicht kennen Sie das aus der C-Programmierung ('\0'). Abgesehen von der Speicherbelegung kann VB diese Zuweisung auch schneller verarbeiten. Wenn Sie viel mit solchen Stringausdrücken in Ihrer Anwendung arbeiten, kann sich das durchaus bemerkbar machen. Am Besten gewöhnen Sie sich die vbNullString-Variante generell an, einen Unterschied im Programmhandling gibt es eigentlich nicht - einzige Ausnahme: einige wenige nicht VB-konforme API-Aufrufe unterstützen den NullString nicht! Sollte es also bei der Übergabe an solche Funktionen einmal zu einem Absturz kommen, so versuchen Sie es mit "" - aber bitte nur dann... | |
Autor: ralf schlegel |
0005 Nur Zahleneingabe zulassen
Ein Texteingabefeld auf die Eingabe von Zahlen zu beschränken läßt sich sehr einfach und übersichtlich mit einer Select Case Anweisung realisieren. Dazu schreiben wir folgende allgemeingültige Funktion in ein Basic-Modul (*.bas): ' Funktion: Public Function numKeys(ByVal KeyAscii As Integer) numKeys = KeyAscii Select Case KeyAscii Case 8 ' Backspace Case 48 To 57 ' Zahlen 0-9 Case Else ' sonst... numKeys = 0 ' ...löschen End Select End Function In der TextBox eines Formulars rufen Sie diese Funktion dann im KeyPress Ereignis auf. Ein Beispiel für die TextBox mit dem Namen txtFon: ' Aufrufbeispiel: Private Sub txtFon_KeyPress(KeyAscii As Integer) KeyAscii = numKeys(KeyAscii) End Sub Das Ganze läßt sich nun beliebig abwandeln: brauchen Sie ein Eingabefeld für Telefonnummern, so möchten Sie vielleicht noch das Leerzeichen (ASCII 32) und den Bindestrich (ASCII 45) zulassen. Dazu kopieren Sie die obige Funktion und benennen Sie nach z.B. "telKeys" um. Vergessen Sie nicht auch innerhalb der neuen Funktion den Ausdruck numKeys durch telKeys zu ersetzen! Fügen Sie in den Select Case Abschnitt 2 Zeilen hinzu: Case 32 Case 45 nun werden auch diese Zeichen akzeptiert. Das sollte als Anregung reichen, programmieren wollen Sie ja schließlich selber... | |
Autor: ralf schlegel |
0006 Mid$ als Zuweisung nutzen
Mit der Funktion Mid$ holt der Programmierer in der Regel einen Teil einer Zeichenkette ab, um mit den ermittelten Werten weiter zu arbeiten. Was viele nicht wissen: Mid$ kann auch als Zuweisung genutzt werden!... Wir wollen in einem String einen Teilausdruck austauschen. Das machen wir dann normalerweise in folgender Form myString = "Hallo" p = InStr(1, myString, "ll") If p > 0 Then ' gefundene Buchstaben austauschen: myString = Left$(myString, p - 1) & "ik" & Mid$(myString, p + 2) Debug.Print myString End If Wesentlich effektiver geht es allerdings durch eine Zuweisung: myString = "Hallo" p = InStr(1, myString, "ll") If p > 0 Then ' Austausch in Kurzform: Mid$(myString, p, 2) = "ik" Debug.Print myString End If Was auf den ersten Blick wie eine nachgemachte Replace-Funktion aussieht, bietet tatsächlich ganz neue Möglichkeiten: denn der 3. Parameter der Mid$-Funktion bestimmt definitiv die Länge! D.h.: wird im obigen Beispiel statt dem konstanten Ausdruck "ik" eine Stringvariable übergeben, die zur Laufzeit unterschiedliche Werte hat, so werden immer nur 2 Zeichen an der Position p ausgetausch, auch wenn der zugewiesene String länger ist! | |
Autor: ralf schlegel |
0007 Initialisierung eines dynamischen Byte-Arrays abfragen
Um größere Datenmengen temporär in den Speicher zu laden bietet sich der Einsatz eines dynamischen Byte-Arrays an, das wie folgt deklariert wird: Dim myByteArray()As Byte Bevor wir nun diese Byte Array füllen können ermitteln wir in unserer Anwendung den benötigten Speicherplatz in Byte und redimensionieren das Array entsprechend. Erst dann ist das Array initialisiert! Das sieht dann z.B. zum Einlesen einer Datei so aus: Dim bytes As Long bytes = FileLen("C:\MyFile.txt") ReDim myByteArry(bytes) Nun können wir die Datei mit einem Rutsch in das Byte-Array einlesen und damit arbeiten, es mit ReDim redimensionieren, mit ReDim Preserve redimensionieren ohne den Inhalt zu verlieren, oder mit dem Befehl Erase myByteArray wieder aus dem Speicher entfernen. Was wir auf den ersten Blick nicht können, ist abzufragen, ob das Array nach der Deklaration bereits initialisiert - also wenigstens einmal mittels ReDim auf eine Größe festgelegt - wurde. Abhilfe schafft hier die Funktion StrPtr, der wir die Variable myByteArray übergeben. Diese Funktion liefert "0" zurück, wenn das Array noch nicht initialisiert, oder durch Erase zerstört wurde, anderenfalls einen Wert ungleich "0": If StrPtr(myByteArray) Then Erase myByteArray() Bevor wir also ins Nichts greifen und einen Runtime-Error erzeugen, fragen wir die Initialisierung mit StrPtr ab, das erspart uns eine "On Error Behandlung" und macht unseren Code übersichtlicher und schneller! | |
Autor: ralf schlegel |
0008 NullTrim einmal anders
Um die lästigen Nullzeichen in einem String zu entfernen haben wir in der Regel eine kleine Funktion mit Namen NullTrim oder ähnlich in unserem Programmcode. Diese Funktion entfernt die eventuell vorhandenen Nullzeichen am Ende eines Strings und gibt diesen bereinigt zurück. Sicher kennen Sie diese Funktion, die i.d.R. folgendemaßen aussieht: ' Entfernt die lästigen Null-Bytes, die von diversen ' API-Funktionen bei Stringrückgaben übergeben werden: Public Function NullTrim(ByVal s As String) As String Dim p As Long p = InStr(s, vbNullChar) If p > 0 Then NullTrim = Left$(s, p - 1) Else NullTrim = s End If End Function Erhalten wir nun aus einem API-Aufruf einen String zurück, so wird dieser in der Regel folgendermaßen bereinigt: retString = NullTrim(retString) Diese Funktion ist allerdings gar nicht nötig, da wir das auch mit einem internen VBA Befehl als Einzeiler lösen können: retString = Split(retString & vbNullChar, vbNullChar, 2)(0) Mit dem Parameter '2' im Split-Audruck sorgen wir dafür, dass die Funktion nach maximal 2 gefundenen Elementen zurückkehrt und nicht sinnlos eine eventuelle Kette von Nullbytes am Ende des Strings zerlegt! Enthält der übergeben String keine Nullzeichen, so wird dennoch ein Element durch die Funktion Split angelegt, das dem übergebenen String entspricht. - Eine absolut sichere Sache, nicht wahr? Autor: ralf schlegel |