Zur Hauptseite ... Zum Onlinearchiv ... Zum Abonnement ... Zum Newsletter ... Zu den Tools ... Zum Impressum ... Zum Login ...

Gedrucktes Heft

Diesen Beitrag finden Sie in Ausgabe 6/2014.

Unser Angebot für Sie!

Lesen Sie diesen Beitrag und 500 andere sofort im Onlinearchiv, und erhalten Sie alle zwei Monate brandheißes Access-Know-how auf 72 gedruckten Seiten! Plus attraktive Präsente, zum Beispiel das bald erscheinende Buch 'Access 2010 - Das Grundlagenbuch für Entwickler'!

Diesen Beitrag twittern

VBA unter Access mit 64 Bit

Die 64bit-Version von Access sollten Sie schon deshalb nicht nutzen, weil diese ActiveX-Steuerelemente wie das TreeView-, das ListView- oder das ImageList-Steuerelement nicht unterstützt. Aber es gibt noch weitere Gründe: Zum Beispiel könnte es Probleme bei der Verwendung von API-Funktionen geben. Manchmal bleibt einem Entwickler allerdings keine anderen Möglichkeit, weil etwa am Arbeitsplatz nur die 64bit-Version vorliegt oder aber der Kunde mit dieser Version arbeiten muss. Der vorliegende Beitrag liefert Informationen, wie Sie nicht kompatible VBA-Anweisungen für die Zielversion anpassen müssen und wie Sie programmieren müssen, um die 32bit- und die 64bit-Version gleichermaßen zu bedienen.

Unterschiede zwischen 32bit- und 64bit-Version

Warum entsteht das in der Einleitung beschriebene Dilemma überhaupt und was ist mit 32bit-Version und 64bit-Version überhaupt gemeint?

Hierbei beziehen wir uns zunächst auf das Betriebssystem. Wenn Sie ein 32bit-Betriebssystem nutzen, kann dieses maximal 2 hoch 32 Bytes Arbeitsspeicher adressieren, also ca. 4.096 Megabyte. Bei einem 64bit-Betriebssystem kann ein Arbeitsspeicher von 2 hoch 64 Byte adressiert werden – dies wird noch eine Weile ausreichen.

Wer also mehr als vier Gigabyte Arbeitsspeicher in seinem Rechner verbaut hat und sich wundert, dass davon nur vier angezeigt werden, fährt also vermutlich noch ein 32bit-Betriebssystem.

Möchten Sie herausfinden, wie viel Arbeitsspeicher Sie nutzen und ob Sie ein 32bit- oder ein 64bit-Betriebssystem nutzen, können Sie dies über die Systemsteuerung ermitteln. Unter Windows 7 etwa klicken Sie dazu auf Start|Systemsteuerung und dann auf System. Es erscheint der Dialog aus Bild 1, dem Sie die notwendigen Informationen entnehmen können. In diesem Fall handelt es sich um ein 64bit-System mit acht Gigabyte Arbeitsspeicher.

Hinweise auf Arbeitsspeicher und Betriebssystem in den Systemeinstellungen von Windows

Bild 1: Hinweise auf Arbeitsspeicher und Betriebssystem in den Systemeinstellungen von Windows

Office mit 32bit und 64bit

Damit kommen wir zum Thema Office und somit auch zu Access. Access 2010 etwa wird standardmäßig in der 32bit-Variante installiert.

Wer die 64bit-Variante wünscht, muss dies explizit bei der Installation angeben. Warum das? Weil es sehr viele externe Tools und Steuerelemente für Access in der 32bit-Version gibt. Würden Sie Access in der 64bit-Version installieren und versuchen, ein mit der 32bit-Version etwa von VB6 entwickeltes Add-In zu starten, führt dies zu einem Fehler.

Das Gleiche gilt, wenn Sie etwa ein 32bit-ActiveX-Steuerelement wie das TreeView-Steuer­element verwenden möchten – mehr dazu weiter unten.

Einfache Lösung

