Aufbau einer Declare-Anweisung

Nachstehend wird ein Beispiel der Declare-Anweisung für die GetTempPath-Funktion angezeigt, die den Pfad des temporären Ordners von Microsoft® Windows zurückgibt:

Private Declare Function GetTempPath Lib "kernel32" _
         Alias "GetTempPathA" (ByVal nBufferLength As Long, _
         ByVal lpBuffer As String) As Long

Durch das Declare-Schlüsselwort wird VBA mitgeteilt, dass die Definition für eine DLL-Funktion in das Projekt eingebunden werden soll. Eine Declare-Anweisung in einem Standardmodul kann öffentlich (public) oder privat (private) sein; dies ist abhängig davon, ob die API-Funktion nur für ein einziges Modul oder für das gesamte Projekt verfügbar gemacht werden soll. In einem Klassenmodul muss eine Declare-Anweisung privat sein.

Der Funktionsname, der auf das Function-Schlüsselwort folgt, ist der Name, den Sie in VBA zum Aufrufen der Funktion verwenden. Dieser Name kann mit dem Namen der API-Funktion identisch sein. Andernfalls können Sie innerhalb der Declare-Anweisung das Alias-Schlüsselwort verwenden, um anzugeben, dass die Funktion aus VBA durch einen anderen Namen (einen Aliasnamen) aufgerufen werden soll.

Im vorherigen Beispiel lautet der Name der API-Funktion in der DLL GetTempPathA, und der Name, mit dem sie aus VBA aufgerufen wird, lautet GetTempPath.

**Anmerkung   **Der tatsächliche Name der DLL-Funktion steht hinter dem Alias-Schlüsselwort.

Anmerkung   GetTempPath ist der Name, der in der Datei Win32API.txt als Aliasname für die Funktion verwendet wird, jedoch beliebig geändert werden kann.

Im Folgenden werden einige Gründe aufgeführt, die für das Verwenden eines Aliasnamens innerhalb der Declare-Anweisung sprechen:

  • Einige Namen von API-Funktionen beginnen mit einem Unterstrich (_), der in VBA nicht zulässig ist. Zum Aufrufen der Funktion aus VBA müssen Sie einen Aliasnamen verwenden.
  • Da das Verwenden eines Aliasnamens eine beliebige Benennung einer DLL-Funktion ermöglicht, können Sie den Funktionsnamen in VBA an Ihre Benennungskonventionen anpassen.
  • Da bei API-Funktionen die Groß-/Kleinschreibung beachtet werden muss, bei VBA-Funktionen jedoch nicht, kann die Groß-/Kleinschreibung eines Funktionsnamens mithilfe eines Aliasnamens geändert werden.
  • Einige DLL-Funktionen verwenden Argumente, die verschiedenen Datentyps sein können. Von den Declare-Anweisungen von VBA für diese Funktionen wird der Typ dieser Argumente als Any definiert. Das Aufrufen einer DLL-Funktion mit als Any deklarierten Argumenten kann schwerwiegende Folgen haben, da durch VBA keine Datentypüberprüfungen vorgenommen werden. Zum Vermeiden von Nachteilen, die das Übergeben von als Any deklarierten Argumenten mit sich bringt, können mehrere Versionen derselben DLL-Funktion mit unterschiedlichen Namen und verschiedenen Datentypen deklariert werden.
  • Die Windows-API enthält jeweils zwei Versionen aller Funktionen, die Argumente vom Typ String haben: eine ANSI-Version und eine Unicode-Version. Wie das oben stehende Beispiel zeigt, wird für die ANSI-Version das Suffix "A" und für die Unicode-Version das Suffix "W" verwendet. Obwohl VBA intern Unicode verwendet, werden alle Zeichenfolgen vor dem Aufrufen einer Funktion in einer DLL in ANSI-Zeichenfolgen konvertiert. Beim Aufrufen einer Windows API-Funktion aus VBA wird daher normalerweise die ANSI-Version verwendet. Das API-Viewer-Add-In versieht automatisch alle Funktionen, die Argumente vom Typ String haben, mit einem Aliasnamen. Das Suffix "A" ist zum Aufrufen der jeweiligen Funktion somit nicht mehr erforderlich.

Das Lib-Schlüsselwort gibt an, welche DLL die Funktion enthält. Beachten Sie, dass der DLL-Name in einer Zeichenfolge innerhalb der Declare-Anweisung steht. Kann die hinter dem Lib-Schlüsselwort angegebene DLL auf dem System des Benutzers nicht gefunden werden, schlägt der Aufruf der Funktion fehl, und der Laufzeitfehler 53, "Datei nicht gefunden", wird ausgelöst. Da Sie diesen Fehler in Ihrem VBA-Code behandeln können, ist es Ihnen möglich, robusten Code zu schreiben, der das Auftreten eines Laufzeitfehlers abfangen kann.

