VBA - Tipps und Tricks für Scripting und Unicodes
Scripting ist äußerst beliebt bei der Problemlösung, auch in Office. So erzeugen Sie mit VBA eindeutige Werte und bekommen lesbare Zeichen mit Unicode.

Mit Visual Basic For Applications, kurz VBA, sind wahrscheinlich sehr viele IT-Profis eine Art Hassliebe eingegangen. Seit den 1990er-Jahren bietet Microsoft mit VBA im Office-Umfeld eine stabile Entwicklungs- und Makro-Umgebung, von dem kleinen Aussetzer in der Office-Version 2008 für Mac OS e...
Mit Visual Basic For Applications, kurz VBA, sind wahrscheinlich sehr viele IT-Profis eine Art Hassliebe eingegangen. Seit den 1990er-Jahren bietet Microsoft mit VBA im Office-Umfeld eine stabile Entwicklungs- und Makro-Umgebung, von dem kleinen Aussetzer in der Office-Version 2008 für Mac OS einmal abgesehen. Während sich jedoch die anderen Sprachen mit dem Namenszusatz Visual über die Jahre weiterentwickelt haben, verbleibt VBA in seinem bekannten Status. Mit einigen Tricks und Kniffen holt der VBA-Programmierer noch mehr aus dem alten Programmierdinosaurier heraus.

Eindeutigkeit per GUID
Es gibt, insbesondere für die Programmierung eigener Lösungen, manchmal die Notwendigkeit, einen absolut eindeutigen Wert zu ermitteln, der auf keinen Fall ein zweites Mal erzeugt werden darf. Ein Beispiel, welches in der Literatur oft angeführt wird, ist das Anlegen einer eindeutigen Kundennummer. An sich ja ganz einfach, man möge doch einfach nur die Nummerntabelle für die Kundendaten in der Datenbank um einen Zähler inkrementieren, und schon hat man seine nächste Kundennummer. Das funktioniert jedoch nur, sofern im Moment der Erstellung des Datensatzes auch eine Verbindung zur Datenbank selbst besteht. Wenn aber ein Außendienstmitarbeiter an seinem Laptop eine neue Nummer generieren will, ohne dass eine Verbindung zum Firmennetzwerk besteht, wäre dies nicht möglich. Anstelle von Kundennummern könnte es sich bei dem Beispiel auch um Dokumenten-Nummern oder Transaktions- IDs handeln. Egal, was der Entwickler mit der ID auch anstellen möchte, sie muss in jedem Fall eindeutig sein.
Als Grundlage zur Kalkulation eines solchen Wertes eignen sich Uhrzeit, Laufzeit oder die MAC-Adresse der Netzwerkkarte, die ja, zumindest der grauen Theorie nach, stets eindeutig sein sollte. Ein Blick in die Windows-Registry zeigt, dass es eine sehr große Anzahl solcher GUIDs (Globally Unique Identifier) pro Installation gibt. Glücklicherweise muss sich der VBAProgrammierer mit den theoretischen Grundlagen bei der Erzeugung eines GUID kaum auseinandersetzen, sofern er über die passende Windows-API-Funktion vorgeht. Bei der Erzeugung einer GUID mithilfe der API-Funktion CoCreateGuid ist, so Microsoft, wirklich sichergestellt, dass es diese GUID nur ein einziges Mal gibt. Die 16-Byte lange Zahl wird über die Netzwerkkarten- MAC erzeugt und selbst wenn der Anwender über mehrere Jahre mit ein und derselben Netzwerkkarte versucht, GUIDs zu erzeugen, so kommt es zu keiner doppelten Zahl. Eingebunden in eine Microsoft Excel-Datei mit einer Schaltfläche Schaltfläche1 ergibt sich folgender Code:
Private Declare Function CoCreateGuid _ Lib "OLE32.DLL" _ (lpGUID As Long) _ As Long Private Declare Function StringFromGUID2 _ Lib "OLE32.DLL" _ (lpGUID As Long, ByVal _ lpszSTring As Long, ByVal lMax As Long) _ As Long Sub Schaltfläche1_Klicken() For a = 1 To 30 For b = 1 To 6 Cells(a, b).Value = ErzeugeGUID Next Next End Sub Public Function ErzeugeGUID() As String Dim lngGUID(1 To 1) As Long CoCreateGuid lngGUID(1) ErzeugeGUID = String(38, 0) StringFromGUID2 lngGUID(1), _ StrPtr(ErzeugeGUID), 39 End Function