Wenn Sie eine neue Office-Version in­stallieren, können Sie diese und anderen Probleme auf einfache Art und Weise umschiffen: Installieren Sie einfach die 32bit-Variante. Windows in der 64bit-Variante bietet eine Kompatibilitätsumgebung namens WOW64, mit der Sie 32bit-Anwendungen wie in diesem Fall Office und Access ganz normal ausführen können.

In diesem Fall wird Office nicht in dem dafür vorgesehenen Verzeichnis C:\Program Files\Microsoft Office\Office15 installiert, sondern etwa unter C:\Program Files (x86)\Microsoft Office\Office15.

Probleme mit ActiveX-Steuerelementen

Das vermutlich kritisch­ste Problem, das bei der Nutzung von Access in der 64bit-Version auftaucht, sind ActiveX-Steuerelemente, die nur in der 32bit-Version verfügbar sind.

Wir haben testweise eine frische Datenbank unter der 32bit-Version mit einem TreeView-Steuerelement versehen. Wenn Sie diese Datenbank unter Access in der 64bit-Version öffnen, löst dies zunächst die Meldung aus Bild 2 aus.

Der Verweis auf die Datei MSCOMCTL.ocx kann unter Access in der 64bit-Version nicht gefunden werden.

Bild 2: Der Verweis auf die Datei MSCOMCTL.ocx kann unter Access in der 64bit-Version nicht gefunden werden.

Wenn Sie diese Meldung ignorieren und dann das Formular mit dem TreeView-Steuerelement öffnen, erhalten Sie die Meldung aus Bild 3.

Der Container mit dem TreeView-Steuerelement ist leer.

Bild 3: Der Container mit dem TreeView-Steuerelement ist leer.

Was tun? Nun: Es gibt keine 64bit-Version dieses Steuerelements, also können Sie nur zur 32bit-Version von Access wechseln oder eine Alternative für das TreeView-Steuerelement suchen.

Probleme mit mde/accde

Wenn Sie eine .mde- oder .accde-Datei unter Access in der 32bit-Version erzeugt haben, können Sie diese nur mit der entsprechenden Access-Version öffnen. Wenn Sie etwa eine 32bit-accde-Datei unter Access in der 64bit-Version öffnen, erhalten Sie die Fehlermeldung aus Bild 4. In diesem Fall besteht Hoffnung: Wenn Sie Zugriff auf die unkompilierte Version der Datenbankdatei haben, können Sie diese unter der 64bit-Version von Access kompilieren und die .mde/.accde-Datei dann unter Access in der 64bit-Version nutzen.

Fehler beim Öffnen einer .mde- oder .accde-Datei, die mit Access in der 32bit-Version erstellt wurde

Bild 4: Fehler beim Öffnen einer .mde- oder .accde-Datei, die mit Access in der 32bit-Version erstellt wurde

Probleme mit API-Deklarationen

Ein weiteres Problem tritt auf, wenn Sie API-Funktionen, die mit der 32bit-Version von Access funktionieren, unter der 64bit-Version einsetzen möchten. Wir schauen uns dazu die GDI-/OGL-Bibliothek von Sascha Trowitzsch an, die eine Menge API-Funktionen verwendet, und wollen diese für die 64bit-Version lauffähig machen.

Wenn Sie das Modul mdlOGL0710 unter Access 2013 in der 64bit-Version öffnen, erhalten Sie einige rot markierte Zeilen wie in Bild 5. Der erste Schritt, um die API-Deklarationen für die 64bit-Version nutzbar zu machen, liegt im Hinzufügen eines einfachen Schlüsselworts, und zwar PtrSafe. Dieses Schlüsselwort fügen Sie unmittelbar hinter der Declare-Anweisung der API-Funktion ein, sodass etwa die erste in der Abbildung sichtbare Funktion wie in Bild 6 aussieht.

Fehlerhafte API-Deklarationen

Bild 5: Fehlerhafte API-Deklarationen

Hinzufügen des Schlüsselworts PtrSafe

Bild 6: Hinzufügen des Schlüsselworts PtrSafe