Anmerkung   Dieses Problem stellt sich beim Aufrufen einer Funktion in einer der grundlegenden Windows-DLLs nicht, da diese DLLs zum Laden der Anwendung vorhanden sein müssen.

In der folgenden Tabelle werden die gebräuchlichsten DLLs in der Windows-API beschrieben.

DLL Inhalt
Kernel32.dll Grundlegende Betriebssystemfunktionen, z. B. für Speicherverwaltung und Ressourcenbehandlung
User32.dll Windows-Verwaltungsfunktionen, z. B. für Meldungsbehandlung, Zeitgeber, Menüs und Kommunikation.
GDI32.dll Die GDI-Bibliothek (GDI, Graphics Device Interface), die Funktionen für die Geräteausgabe enthält, z. B. Zeichnen, Anzeigen von Kontext und Schriftenverwaltung.

Die meisten DLLs, einschließlich den in der Windows-API enthaltenen, sind in C oder C++ geschrieben. Das Übergeben von Argumenten an eine DLL-Funktion setzt somit ein gewisses Verständnis für die von einer C- oder C++-Funktion erwarteten Argumente und Datentypen voraus, die sich in verschiedener Hinsicht von den Argumenten und Datentypen unterscheiden, die von einer VBA-Funktion erwartet werden.

Außerdem werden viele Argumente als Wert an DLL-Funktionen übergeben. Da Argumente in VBA standardmäßig als Verweis übergeben werden, ist die Aufnahme des ByVal-Schlüsselwortes in die Funktionsdefinition unbedingt notwendig, wenn die DLL-Funktion die Übergabe eines Arguments als Wert erforderlich macht. Das Fehlen des ByVal-Schlüsselwortes in einer Funktionsdefinition kann in einigen Fällen den Fehler "Ungültige Seite" in der Anwendung verursachen. In anderen Fällen kann der VBA-Laufzeitfehler 49, "Falsche DLL-Aufrufkonvention", auftreten.

Beim Übergeben eines Arguments als Verweis wird der Arbeitsspeicherort des jeweiligen Arguments an die aufgerufene Prozedur übergeben. Beim Ändern des Argumentwertes durch die Prozedur ändert sie die einzige Kopie des Arguments. Wenn die Ausführung dann an die aufrufende Prozedur zurückgegeben wird, enthält das Argument den geänderten Wert.

Wird das Argument hingegen als Wert an eine DLL-Funktion übergeben, wird eine Kopie des Arguments übergeben, so dass die Funktion eine Kopie des Arguments verwendet. Dadurch wird ein Ändern des Inhalts des eigentlichen Arguments durch diese Funktion verhindert. Wenn die Ausführung an die aufrufende Prozedur zurückgegeben wird, enthält das Argument den gleichen Wert wie vor dem Aufrufen der Prozedur.

Da durch eine Verweisübergabe das Argument im Arbeitsspeicher geändert werden kann, kann eine inkorrekte Übergabe eines Arguments als Verweis ein unbeabsichtigtes Überschreiben von Arbeitsspeicherbereichen durch die DLL-Funktion zur Folge haben, so dass ein Fehler oder ein anderweitig unerwartetes Verhalten verursacht wird. Windows verwaltet viele Werte, die nicht überschrieben werden dürfen. Windows weist z. B. jedem Fenster einen 32-Bit-Bezeichner, das Handle, zu. Handles werden als Wert an API-Funktionen übergeben, da Windows bei einem möglichen Ändern eines Fensterhandles dieses Fenster nicht mehr auffinden könnte.

Anmerkung   Auch wenn das ByVal-Schlüsselwort vor einigen Argumenten vom Datentyp String auftritt, werden Zeichenfolgen grundsätzlich als Verweis an Windows API-Funktionen übergeben.

Siehe auch

API-Grundlagen | Funktionsweise einer API | Vorteile beim Aufrufen von Windows-API mit VBA | Informationsquellen zur API | Zugreifen auf Funktionen in einer DLL | Konstanten und benutzerdefinierte Typen | Grundlegendes zu Handles | Aufrufen von DLL-Funktionen | Übergeben von Argumenten als Wert oder als Verweis | Nutzen des vollen Funktionsumfangs von Visual Basic für Applikationen