{"id":55000496,"date":"2025-12-01T00:00:00","date_gmt":"2026-02-05T15:44:27","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=496"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"VBA_Bedingte_Kompilierung_nutzen","status":"publish","type":"post","link":"https:\/\/vbentwickler.de\/VBA_Bedingte_Kompilierung_nutzen\/","title":{"rendered":"VBA: Bedingte Kompilierung nutzen"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg08.met.vgwort.de\/na\/7e2e8352958146a9b2ef44415fa53676\" width=\"1\" height=\"1\" alt=\"\"><b>In VBA-Projekten kann es vorkommen, dass Anweisungen nur in bestimmten Situationen kompiliert werden sollen. Das bekannteste Beispiel sind die Deklarationen von API-Funktionen, die je nach VBA-Version mal in der 32-Bit- und mal in der 64-Bit-Variante bereitgestellt werden sollen. Da die 64-Bit-Version bei Verwendung von 32-Bit-Access unter Umst&auml;nden Datentypen mit sich bringt, die es in der 32-Bit-Version nicht gibt, w&uuml;rde dies beim Kompilieren zu Fehlern f&uuml;hren. Daher gibt es die sogenannte bedingte Kompilierung, bei der man mit speziellen If&#8230;Then-Bedingungen daf&uuml;r sorgen kann, dass nur die f&uuml;r die aktuelle Version relevanten Codezeilen kompiliert werden k&ouml;nnen. In diesem Artikel zeigen wir, wie die bedingte Kompilierung funktioniert. Au&szlig;erdem stellen wir ein weiteres Beispiel vor, in dem wir entweder die Early Binding- oder die Late Binding-Verwendung von Variablen nutzen wollen &#8211; abh&auml;ngig von einer zur Laufzeit gesetzten Bedingung.<\/b><\/p>\n<h2>Bedingte Kompilierung<\/h2>\n<p>Die bedingte Kompilierung arbeitet mit <b>If&#8230;Then<\/b>-Bedingungen, die mit einem vorangestellten Raute-Zeichen angelegt werden:<\/p>\n<pre>#If VBA7 Then\r\n''API-Deklarationen f&uuml;r VBA7\r\n#Else\r\n''API-Deklarationen f&uuml;r &auml;ltere VBA-Version\r\n#End If<\/pre>\n<p>Hier haben wir bereits die erste von einigen wenigen eingebauten Kompilierungskonstanten verwendet, n&auml;mlich <b>VBA7<\/b>. Diese hat den Wert <b>True<\/b>, wenn VBA in der Version 7 verwendet wird. Den Wert dieser Konstanten k&ouml;nnen wir nur in einer mit dem Raute-Zeichen beginnenden Zeile auslesen, sie kann nicht einfach mit Debug.Print ermittelt werden. Die folgende Anweisung liefert kein Ergebnis:<\/p>\n<pre><span style=\"color:blue;\">Debug.Print<\/span> VBA7<\/pre>\n<p>Wir k&ouml;nnen aber eine Prozedur schreiben, in der wir per <b>#If&#8230;#Then<\/b>-Bedingung pr&uuml;fen, ob <b>VBA7 <\/b>den Wert <b>True <\/b>oder <b>False <\/b>hat:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>IsVBA7()\r\n#If VBA7 Then\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"VBA7\"\r\n#Else\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"&Auml;lteres VBA\"\r\n#End If\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Dies liefert f&uuml;r aktuelle Office-Versionen (ab Version 2010) den Wert <b>VBA7<\/b>.<\/p>\n<h2>32-Bit oder 64-Bit?<\/h2>\n<p>Auf die gleiche Weise k&ouml;nnen wir herausfinden, ob die aktuelle Office-Version in der 32-Bit- oder in der 64-Bit-Version vorliegt.<\/p>\n<p>Hier verwenden wir die Kompilierungskonstante <b>Win64<\/b>:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>Is32Or64Bit()\r\n#If Win64 Then\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"64-Bit\"\r\n#Else\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"32-Bit\"\r\n#End If\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Wir k&ouml;nnen auch explizit auf die 32-Bit-Version pr&uuml;fen:<\/p>\n<pre>#If Win32 Then\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"32-Bit\"\r\n#Else\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"64-Bit\"\r\n#End If<\/pre>\n<h2>Bedingte Kompilierung mit benutzerdefinierten Konstanten<\/h2>\n<p>Wir k&ouml;nnen auch eigene Kompilierungskonstanten definieren und diese per <b>#If&#8230;#Then<\/b>-Bedingung abfragen.<\/p>\n<p>Diese Konstanten m&uuml;ssen ohne Datentyp angegeben werden und werden ebenfalls mit f&uuml;hrenden Raute-Zeichen definiert, zum Beispiel:<\/p>\n<pre>#Const cEarlyBinding = -1<\/pre>\n<p>Die Konstanten d&uuml;rfen au&szlig;erdem nur <b>Long<\/b>-Werte enthalten. <\/p>\n<p>Diese fragen wir dann wie folgt ab:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>EigeneKonstante()\r\n#If cEarlyBinding = -1 Then\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"cEarlyBinding ist True\"\r\n#Else\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"cEarlyBinding ist False\"\r\n#End If\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>Bedingte Kompilierung f&uuml;r Early Binding und Late Binding<\/h2>\n<p>Wenn wir auf dem Entwicklungsrechner mit Early Binding arbeiten wollen, um IntelliSense nutzen zu k&ouml;nnen, aber auf dem Produktivrechner sicherstellen wollen, dass das Projekt auch ohne Vorhandensein der jeweiligen Bibliothek zumindest ohne Kompilierfehler verwendet werden kann, k&ouml;nnen wir hier die Anweisungen zum Deklarieren und Initialisieren von Objektvariablen einf&uuml;gen:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>EarlyBinding()\r\n#If cEarlyBinding = -1 Then\r\n     <span style=\"color:blue;\">Dim <\/span>rst<span style=\"color:blue;\"> As <\/span>adodb.Recordset\r\n     <span style=\"color:blue;\">Set<\/span> rst = <span style=\"color:blue;\">New<\/span> adodb.Recordset\r\n#Else\r\n     <span style=\"color:blue;\">Dim <\/span>rst<span style=\"color:blue;\"> As Object<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> rst = CreateObject(\"ADODB.Recordset\")\r\n#End If\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Wenn wir <b>#cEarlyBinding <\/b>auf <b>-1 <\/b>einstellen, werden die Anweisungen im <b>#If<\/b>-Teil der Bedingung kompiliert und ausgef&uuml;hrt, andernfalls die aus dem <b>#Else<\/b>-Teil. Das k&ouml;nnen wir leicht pr&uuml;fen, indem wir die Anweisungen schrittweise durchlaufen.<\/p>\n<p>Wenn wir die Konstante <b>#cEarlyBinding <\/b>auf den Wert <b>-1 <\/b>einstellen und die Bibliothek <b>Microsoft ActiveX Data Objects x.y <\/b>nicht per Verweis eingebunden ist, erhalten wir au&szlig;erdem einen Kompilierfehler (siehe Bild 1). Hier m&uuml;ssen wir also, solange wir auf dem Entwicklungsrechner arbeiten, den Wert von <b>#cEarlyBinding <\/b>auf <b>-1 <\/b>einstellen und den Wert vor der Weitergabe auf <b>0 <\/b>&auml;ndern.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_06\/pic_496_001.png\" alt=\"Kompilierfehler, weil die ADODB-Bibliothek fehlt\" width=\"428,1424\" height=\"398,2087\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Kompilierfehler, weil die ADODB-Bibliothek fehlt<\/span><\/b><\/p>\n<h2>Kompilierungskonstanten in den Eigenschaften des VBA-Projekts speichern<\/h2>\n<p>Die Kompilierungskonstante <b>cEarlyBinding <\/b>k&ouml;nnen wir auch in den Eigenschaften des VBA-Projekts hinterlegen. Diese &ouml;ffnen wir &uuml;ber den Men&uuml;befehl <b>Extras|Eigenschaften von [Projektname]&#8230; <\/b>und erhalten den Dialog aus Bild 2. Die Kompilierungskonstante aus dem Code k&ouml;nnen wir nun entfernen und die Kompilierung funktioniert dennoch wie erwartet.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_06\/pic_496_002.png\" alt=\"Kompilierungskonstanten in den Eigenschaften des VBA-Projekts\" width=\"503,1425\" height=\"460,6062\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Kompilierungskonstanten in den Eigenschaften des VBA-Projekts<\/span><\/b><\/p>\n<h2>Kompilierkonstanten zur Laufzeit einstellen<\/h2>\n<p>Dies hat den Vorteil, dass wir die Kompilierungskonstante auch zur Laufzeit einstellen k&ouml;nnen, was bei der Konstanten im Code nicht m&ouml;glich ist. Dazu nutzen wir die <b>SetOption<\/b>-Methode des <b>Application<\/b>-Objekts. Hier stellen wir die Konstante <b>cEarlyBinding <\/b>auf den Wert <b>-1 <\/b>ein:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>KompilierungskonstanteEinstellen()\r\n     Application.SetOption _\r\n         \"Conditional Compilation Arguments\", _\r\n         \"cEarlyBinding=-1\"\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Diese Konstante k&ouml;nnen wir in Abh&auml;ngigkeit von verschiedenen Bedingungen einstellen. Wir k&ouml;nnten zum Beispiel pr&uuml;fen, ob sich die Datenbank auf dem Entwicklungsrechner an einem bestimmten Ort befindet, zum Beispiel so:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>KompilierungskonstanteEinstellen()\r\n     If CurrentDb.Name = _\r\n             \"C:\\...\\VBABedingteKompilierungNutzen.accdb\" Then\r\n         Application.SetOption _\r\n             \"Conditional Compilation Arguments\", _\r\n             \"cEarlyBinding=-1\"\r\n     <span style=\"color:blue;\">Else<\/span>\r\n         Application.SetOption _\r\n             \"Conditional Compilation Arguments\", _\r\n             \"cEarlyBinding=0\"\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Dann wird auf dem Entwicklungsrechner die Konstante auf <b>-1 <\/b>eingestellt und andernfalls auf <b>0 <\/b>(au&szlig;er, beim Benutzer ist die Datenbank zuf&auml;llig unter genau dem gleichen Pfad gespeichert).<\/p>\n<p>Damit die Konstante f&uuml;r die bedingte Kompilierung direkt beim Start der Anwendung festgelegt wird, k&ouml;nnen wir ein AutoExec-Makro definieren, das eine Funktion mit den obigen Anweisungen ausf&uuml;hrt. F&uuml;r das <b>AutoExec<\/b>-Makro legen wir die <b>Ausf&uuml;hrenCode<\/b>-Aktion fest und tragen als auszuf&uuml;hrende Funktion den Wert <b>=BedingteKompilierung() <\/b>ein (siehe Bild 3).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_06\/pic_496_003.png\" alt=\"AutoExec-Makro zum Aufrufen der Funktion zum Einstellen der Konstanten f&uuml;r die bedingte Kompilierung\" width=\"428,1424\" height=\"210,7779\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: AutoExec-Makro zum Aufrufen der Funktion zum Einstellen der Konstanten f&uuml;r die bedingte Kompilierung<\/span><\/b><\/p>\n<p>Die folgende Funktion enth&auml;lt die gleichen Anweisungen wie die zuvor beschriebene:<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>BedingteKompilierung()\r\n     ...\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p>Beim Start der Anwendung wird nun das <b>AutoExec<\/b>-Makro aufgerufen, das wiederum die Funktion <b>BedingteKompilierung <\/b>startet. Dadurch wird die Kompilierungskonstante <b>cEarlyBinding <\/b>auf den entsprechenden Wert eingestellt.<\/p>\n<h2>Mehrere Kompilierungskonstanten verwenden<\/h2>\n<p>Wir k&ouml;nnen auch mehrere Konstanten hinterlegen. Diese m&uuml;ssen wir durch einen Doppelpunkt voneinander trennen (siehe Bild 4).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_06\/pic_496_004.png\" alt=\"Beispiel f&uuml;r mehrere Kompilierungskonstanten\" width=\"428,1424\" height=\"391,9469\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Beispiel f&uuml;r mehrere Kompilierungskonstanten<\/span><\/b><\/p>\n<p>Dass dies funktioniert, pr&uuml;fen wir mit der folgenden Funktion:<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>TestMehrereKonstanten()\r\n#If A = -1 Then\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"A = -1\"\r\n#Else\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"A = 0\"\r\n#End If\r\n#If B = -1 Then\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"B = -1\"\r\n#Else\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"B = 0\"\r\n#End If\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<h2>Vorsicht, .accde-Datenbanken!<\/h2>\n<p><b>Achtung: <\/b>Das Setzen der Kompilierkonstanten per VBA funktioniert nicht in <b>.accde<\/b>-Datenbanken!<\/p>\n<h2>Zusammenfassung und Ausblick<\/h2>\n<p>Dieser Artikel zeigt, wie man die bedingte Kompilierung nutzt, um bestimmte Anweisungen nur unter den entsprechenden Bedingungen zu kompilieren und ausf&uuml;hrbar zu machen.<\/p>\n<p>Damit k&ouml;nnen wir beispielsweise API-Funktionen f&uuml;r 32-Bit und 64-Bit deklarieren oder Early Binding und Late Binding gezielt einsetzen.<\/p>\n<h2>Downloads zu diesem Beitrag<\/h2>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>VBABedingteKompilierungNutzen.accdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/F78D9BFC-C341-4063-90A8-4057D6AD78C9\/vbe_496.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In VBA-Projekten kann es vorkommen, dass Anweisungen nur in bestimmten Situationen kompiliert werden sollen. Das bekannteste Beispiel sind die Deklarationen von API-Funktionen, die je nach VBA-Version mal in der 32-Bit- und mal in der 64-Bit-Variante bereitgestellt werden sollen. Da die 64-Bit-Version bei Verwendung von 32-Bit-Access unter Umst&auml;nden Datentypen mit sich bringt, die es in der 32-Bit-Version nicht gibt, w&uuml;rde dies beim Kompilieren zu Fehlern f&uuml;hren. Daher gibt es die sogenannte bedingte Kompilierung, bei der man mit speziellen If&#8230;Then-Bedingungen daf&uuml;r sorgen kann, dass nur die f&uuml;r die aktuelle Version relevanten Codezeilen kompiliert werden k&ouml;nnen. In diesem Artikel zeigen wir, wie die bedingte Kompilierung funktioniert. Au&szlig;erdem stellen wir ein weiteres Beispiel vor, in dem wir entweder die Early Binding- oder die Late Binding-Verwendung von Variablen nutzen wollen &#8211; abh&auml;ngig von einer zur Laufzeit gesetzten Bedingung.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[662025,66062025,44000026,44000025],"tags":[],"yst_prominent_words":[],"class_list":["post-55000496","post","type-post","status-publish","format-standard","hentry","category-662025","category-66062025","category-Outlook_programmieren","category-VBAProgrammierung"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000496","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/comments?post=55000496"}],"version-history":[{"count":0,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000496\/revisions"}],"wp:attachment":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/media?parent=55000496"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/categories?post=55000496"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/tags?post=55000496"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/yst_prominent_words?post=55000496"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}