Auf diese Weise statten Sie nun alle API-Funktionen mit diesem Schlüsselwort aus. Die Suchen/Ersetzen-Funktion des VBA-Editors ist dabei eine willkommene Erleichterung: Ersetzen Sie zunächst Declare Function durch Declare PtrSafe Function und dann Declare Sub durch Declare PtrSafe Sub – klicken Sie dabei jeweils auf Alle ersetzen (siehe Bild 7).

PtrSafe per Suchen/Ersetzen hinzufügen

Bild 7: PtrSafe per Suchen/Ersetzen hinzufügen

Sollten sich noch weitere nicht kompatible API-Deklarationen finden, können Sie diese durch Betätigen des Menübefehls Debuggen|Kompilieren von auffinden. Es erscheint dann die Meldung aus Bild 8.

Meldung, wenn beim Debuggen noch inkompatible API-Deklarationen gefunden werden

Bild 8: Meldung, wenn beim Debuggen noch inkompatible API-Deklarationen gefunden werden

Damit wären schon einmal die Probleme mit der Variablendeklaration behoben.

Probleme mit Variablentypen

Nach diesem Problem folgt auch gleich das nächste – wenn auch nicht offensichtlich. Dazu betätigen wir nochmals den Debuggen|Kompilieren von .

In unserem Beispiel meldet Access nun Fehler beim Kompilieren: Typen unverträglich und markiert einen Parameter der API-Funktion GdipCreateBitmapFromFile (siehe Bild 9). Hier wird offensichtlich eine Funktion namens StrPtr verwendet, um der Funktion die Adresse der Variablen sFileName zu übermitteln.

Datentyp-Fehler

Bild 9: Datentyp-Fehler

Was geht hier schief? Schauen wir uns die Funktion StrPtr an, indem wir das Kontextmenü zu diesem Befehl öffnen und den Eintrag Definition auswählen. Dies führt zunächst zur Fehlermeldung aus Bild 10.

Problem beim Anzeigen der Funktion StrPtr

Bild 10: Problem beim Anzeigen der Funktion StrPtr

Das ist aber kein Problem: Wir aktivieren im Objektkatalog mit einem Klick auf den Eintrag Verborgene Einträge anzeigen des Kontextmenüs die Anzeige der verborgenen Elemente.

Anschließend versuchen wir erneut, die Definition der Funktion StrPtr im Objektkatalog anzuzeigen. Diesmal gelingt es, wie Bild 11 zeigt. Hier erfahren wir dann, dass StrPtr einen Wert des Datentyps LongPtr zurückliefert. Damit schauen wir uns nun die Definition der API-Funktion an:

Anzeigen der Funktion StrPtr im Objektkatalog

Bild 11: Anzeigen der Funktion StrPtr im Objektkatalog

Private Declare PtrSafe Function GdipCreateBitmapFromFile_O Lib "ogl" Alias "GdipCreateBitmapFromFile" _
    (ByVal FileName As Long, bitmap As Long) As Long

Hier sehen wir nun, dass der erste Parameter nicht mit dem Datentyp LongPtr, sondern mit dem Datentyp Long definiert ist. Schauen wir uns den gleichen Code auf einem Rechner mit Office in der 32bit-Version an, so führt das Kompilieren dieser Definition der API-Funktion nicht zu einem Fehler – der LongPtr-Wert kann also wohl problemlos für den Long-Parameter angegeben werden.

Aber worum handelt es sich bei diesem LongPtr-Datentyp eigentlich? Er wurde mit VBA 7 eingeführt und nimmt wie der Long-Datentyp Ganzzahlen auf.

Der Datentyp Long unterstützt einen Wertebereich von -2.147.483.648 bis 2.147.483.647. Welchen Wertebereich der Datentyp LongPtr unterstützt, hängt von der Office-Version ab:

  • Unter Office 2010 und neuer in der 32bit-Version werden ebenfalls nur die Werte von -2.147.483.648 bis 2.147.483.647 unterstützt.
  • Unter Office 2010 und neuer in der 64bit-Version werden Zahlen eines wesentlicher höheren, annähernd 264 umfassenden Wertebereichs unterstützt.