Unicode-Dateien
Wer einmal auf Wikipedia den Begriff Unicode nachschlägt, der wird sich über die Erklärung rund um die Aufgabe "dass langfristig für jedes sinntragende Schriftzeichen oder Textelement aller bekannten Schriftkulturen und Zeichensysteme ein digitaler Code festgelegt wird" freuen. Derzeit stellt sich das mit den sinntragenden Schriftzeichen eher in derForm dar, dass aus einer an sich lesbaren Datei plötzlich nur Kauderwelsch entnommen werden kann. Da helfen die im Moment definierten 110.182 Zeichen in der Version 6.2 von Unicode auch nicht wirklich weiter. Im Jahre 1988 war Joseph D. Becker von Xerox noch der Meinung, man könne mit einer 16-Bit-Zeichensatzcodierung mit 16.384 möglichen Zeichen problemlos alle Schriftzeichen der Welt codieren, da hatte er sich wohl verschätzt.
Wer bisher Text-Dateien über OpenTextFile im File- SystemObject in dieser Form geöffnet hat:
option explicitdim objSHELL, objFSO, objOTX, strFILENAME, strDATA strFILENAME = "{PFAD-DATEINAME}" set objSHELL = CreateObject("WScript.Shell") set objFSO = CreateObject _ ("Scripting.FileSystemObject") set objOTX = objFSO. OpenTextFile(strFILENAME,1,0) strDATA = objOTX.ReadAll msgbox(strData)
... dem werden in der Msgbox lediglich kryptischeZeichen dargestellt, anstelle eines brauchbaren Texts, sobald es sich um eine Unicode-Datei handelt. Im UNICODE-Umfeld, mit Dateien für alle erdenklichen Schriftzeichen, auch für historische und nicht mehr verwendete Sprachen, funktioniert das Öffnen über die herkömmliche ASCII-Variante nichtmehr fehlerfrei. Durch eine kleine Anpassung des Skripts, welches auch direkt als VBS-Datei unverändert genutzt werden kann, öffnet der IT-Profi auch UTF-16-Dateien. Bei UTF16 handelt es sich um das älteste und gleichzeitig am verbreitetste Unicode- Codierungsformat.
option explicitDim objSTREAM, strDATA, strFILENAME strFILENAME = "{PFAD-DATEINAME}" Set objSTREAM = CreateObject("ADODB.Stream") objSTREAM.CharSet = "utf-16" objSTREAM.Open objSTREAM.LoadFromFile(strFILENAME) strDATA = objStream.ReadText() msgbox(strDATA)
Aufgrund der Struktur von UTF-16 kommt es zu einem sehr interessanten Phänomen. Wird ein UTF-16-codierter Text als ASCII interpretiert, sind lateinische Buchstaben zwar erkennbar, aber durch Null-Bytes getrennt. Faktisch kommt es in unserem Schriftzeichen-Raum zu einer Verdoppelung des benötigten Speicherplatzes.
Doch wie kann man überhaupt herausfinden, in welcher Codierung eine Datei vorliegt? Es gibt im Internet eine große Anzahl von Diskussionsforen, wie Programme sicher feststellen können, ob es sich um eine Unicode-Codierung oder um eine ASCII-Datei handelt. Die gebräuchlichste Variante ist die Prüfungder ersten drei Bytes einer Datei, auch wenn diese Form nicht mit absoluter Sicherheit eine Unicode-Datei identifiziert. In unseren Prüfungen hat es stets funktioniert.
Function TestFile(ByVal path As String) As String Dim strBuffer As String Dim InFileNum As Integer Dim byteOne As Integer Dim byteTwo As Integer Dim byteThree As Integer strBuffer = String(100, " ") InFileNum = FreeFile Open path For Binary Access Read Lock Read As _ InFileNum Get InFileNum, , strBuffer Close InFileNum byteOne = Asc(Mid(strBuffer, 1, 1)) byteTwo = Asc(Mid(strBuffer, 2, 1)) byteThree = Asc(Mid(strBuffer, 3, 1)) If (byteOne = 255 And byteTwo = 254) Then TestFile = "Unicode" ElseIf (byteOne = 254 And byteTwo = 255) Then TestFile = "Unicode" ElseIf (byteOne = 239 And byteTwo = 187 And byteThree = 191) Then TestFile = "Unicode" Else TestFile = "AscII" End If End Function
Wir haben alle drei Kommandos, die Funktion TestFile wird in der Form MsgBox (TestFile({Pfad und Name})) aufgerufen, in eine Microsoft Excel-Datei eingebunden. Diese finden Sie im Internet zum Download unter PC Magazin Professional. Das erspart das Abtippen. Wer in VBA, etwa in Excel, Dateien weiterinterpretieren soll, wird über diese drei Skripte sicherstellen, dass die Textdateien, unabhängig von ihrer Codierung, stets korrekt geöffnet werden.
