(C) 2009 - 2021 by Mourad Louha · Alle Rechte vorbehalten

Excel VBA Application Objekte per Windows API erzeugen (Teil 2)

In meinem Artikel „Excel VBA Application Objekte per Windows API erzeugen (Teil 1)“ hatte ich eine Möglichkeit vorgestellt, wie über Windows API Funktionen alle geöffneten Excel Instanzen ermittelt werden können und gegebenenfalls daraus VBA Application Objekte erzeugt werden können. Das funktionierte jedoch nur mit den Excel Instanzen, in denen eine Arbeitsmappe geöffnet war. Dieser Artikel stellt nun eine Lösung vor, wie in Excel Instanzen ohne geöffnete Mappe per Windows API eine neue Mappe angelegt wird und anschließend das VBA Application Objekt erzeugt wird.

VBA Window Handles

Die Idee war insofern, ein neues Dokument in der Excel Instanz anzulegen und anschließend den Scan-Vorgang für alle Fensterhandles in dieser Instanz zu wiederholen. Um ein neues Dokument in Excel anzulegen, kann die Tastenkombination „Strg + N“ verwendet werden. Am einfachsten wäre es sicherlich einfach den Tastendruck und gedrückt halten für „Strg“ und anschließend die Taste „N“ zu simulieren.

Mein erster Versuch die Tastenkombination „Strg + N“ an eine bestimmte Excel Instanz zu senden bestand im Wesentlichem darin, mir den aktuellen Tastaturstatus zu merken, die Taste „Strg“ auf gedrückt zu setzen, das Hauptfenster der Zielinstanz in der Vordergrund zu holen und die Taste „N“ per Windows API Funktion „PostMessage()“ an die Instanz zu senden. Abschließend hatte ich dann den Tastaturstatus wieder restauriert.

Leider hat diese Methode nicht funktioniert. Excel erkennt nicht, das die „Strg“ Taste gedrückt ist. Ich vermute, dass Excel den Status der Tastatur laufend für sich abfragt, so dass keine Chance (jedenfalls habe ich keine Möglichkeit gefunden) besteht, da einzugreifen.

Insofern musste ich mir eine andere Lösung überlegen. Windows stellt auch die Funktion „SendInput()“ zur Verfügung, die das direkte Senden einer Tastenfolge ermöglicht. Die Funktion erwartet ein Array von „INPUT“ Strukturen. Die Struktur unterscheidet zwischen Maus-, Tastatur- und Hardwareereignissen. Insofern optimal für mich. Folgend ein Auszug des Codes, wie er nun im Tool implementiert ist:

Die Tastenfolge, um nun ein neues Dokument in der Excel Instanz anzulegen wäre dann, „Strg gedrückt“, „N gedrückt“, „N losgelassen“ und „Strg losgelassen“.

Dies spiegelt sich in der Funktion durch das Füllen der 4 Variablen k(0), k(1), k(2) und k(3) sowie Zuordnen dieser zu Elementen der Variablen „t“ vom Typ „apiInput“. Letzterer Typ entspricht dem zuvor erwähnten Windows API Typ „INPUT“. Anschließend wird das Hauptfenster der Excel Instanz in den Vordergrund geholt und die API Funktion zum Senden der Tastenkombination an die Excel Instanz aufgerufen. Die „4“ im ersten Parameter entspricht der Anzahl der Elemente im übergebenen Array; hier also t(0) bis t(3). Schließlich wird das Excel Fenster wieder aktiviert, in dem der Code läuft. Das war’s auch schon und funktioniert auf meinem Rechner zuverlässig.

VBA Window Handles

Den Code in der UserForm zum Tool habe ich zudem noch etwas angepasst bzw. erweitert. Wenn eine Excel Instanz gefunden wird, die keine geöffnete Mappe beinhaltet, zeigt das Tool die Schaltfläche „Create new document“ an. Ausserdem habe ich den Code leicht verbessert. Das Tool erhebt jedoch keinen Anspruch auf Fehlerlosigkeit oder Vollständigkeit; es wurde nur zum Zweck des Testens der API Funktionen entwickelt.

Das Tool enthält jetzt auch eine Möglichkeit, geöffnete Word Instanzen zu ermitteln und daraus Word VBA Application Objekt zu generieren. Während bei Excel nach „XLMAIN“ gesucht wird, ist bei Word „OpusApp“ zu verwenden (wer auch immer darauf gekommen ist). Da jedoch auch Word Fenster auftauchten, die keinen Namen haben, habe ich ebenfalls den Code zum Füllen des Treeviews so angepasst, dass diese Fenster nicht berücksichtigt werden.

Zusammenfassend heißt das nun, dass, zu mindestens in meiner Systemumgebung, aus jeder geöffneten Excel Instanz per Windows API ein Application Objekt generiert werden kann, über welches der Zugriff mit VBA auf die Excel Instanz möglich wird. Dies funktioniert auch mit Word und würde meines Erachtens auch mit PowerPoint gehen, wobei aber bei PowerPoint die Klassennamen der Fenster von Version zu Version unterschiedlich sind.