Sprich: Bei Verwendung der 32bit-Version verwenden Long und LongPtr den gleichen Wertebereich. Deshalb gibt es auch in der 32bit-Version keinen Fehler, wenn Sie einer Long-Variablen einen Wert zuweisen, der durch die Funktion StrPtr ermittelt wurde.

In der 64bit-Version liegt dieser Fehler jedoch vor, weshalb wir schlicht und einfach den Datentyp der Parameter in den betreffenden API-Funktionen von Long in LongPtr ändern. Da dieser Datentyp auch unter VBA 7 in der 32bit-Version unterstützt wird, erhalten wir die volle Kompatibilität – vorausgesetzt, VBA 7 wird verwendet.

Damit gehen wir nun weiter und schauen, wo es noch Probleme gibt. Diese halten sich im Rahmen: Sie müssen im Beispielmodul lediglich noch hier und da den Datentyp Long durch LongPtr ersetzen, und zwar in API-Funktionen als auch in Type-Elementen.

Kompatibilität mit älteren VBA-Versionen

Wenn Sie eine Anwendung also durch Ersetzen des Datentyps Long durch LongPtr 64bit-fähig gemacht haben, können Sie diese unter Windows 7 (natürlich in der 64bit-Variante) unter Office in der 32bit- und in der 64bit-Version nutzen.

Was nun noch fehlt, ist die Prüfung der Abwärtskompatibilität. Wie sieht es aus, wenn wir den Code unter einer Office-Version nutzen wollen, die noch VBA 6 nutzt – was ja nicht 64bit-fähig ist? Dies prüfen wir, indem wir den betroffenen Code auf einem Rechner mit dem entsprechenden Office-Paket kompilieren und ausführen. Hier tritt dann gleich der Fehler aus Bild 12 auf – VBA erkennt den Befehl PtrSafe nicht.

Fehler beim Kompilieren unter Access 2003

Bild 12: Fehler beim Kompilieren unter Access 2003

Kein Wunder, denn wir verwenden ja hier auch die Version 6.0 von VBA (s. Bild 13).

Ermittlung der VBA-Version

Bild 13: Ermittlung der VBA-Version

Kompatibilität per Kompilierungskonstante

Was also können wir tun, damit der für die 64bit-Version von Access angepasste Code nun auch für ältere Versionen von VBA kompatibel ist? Dazu nutzen wir eine von zwei neuen Kompilierungskonstanten. Dabei handelt es sich um Konstanten, die für die bedingte Kompilierung genutzt werden – eine Möglichkeit, Codezeilen nur dann zu kompilieren, wenn eine bestimmte Bedingung eintritt.

Ein einfaches Beispiel sieht wie folgt aus – hier wird schlicht in Abhängigkeit der Kompilierungskonstante VBA7 ein entsprechender Ausdruck im Direktfenster ausgegeben:

Public Sub TestVBA7()
     #If vba7 Then
         Debug.Print "VBA7 wird genutzt."
     #Else
         Debug.Print _
             "VBA7 wird nicht genutzt."
     #End If
End Sub

Diese Kompilierungskonstante funktioniert nur in Anweisungen der bedingten Kompilierung, also mit #If...Then, #If...Then...Else, #Else und #End If.

Die #If...Then-Bedingung prüft den Wert der Kompilierkonstanten VBA7 und führt dann entweder den #If- oder den #Else-Teil der Bedingung aus.

In unserem Fall fügen wir dem If-Teil der Bedingung beispielsweise die API-Deklaration mit dem PtrSafe-Schlüsselwort hinzu, dem Else-Teil die gleiche API-Deklaration ohne das PtrSafe-Schlüsselwort (s. Listing 1).

#If vba7 Then
Private Declare PtrSafe Function OleCreatePictureIndirect Lib "oleaut32.dll" _
    (lpPictDesc As PICTDESC, riid As GUID, _
    ByVal fPictureOwnsHandle As Long, IPic As Object) As Long
#Else
Private Declare Function OleCreatePictureIndirect Lib "oleaut32.dll" _
    (lpPictDesc As PICTDESC, riid As GUID, _
    ByVal fPictureOwnsHandle As Long, IPic As Object) As Long
