Mit Access 2007 ist wieder mal eine neue Version erschienen. Damit stellt sich für Softwareentwickler und auch für Anwender die Frage, ob man zu dieser Version wechseln sollte oder vielleicht versucht, eine Anwendung so weit anzupassen, dass diese auch mit der neuen Version zusammenarbeitet und gleichzeitig die vorhandenen Versionen unterstützt. Wie sich das für einzelne Features umsetzen lässt, zeigen wir am Beispiel PDF-Export.
Eine Anwendung bauen, die unter Access 2003 und älter und auch unter Access 2007 läuft Was soll das bringen und vor allem: Wie soll das funktionieren Bei früheren Versionswechseln sah man sich in der Regel nicht solch gravierenden Neuerungen ausgesetzt wie es jetzt unter Access 2007 der Fall ist. Das gilt natürlich insbesondere für das Ribbon, das die bisher verwendeten Menüleisten ersetzt. Aber auch unter VBA und in anderen Bereichen sind einige Features hinzugekommen.
Wir haben uns den PDF-Export vorgenommen, der unter Access 2003 und älter und unter Access 2007 auf unterschiedliche (kostenlose) Weise erfolgen kann, um zu untersuchen, wie man eine Anwendung für mehrere Access-Versionen und deren Eigenarten vorbereitet.
Lebans vs. Microsoft
Bis Office 2007 erschien und mit ihm ein Add-In, das den Export von Access-Berichten und auch von Office-Dokumenten ins PDF-Format erlaubte, konnte man sich entweder bei einer der kostenpflichtigen Lösungen bedienen oder etwas Handgemachtes einsetzen. Für Access-Berichte haben viele Entwickler zu einer Lösung von Stephen Lebans gegriffen (http://www.lebans.com/reporttopdf.htm). Diese Lösung verwendet zwei DLLs, die man einfach im Systempfad speichert und vom Programmcode aus aufruft. Details dazu erfahren Sie im Beitrag Vom Bericht zum PDF-Dokument (Shortlink 430).
Ab Access 2007 bietet Microsoft unter folgendem Link ein Add-In an, mit dem man wahlweise über einen Eintrag des Office-Menüs oder über den Befehl DoCmd.OutputTo ein Objekt (in der Regel einen Bericht) im PDF-Format speichert: http://www.microsoft.com/downloads/details.aspxdisplaylang=de&FamilyID=f1fc413c-6d89-4f15-991b-63b07ba5f2e5
Alles in einem
Für beide Lösungen ist eine gewisse Menge Code notwendig. Wenn Sie die Anwendung unter Access 2003 kompilieren, möchten Sie normalerweise nur den dafür nötigen Code dort unterbringen, unter Access 2007 sieht das genauso aus.
VBA bietet für solche Fälle die bedingte Kompilierung an. Damit können Sie für ein Modul eine Konstante festlegen und in Abhängigkeit vom Wert dieser Konstanten in einer speziell markierten If…Then-Anweisung den jeweiligen Code unterbringen. Das sieht etwa so aus:
#Const AccessVersion = 2000 Public Sub BeispielBedingteKompilierung() #If AccessVersion = 2000 Then MsgBox "2000" #ElseIf AccessVersion = 2007 Then MsgBox "2007" #End If End Sub
Im aktuellen Fall, also mit dem Konstantenwert 2000, wird Access die erste MsgBox-Anweisung ausführen.
Der Unterschied zu einer herkömmlichen If…Then-Bedingung und der Clou an der Sache ist, dass VBA nur den Teil des Codes kompiliert, der beim aktuellen Wert der Konstanten AccessVersion angesprungen wird. Das bedeutet, dass die .mdb/.accdb-Datei zwar den kompletten Code im Rohformat enthält (also das, was Sie auch im VBA-Editor sehen, auch kanonischer Code genannt), aber nur den Teil in kompilierter Fassung (P-Code), den Sie durch die #If…#Then-Bedingung zur bedingten Kompilierung freigegeben haben. Wenn Sie schon die gleiche Funktion für zwei verschiedene Access-Versionen im Projekt haben, brauchen Sie ja nicht auch noch das Kompilat des jeweils nicht benötigten Teils mitzuschleppen.
Noch besser wird es, wenn Sie eine .mde/.accde-Datenbank aus der Originaldatenbank erzeugen: Hier wirft Access ja bekanntlich den kompletten kanonischen Code raus und behält nur den P-Code. Auf unser Beispiel bezogen fällt, wenn Sie beispielsweise eine Version für Access 2000 bis 2003 kompilieren, der Code weg, der für die Ausgabe von PDFs mit dem Microsoft'schen Add-In nötig war.
Pro Modul
Leider ist die Gültigkeit der Konstanten für die bedingte Kompilierung auf ein Modul beschränkt, und es gibt auch immer nur eine solche Konstante. Dabei spielt es allerdings keine Rolle, ob Sie die Konstante innerhalb einer Routine oder im Modulkopf festlegen. Es ist sogar egal, ob Sie die #If…#Then-Anweisung zur bedingten Kompilierung innerhalb oder außerhalb von Routinen unterbringen. Das kann zum Beispiel auch so aussehen:
Public Sub Test() #Const AccessVersion = 2000 End Sub #If AccessVersion = 2000 Then Public Sub BeispielBedingteKompilierung() MsgBox "2000" End Sub #ElseIf AccessVersion = 2007 Then Public Sub BeispielBedingteKompilierung() MsgBox "2007" End Sub #End If