#End If

Listing 1: Verschiedene Deklarationen per bedingter Kompilierung

Auf die gleiche Art und Weise fassen wir die kompletten API-Deklarationen einmal in den If- und einmal in den Then-Teil ein, das Gleiche gilt für die übrigen unter VBA 6.0 nicht kompilierbaren Anweisungen, die Sie nachfolgend durch wiederholtes Kompilieren aufdecken.

Bei den API-Deklarationen müssen Sie bei der VBA 6.0-Variante natürlich auch noch die LongPtr-Parameter in Long-Parameter zurückverwandeln.

Die Beispieldatenbank VBA64.mdb enthält nun Code, der sowohl unter VBA 6.0 als auch unter VBA 7.0 in der 32bit- und der 64bit-Version funktioniert.

Unterschiede zwischen 32bit und 64bit

Es gibt noch weitere mögliche Unterschiede zwischen der 32bit- und der 64bit-Version von VBA. Während die bisher in diesem Beitrag vorgestellten Änderungen, die zur Sicherstellung der Kompilierbarkeit unter der 64bit-Version nötig waren, zur 32bit-Version abwärtskompatibel sind, gibt es auch noch solche, die unter der 32bit-Version nicht kompilierbar sind.

Allerdings halten sich diese Änderungen in Grenzen: Nach unseren Erkenntnissen handelt es sich allein um den Datentyp LongLong.

Dessen Wertebereich sollte eigentlich von -9.223.372.036.854.775.808 bis 9.223.372.036.854.775.807 reichen – also von -263 bis 263-1.

Für den bei der Erstellung der Beispiele zu diesem Beitrag verwendeten Rechner haben wir mit folgender Prozedur experimentell aber andere Werte ermittelt:

Public Sub TestLongLong()
     Dim lnglng As LongLong
     lnglng = Eval("-2^63-1024")
     Debug.Print "LongLong minimal: " _
         & lnglng
     lnglng = Eval("2^63-513")
     Debug.Print "LongLong maximal: " _
         & lnglng
End Sub

Das Ergebnis im Direktfenster sieht dann so aus:

LongLong minimal: -9223372036854775808
LongLong maximal: 9223372036854774784

Mit einigen Tausendertrennzeichen für die bessere Lesbarkeit ergibt dies einen Wertebereich von -9.223.372.036.854.775.808 bis 9.223.372.036.854.774.784.

Ob die aktuelle Office-Version nun im 32bit- oder im 64bit-Betrieb läuft, ermitteln Sie mit der Win64-Kompilierkon­stanten. Hier ein kleines Beispiel:

Public Sub Test64bit()
     #If Win64 Then
         Debug.Print "Win64"
     #Else
         Debug.Print "Anderes"
     #End If
End Sub

Nun können Sie aber keine Variablen deklarieren, die den Typ LongLong verwenden und auch dessen Wertebereich ausschöpfen und diese dann auch für Office in der 32bit-Variante zugänglich machen. Dies wird allerdings auch etwa von API-Funktionen berücksichtigt – wie etwa von der fiktiven Funktion MyMathFunction. Diese deklarieren Sie für größtmögliche Kompatibilität einfach wie in Listing 2.

#If Win64 Then
     Declare PtrSafe Function MyMathFunc Lib "user32" (ByVal N As LongLong) As LongLong
#Else
     Declare PtrSafe Function MyMathFunc Lib "user32" (ByVal N As Long) As Long
#End If

Listing 2: Deklaration einer API-Funktion für 64bit- und 32bit-VBA

Links:

http://msdn.microsoft.com/de-de/library/office/ee691831(v=office.14).aspx
http://windows.microsoft.com/de-de/windows/32-bit-and-64-bit-windows#1TC=windows-7
http://www.hardwareschotte.de/magazin/32-bit-vs-64-bit-wo-ist-der-unterschied-a41592

Download

Download

Die .zip-Datei enthält folgende Dateien:

VBA64.mdb

Beispieldateien downloaden

© 2003-2018 André Minhorst Alle Rechte vorbehalten.