Senden von Tastenbefehlen (SendKeys) Home Home

WB01727_.gif (1537 Byte)

Inhalt dieses Dokumentes
Wenn man eine Arbeitsmappe erstellt, die einem beliebigen Benutzerkreis zur Verfügung gestellt werden soll, so muss man daran denken, dass Microsoft Excel sowohl für Windows als auch für Macintosh existiert. Eine mit Excel für Windows erstellte Mappe muss daher auch in Excel für Macintosh bearbeitbar sein und umgekehrt. Zwischen Excel für Windows und Excel für Macintosh gibt es eine ganze Reihe wichtiger Unterschiede, die man beachten muss. Insbesondere beim Schreiben von VBA-Programmcode muss man viele Spezialitäten und Inkompatibilitäten berücksichtigen, die unter anderem in VBA, im Excel-Objektmodell und im Office-Objektmodell enthalten sind.

Diese Dokumentation stellt sämtliche derzeit bekannten Unterschiede, Inkompatibilitäten, Spezialfälle und potenzielle Probleme von plattformunabhängigen Excel-Arbeitsmappen und VBA-Programmen vor.

Sie erhalten hier ausführliche Beschreibungen, Anleitungen, Empfehlungen, Tipps und Tricks sowie VBA-Codebeispiele. Viele Informationen beziehen ganz allgemein auf VBA und gelten somit auch für VBA-Programme, die mit einem anderen Microsoft Office-Programm als Microsoft Excel entwickelt wurden.

Diese Dokumentation ist auch als PDF-Dokument erhältlich. Mehr dazu siehe hier.


Version: Dokument-Version 3.2
Datum: Zuletzt aktualisiert am 27.01.2006
Autor: Philipp von Wartburg (mailto:philipp_von_wartburg@yahoo.de), Winkel 115, CH-8916 Jonen

Zielpublikum
Microsoft Office-Anwender und -Programmierer, insbesondere von Microsoft Excel, die Arbeitsmappen, Add-Ins, Makros und VBA-Programme sowohl für Excel für Windows als auch für Excel für Macintosh entwickeln.

WB01727_.gif (1537 Byte)

Inhalt

arrow_r.gif (830 Byte) Einleitung
     Inhalt dieser Seite
     Zweck von Tastenbefehlen senden
     Einsatzgebiete

arrow_r.gif (830 Byte) Voraussetzungen für das Senden von Tasten
     1. Anwendung muss aktiv sein
     2. Anwendung muss Taste verstehen können
     3. Anwendung muss Taste verarbeiten können

arrow_r.gif (830 Byte) Die verschiedenen Möglichkeiten zum Senden von Tastenfolgen
     SendKeys (VBA-Anweisung)
     Application.SendKeys (Objekt-Methode)
     Application.DDEExecute (Objekt-Methode)

arrow_r.gif (830 Byte) Technische Informationen zu SendKeys, Application.SendKeys und DDEExecute

arrow_r.gif (830 Byte) SendKeys, Application.SendKeys oder DDEExecute?
     Unterschiede zwischen SendKeys und Application.SendKeys
     Ein kleiner Praxis-Test
     Unterschiedliches Verhalten je nach Windows-Version
     Verwendung von DoEvents
     Was bewirkt der Wait-Parameter?
     Wann muss der Wait-Parameter auf True gesetzt werden?

arrow_r.gif (830 Byte) So sendet man Tastenanschläge
     Tastenfolgen zur Steuerung einer Dialogmaske an Excel senden
     Sonstige Tastenfolgen an Excel senden
     Tastenfolgen an eine andere Anwendung senden

arrow_r.gif (830 Byte) Einschränkungen und Grenzen von SendKeys
     Nicht unterstützte Tasten
     Umgehungslösung für nicht unterstützte Tasten

arrow_r.gif (830 Byte) Bestimmen der Ausführungsumgebung

arrow_r.gif (830 Byte) Empfänger-Anwendung starten und aktivieren

arrow_r.gif (830 Byte) Eine alltägliche Aufgabe: Anwendung starten, Fenster aktivieren, Tasten senden

arrow_r.gif (830 Byte) Programm-Stabilität und -Fehlerfreiheit
     Makro-Unterbrechung verhindern
     Makro-Abbruch verhindern
     Unterbrochenes Makro fortsetzen

arrow_r.gif (830 Byte) Checkliste für die Programmierung

arrow_r.gif (830 Byte) Programmverhalten testen

arrow_r.gif (830 Byte) VBA Codebeispiele

arrow_r.gif (830 Byte) Begriffserklärungen

arrow_r.gif (830 Byte) Tasten-Namen

Zum Anfang


Einleitung

Inhalt dieser Seite

Auf dieser Seite finden Sie umfassende und ausführliche Informationen zum Thema "Senden von Tastenfolgen an eine Anwendung". Lesen Sie hier allerlei Interessantes zu diesen Dingen:

- warum und in welchen Situationen man Tastenfolgen senden sollte
- was man grundsätzlich beachten muss
- welche Risiken und Gefahren existieren
- welche Probleme und Fehler bekannt sind
- was man bereits vor dem Programmieren beachten sollte
- was aus technischer Sicht beim Senden von Tastenfolgen vorgeht
- wie die in VBA zur Verfügung stehenden Anweisungen und Funktionen heissen
- wie man mit VBA Tastenfolgen sendet
- was man bei Auftreten eines Fehlers tun kann
- welche Tasten nicht an eine Anwendung gesendet werden können
- wie man Spezialtasten wie u.a. CapsLock aufrufen kann
- wie eine andere Anwendung gestartet wird
- welche Alternativen es zum Senden von Tastenbefehlen gibt
- wie man überprüfen kann, ob Tastenfolgen korrekt verarbeitet wurden
- welche geheime und undokumentierte Features existieren
- wie man SendKeys-Programmcode stabil und fehlerresistent macht
- wie die offiziellen Tastenbezeichnungen lauten
- wo man weitere themenbezogene Informationen erhält

Zum Anfang


Zweck von Tastenbefehlen senden

Das Senden von Tastenfolgen stellt eine einfache Lösung dar, eine beliebige Anwendung zu steuern, Funktionen dieser Anwendung auszuführen, Menübefehle aufzurufen, Daten zu übergeben bzw. zu übernehmen, und so weiter. Die Möglichkeiten sind praktisch unbegrenzt, wobei es ein paar wenige Einschränkungen gibt (siehe Kapitel Einschränkungen und Grenzen von SendKeys).

Üblicherweise werden Tastenfolgen an eine andere Anwendung gesendet. Man kann jedoch problemlos auch Tastenbefehle an die eigene Anwendung senden, sprich an diejenige Anwendung, die den Programmcode enthält und ausführt, und somit die aktive Anwendung darstellt.

Zum Anfang


Einsatzgebiete

In den meisten Fällen gibt es bessere Lösungen als das Senden von Tastenbefehlen, nämlich unter anderem die Steuerung der anderen Anwendung mittels Automation (auch Office Automation genannt, früher OLE Automation genannt), oder, wenn die eigene Anwendung gesteuert werden soll, die Verwendung der entsprechenden, standardmässig vorhandenen VBA-Anweisungen und Objekt-Methoden.

Alternative 1: Objekt-Methode
Anstelle das Senden der Tastenkombination Strg+X verwendet man innerhalb Microsoft Excel zum Ausschneiden einer Zelle besser die Cut-Methode. Mit der Codezeile "ActiveCell.Cut" wird beispielsweise die gerade aktive Zelle ausgeschnitten.

Alternative 2: VBA-Anweisung
Zum Kopieren einer Datei muss man nicht den Windows Explorer mittels Shell-Funktion starten, die gewünschte Datei selektieren und dann den Kopieren-Befehl des Bearbeiten-Menüs anhand von gesendeten Tastenanschlägen aufrufen. Einfacher geht es mit der FileCopy-Anweisung von VBA.

Alternative 3: Automation
Ein neues Word-Dokument kann aus einer anderen Anwendung heraus sehr einfach mittels Office Automation angelegt werden. Man muss also nicht Microsoft Word mit VBA (z.B. mit Shell oder ActivateMicrosoftApp) starten und dann anhand von Tastenfolgen den Menübefehl Datei/Neu von Word aufrufen.

Der VBA-Programmcode dieser Automation-Lösung, welche Word starten, ein neues Dokument erstellt, das Dokument speichert und anschliessend Word beendet sieht folgendermassen aus:

Sub CreateNewDocument()
  Dim appWord As Object
  Set appWord = CreateObject("Word.Application")
  appWord.Documents.Add.SaveAs "D:\NewDocument.doc"
  appWord.Quit
  Set appWord = Nothing

End Sub

 

Wenn es keine Alternative gibt

Wie gesagt funktioniert in den meisten Fällen mindestens eine der oben aufgeführten Alternativen. Es gibt jedoch ein paar Fälle, bei denen weder eine VBA-Anweisung, noch eine Objekt-Methode, noch eine Automation-Lösung in Frage kommt, und zwar ganz einfach aus dem Grund, weil es keine entsprechende Lösungsmöglichkeit gibt.

Verschiedene Aufgabenstellungen lassen sich ausschliesslich durch das Senden von Tastenfolgen lösen. In Bezug auf Microsoft Excel kann man diese in zwei Gruppen einteilen:
1. Dialogmasken und Fenster, die in Excel zwar aufgerufen werden können, aber nicht mit VBA angesprochen werden können
2. Funktionen, Befehle und Optionen, die im Excel-Objektmodell nicht als Methoden oder Eigenschaften existieren

Hier ein paar solcher Aufgaben:

Aufgabe Beschreibung Beispiel
Drucker-Eigenschaften ändern Die Drucker-Eigenschaften können nicht mit VBA eingestellt werden, da entsprechende Eigenschaften im Objektmodell fehlen. -
Bearbeiten-Modus aktivieren Der Zellbearbeitungsmodus wird in Excel mittels Doppelklick auf eine Zelle oder mit der Funktionstaste F2 aktiviert. Excel-VBA stellt keine entsprechende Methode zur Verfügung. -
Bestimmter Datensatz in Datenmaske anzeigen - -
Optionen-Dialogfenster öffnen - -
Optionen des VBA-Editors ändern - -

Zum Anfang

 


Voraussetzungen für das Senden von Tasten

Damit eine Taste an eine Anwendung gesendet und von dieser verarbeitet werden kann, müssen insbesondere drei Bedingungen erfüllt sein:
1. Die Empfänger-Anwendung muss aktiv sein
2. Die Empfänger-Anwendung muss die an sie gesendete Taste interpretieren können
3. Die Empfänger-Anwendung muss die an sie gesendete Taste verarbeiten können

In den folgenden drei Abschnitten werden diese drei Bedingungen vorgestellt.

Zum Anfang


1. Anwendung muss aktiv sein

Gesendete Tastenfolgen werden immer von derjenigen Anwendung empfangen, die gerade aktiv ist. Die aktive Anwendung erkennt man daran, dass das Fenster dieser Anwendung aktiv ist, sprich den Fokus besitzt. Eine Anwendung, die kein Fenster besitzt oder nicht aktiviert werden kann, kann folglich auch keine Tastenbefehle empfangen (z.B. ein Systemprozess oder eine Anwendung mit einem ausgeblendeten Fenster).

Zum Anfang


2. Anwendung muss Taste verstehen können

Obwohl diese Voraussetzung an sich 'logisch' ist, darf man sie nicht vergessen und schon gar nicht als selbstverständlich betrachten.

Beispielsweise die an Microsoft Excel gesendete Tastenfolge "ALT+D, I" bewirkt, dass das Dialogfenster "Eigenschaften" geöffnet wird, weil mit ALT+D das Menü "Datei" geöffnet und mit der I-Taste der Menübefehl "Eigenschaften" ausgeführt wird. Es ist soweit eigentlich klar, dass Excel die Tastenfolge nur dann versteht, wenn es ein Menü "Datei" mit unterstrichenem Buchstabe D gibt und beim Menübefehl "Eigenschaften" der Buchstabe I unterstrichen ist. Gäbe es dies nicht, würde Excel die Tasten zwar ausführen, was jedoch zu einem unerwünschten oder gar keinem Resultat führen würde.

In diesem Zusammenhang wird oft vergessen, dass das Menü "Datei", um beim obigen Beispiel zu bleiben, nicht zwingend die Zugriffstaste ALT+D besitzt. Einerseits ist es für einen Excel-Anwender kein Problem, diesem Menü eine andere oder gar keine Zugriffstaste zu vergeben. Andererseits lautet das Menü nur in der deutschsprachigen Excelversion "Datei". In beispielsweise der englischen Version heisst dieses Menü "File" und wird mit der Tastenkombination ALT+F aufgerufen. Die Tastenfolge "ALT+D, I" wird somit bei der englischen Excelversion auf jeden Fall nicht das Dialogfenster "Eigenschaften" öffnen, sondern eine andere (oder gar keine) Aktion ausführen.

Zum Anfang


3. Anwendung muss Taste verarbeiten können

Es gibt Tasten, die von einer Anwendung nicht verarbeitet werden können. Es ist beispielsweise möglich, die Feststell-Taste (Caps Lock) mittels SendKeys zu senden (bzw. zu drücken):

SendKeys "{CAPSLOCK}"

Allerdings wird nichts passieren, wenn Sie diese Anweisung ausführen. Es liegt nicht etwa daran, weil der Tastencode "CAPSLOCK" falsch wäre (er existiert sehr wohl) oder weil die Feststell-Taste zwei Zustände Ein/Aus haben kann (auch die Druck-Taste funktioniert nicht). Der Grund ist ganz einfach, dass die aktive Anwendung mit der Feststell-Taste nichts anfangen und daher nicht verarbeiten kann. Nur das Betriebssystem - im Falle von VBA ist dies gewöhnlich Windows - kann diese Taste verarbeiten. Weil aber mit SendKeys Tasten immer an das aktive Anwendungsfenster gesendet werden und nie an Windows, funktioniert die obige VBA-Anweisung nicht.

Zum Anfang

 


Die verschiedenen Möglichkeiten zum Senden von Tastenfolgen

Sinn und Zweck von SendKeys

SendKeys sendet Tastenfolgen an die aktive Anwendung bzw. das aktive Fenster. Die Methode SendKeys des Application-Objektes von Excel (Application.SendKeys) besitzt grundsätzlich den gleichen Zweck, besitzt allerdings ein paar kleine Unterschiede. Mit DDEExecute kann man ebenfalls Tastenanschläge an eine andere Anwendung senden.

Zum Anfang


SendKeys (VBA-Anweisung)

Syntax
SendKeys string[, wait]

Die Syntax der SendKeys-Anweisung verwendet die folgenden benannten Argumente:

Argument

Beschreibung

string Erforderlich. Ein Zeichenfolgenausdruck, der die zu sendende Tastenfolge angibt.
wait Optional. Ein Wert vom Typ Boolean, der den Wartemodus angibt. Wenn der Wert False ist (Voreinstellung), setzt die Prozedur die Ausführung fort, unmittelbar nachdem die Tastenfolge gesendet wurde. Wenn der Wert True ist, muss die Tastenfolge verarbeitet werden, bevor die Prozedur die Ausführung fortsetzen kann.

Bemerkungen
Jede Taste wird durch mindestens ein Zeichen repräsentiert. Ein einzelnes Zeichen auf der Tastatur kann mit dem Zeichen selbst angegeben werden. "A" für das Argument string repräsentiert beispielsweise den Buchstaben A. Sie geben mehrere Zeichen an, indem Sie die Zeichen aneinanderhängen. "ABC" für string repräsentiert zum Beispiel die Buchstaben A, B und C.

Das Pluszeichen (+), Caret-Zeichen (^), Prozentzeichen (%), die Tilde (~) und die Klammern ( ) haben bei der SendKeys-Anweisung eine spezielle Bedeutung. Sie müssen jedes dieser Zeichen in geschweifte Klammern einschliessen ({}), um es verwenden zu können. Für das Pluszeichen geben Sie beispielsweise {+} an. Eckige Klammern ([ ]) haben bei der SendKeys-Anweisung zwar keine spezielle Bedeutung, müssen aber auch in geschweifte Klammern eingeschlossen werden, da sie in anderen Anwendungen eine spezielle Bedeutung haben, insbesondere im Zusammenhang mit dynamischem Datenaustausch (DDE). Die Zeichen für die geschweiften Klammern legen Sie unter Verwendung von {{} und {}} fest.

Für Zeichen, die beim Drücken einer Taste nicht angezeigt werden (z.B. die EINGABETASTE oder TAB-TASTE) und für bestimmte Aktionstasten können Sie die folgenden Codes verwenden:

Taste

Code

RÜCKTASTE {BACKSPACE}, {BS} oder {BKSP}
PAUSE {BREAK}
FESTSTELLTASTE {CAPSLOCK}
ENTF {DELETE} oder {DEL}
NACH-UNTEN {DOWN}
ENDE {END}
EINGABETASTE {ENTER} oder ~
ESC {ESC}
HILFE {HELP}
POS 1 {HOME}
EINFG {INSERT} oder {INS}
NACH-LINKS {LEFT}
NUM-FESTSTELL {NUMLOCK}
BILD-AB {PGDN}
BILD-AUF {PGUP}
DRUCK {PRTSC}
NACH-RECHTS {RIGHT}
ROLLEN-FESTSTELL {SCROLLLOCK}
TAB-TASTE {TAB}
NACH-OBEN {UP}
F1 {F1}
F2 {F2}
F3 {F3}
F4 {F4}
F5 {F5}
F6 {F6}
F7 {F7}
F8 {F8}
F9 {F9}
F10 {F10}
F11 {F11}
F12 {F12}
F13 {F13}
F14 {F14}
F15 {F15}
F16 {F16}

Sie können Tastenkombinationen mit der UMSCHALTTASTE, STRG-TASTE oder ALT-TASTE angeben, indem Sie vor dem normalen Tasten-Code einen oder mehrere der folgenden Codes angeben:

Taste

Code

UMSCHALT +
STRG ^
ALT %

Wenn UMSCHALT, STRG und ALT gleichzeitig mit anderen Tasten gedrückt werden müssen, schliessen Sie die Codes für die Tasten in Klammern ein. Wenn zum Beispiel die UMSCHALTTASTE gleichzeitig mit den Tasten E und C gedrückt werden soll, geben Sie "+(EC)" an. Wenn die UMSCHALTTASTE zusammen mit E gedrückt werden soll und im Anschluss daran C ohne UMSCHALTTASTE, geben Sie "+EC" an.

Tastenwiederholungen können Sie in der Form {Taste Zahl} angeben. Das Leerzeichen zwischen Taste und Zahl ist dabei zwingend erforderlich. {LEFT 42} wird zum Beispiel als 42-maliges Drücken der NACH-LINKS-TASTE interpretiert, {h 10} als 10-maliges Drücken der Taste H.

Anmerkung
SendKeys kann keine Tastenanschläge an Anwendungen senden, die nicht unter Microsoft Windows oder auf dem Macintosh ausgeführt werden können. SendKeys kann auch die DRUCK-TASTE {PRTSC} an keine Anwendung senden.

Zum Anfang


Application.SendKeys (Objekt-Methode)

Syntax
Ausdruck.SendKeys(Keys, Wait)

Ausdruck: Ein optionaler Ausdruck, der ein Application-Objekt zurückgibt.

Keys: Variant erforderlich. Die Taste oder Tastenkombination, die Sie als Zeichenfolge an die Anwendung senden möchten.

Wait: Variant optional. Falls True, wartet Microsoft Excel das Ende der Verarbeitung ab, bevor die Steuerung an das Makro zurückgegeben wird. False oder keine Angabe führt das Makro weiter aus, ohne auf einen Tastenkombination zu warten.

 

Anmerkungen
Diese Methode schreibt die Tastenkombination in einen Tastenpuffer. In einigen Fällen müssen Sie diese Methode vor der Methode aufrufen, die die Tastenkombination verarbeitet. Wenn Sie z.B. ein Kennwort an ein Dialogfeld senden möchten, müssen Sie zuerst die SendKeys-Methode aufrufen, bevor Sie das Dialogfeld anzeigen.

Das Argument Keys kann eine einzelne Taste oder eine Taste kombiniert mit einer oder mehreren der Tasten ALT, STRG oder UMSCHALT sein. Jede Taste wird durch ein oder mehrere Zeichen dargestellt, wie z.B. "a" für das Zeichen a oder "{EINGABE}" für die EINGABETASTE.

Wenn Sie Zeichen angeben möchten, die beim Drücken der entsprechenden Taste nicht angezeigt werden (z. B. EINGABE oder TAB), verwenden Sie die Codes aus der folgenden Tabelle. Jeder Code in der Tabelle steht für eine Taste auf der Tastatur.

Taste

Code

RÜCKTASTE {RÜCKTASTE} oder {RÜCK}
UNTBR oder BREAK {UNTBR}
FESTSTELLTASTE {FESTSTELLTASTE}
CLEAR oder LÖSCHTASTE {SÄUBERN}
ENTF oder LÖSCH {ENTF} oder {LÖSCH}
NACH-UNTEN {UNTEN}
ENDE {ENDE}
EINGABETASTE (Ziffernblock) {EINGABE}
EINGABETASTE ~ (Tilde)
RETURNTASTE {EINGABE}
ESC {ESCAPE} oder {ESC}
HILFE {HILFE}
POS1 {POS1}
EINFG {EINFG}
NACH-LINKS {LINKS}
NUM {NUMFT}
BILD-AB {BILDU}
BILD-AUF {BILDO}
NACH-RECHTS {RECHTS}
ROLLEN oder SCROLL {UNTERBR}
TAB {TAB}
NACH-OBEN {OBEN}
F1 bis F15 {F1} bis {F15}

Sie können jede beliebige Tastenkombination mit UMSCHALT, STRG und ALT angeben. Kombinieren Sie eine Taste mit einer oder mehreren anderen Tasten entsprechend der folgenden Tabelle.

Kombinieren mit

Vorangestelltes Zeichen

UMSCHALT + (Pluszeichen)
STRG ^ (Caret-Zeichen)
ALT % (Prozentzeichen)

Zum Anfang


Application.DEExecute (Objekt-Methode)

Syntax
Ausdruck.DDEExecute(Channel, String)

Ausdruck   Optional. Ein Ausdruck, der ein Application-Objekt zurückgibt.
Channel   Long erforderlich. Die Kanalnummer, die von der DDEInitiate-Methode zurückgegeben wird.
String   String erforderlich. Die Nachricht, die in der empfangenden Anwendung definiert wurde.

Anmerkungen
Die DDEExecute-Methode dient dazu, Befehle an eine andere Anwendung zu senden. Mit Hilfe dieser Methode lassen sich auch Tastenanschläge an die andere Anwendung senden, obwohl für diesen Zweck die SendKeys-Methode geeigneter ist. Das String-Argument kann jede einzelne Taste angeben, die mit ALT, STRG oder UMSCHALT sowie jeder Kombination dieser Tasten kombiniert wird. Jede Taste wird durch ein oder mehrere Zeichen repräsentiert, etwa "a" für das Zeichen a, oder "{ENTER}" für die EINGABETASTE.

Zur Angabe von Zeichen, die beim Drücken der entsprechenden Taste nicht angezeigt werden (z. B. EINGABE oder TAB), verwenden Sie die in der Tabelle unten angeführten Codes. Jeder Code in der Tabelle repräsentiert eine Taste auf Ihrer Tastatur.

Taste

Code

RÜCKTASTE {RÜCKTASTE} oder {RÜCK}
UNTBR {UNTBR}
FESTSTELLTASTE {FEST}
CLEAR oder LÖSCHTASTE {SÄUBERN}
LÖSCH oder ENTF {ENTF} oder {LÖSCH}
NACH-UNTEN {UNTEN}
ENDE {ENDE}
EINGABETASTE (Zehnertastatur) {EINGABE}
EINGABETASTE ~ (Tilde)
ESC {ESCAPE} oder {ESC}
HILFE {HILFE}
POS1 {POS1}
EINFG {EINFG}
NACH LINKS {LINKS}
NUM {NUMFT}
BILD-AB {BILDU}
BILD-AUF {BILDO}
RETURNTASTE (Macintosh) {EINGABE}
NACH RECHTS {RECHTS}
ROLLEN {ROLLEN}
TAB {TAB}
NACH OBEN {OBEN}
F1 bis F15 {F1} bis {F15}

Sie können zudem Tasten angeben, die mit UMSCHALT und/oder STRG und/oder ALT kombiniert sind. Um eine Taste anzugeben, die mit einer oder mehreren der oben erwähnten Tasten kombiniert wird, verwenden Sie die folgende Tabelle.

Kombination mit

Vorangestelltes Zeichen

UMSCHALT + (Pluszeichen)
STRG oder CTRL ^ (Caret-Zeichen)
ALT % (Prozentzeichen)

Zum Anfang

 


Technische Informationen zu SendKeys, Application.SendKeys und DDEExecute

SendKeys (VBA-Anweisung)

SendKeys ist eine Anweisung die zum Sprachumfang von VBA gehört. Die SendKeys-Anweisung ist allerdings keine Core-Anweisung von VBA (d.h. keine Anweisung, die zum Kernumfang der Sprache gehört) wie beispielsweise die Anweisungen "For...Next", "Exit" oder "End". SendKeys ist in der Objektbibliothek von VBA (genau wie Excel besitzt auch VBA eine Objektbibliothek) definiert, und zwar im Modul "Interaction" (Achtung: Interaction ist ein Modul und keine Klasse). Das Interaction-Modul enthält VBA-Anweisungen wie unter anderem "AppActivate", "CreateObject", "MsgBox" und "Shell", also alles Anweisungen, die eine Interaktion mit dem Benutzer oder mit einer Anwendung bezwecken.

Library
VBA

Path
D:\Programme\Gemeinsame Dateien\Microsoft Shared\VBA\VBA332.dll

Description
Visual Basic For Applications

Module
Interaction

Syntax
SendKeys(String As String, [Wait])

Samples
SendKeys

Interaction.SendKeys
VBA.Interaction.SendKeys
VBA.SendKeys

Zum Anfang


Application.SendKeys (Methode des Application-Objektes)

Application.SendKeys gehört zum Sprachumfang von Excel-VBA. Die SendKeys-Methode ist in der Objektbibliothek von Microsoft Excel definiert, und zwar in der Klasse Application.

Library
Excel

Path
D:\Programme\Microsoft Office\Office\EXCEL8.OLB

Description
Microsoft Excel 8.0 Object Library

Class
Application (Global)

Syntax
SendKeys(Keys, [Wait])

Samples
Application.SendKeys
Excel.Application.SendKeys
Excel.SendKeys
Excel.Global.SendKeys
Excel.Global.Application.SendKeys

Zum Anfang

 


SendKeys oder Application.SendKeys oder DDEExecute verwenden?

Unterschiede zwischen SendKeys und Application.SendKeys

Die SendKeys-Anweisung von VBA und die SendKeys-Methode des Application-Objektes von Excel sind an sich identisch. Allerdings können Sie SendKeys und Application.SendKeys in einem VBA-Programm nicht ohne weiteres austauschen. Ich habe unzählige Tests mit beiden Anweisungen durchgeführt und insbesondere drei markante Unterschiede festgestellt:

  1. Die VBA-Anweisung SendKeys verwendet englische Bezeichnungen für die Tastencodes. Die SendKeys-Methode von Excel dagegen verwendet deutsche Abkürzungen.

  2. Enter-Taste ist nicht gleich Enter-Taste. Wie in Punkt 1 erwähnt, werden deutsche oder englische Tastencodes verwendet. Der Code {ENTER} darf nicht mit {EINGABE} gleichgesetzt werden. Der Tastencode {EINGABE} steht für die Eingabetaste der Zehnertastatur. Auch wenn diese Eingabetaste in der Empfänger-Anwendung den genau gleichen Zweck wie die Eingabetaste der Alpha-Tastatur besitzt, verhält sie sich bei Application.SendKeys anders.

  3. Ein auf True gestellter Wait-Parameter funktioniert bei Application.SendKeys je nach Windows-Version nur eingeschränkt oder sogar überhaupt nicht. Das Argument "Wait:=True" von SendKeys funktioniert dagegen in jeder Situation korrekt.

Damit man sich diese Unterschiede besser vorstellen kann, nachfolgend ein kleiner Praxis-Test mit ein paar VBA-Beispielen zu den obigen Punkten 1 und 2.

Zum Anfang


Ein kleiner Praxis-Test

Testvorbereitung

1. Starten Sie zuerst den Windows Editor (Notepad.exe).

2. Geben Sie die Ziffern 0 bis 9 sowie einen Leerschlag ein, d.h. "0123456789 ". Lassen Sie nach der Eingabe den Textcursor einfach stehen, sodass er nach dem Leerzeichen blinkt. Drücken Sie nicht die Enter-Taste. Speichern Sie auch nicht (es ist wichtig, dass im Fenstertitel "Unbenannt" steht).

SendKeys-Demo

 

Schritt 1: Testen von SendKeys

Führen Sie das Makro NotepadSendKeysTest1 aus. Das Makro sendet diese Tastenfolgen insgesamt 10 mal: Menübefehl Bearbeiten/Alles markieren, Menübefehl Bearbeiten/Kopieren, Tasten Pfeil nach unten und Eingabe, Menübefehl Bearbeiten/Einfügen.

Sub NotepadSendKeysTest1()
  Dim intCounter As Integer
  AppActivate "Unbenannt", True

  For intCounter = 1 To 10
    SendKeys "%(BM)", True
    SendKeys "%(BK)", True
    SendKeys "{DOWN}{ENTER}", True
    SendKeys "%(BE)", True
  Next intCounter
End Sub

Sobald die Makroausführung beendet ist, sehen Sie im Editor den eingegebenen Text "0123456789 ", der mehrmals untereinander aufgelistet ist:

SendKeys-Demo

 

Schritt 2: Testen von Application.SendKeys

Löschen Sie den Inhalt des Notizblocks (Menübefehl Datei/Neu) und geben Sie den Text "0123456789 " erneut ein. Führen Sie jetzt das Makro NotepadSendKeysTest2 aus. Dieses Makro macht genau das gleiche wie das erste Makro, mit dem einzigen Unterschied, dass Application.SendKeys anstatt SendKeys benutzt wird.

Sub NotepadSendKeysTest2()
  Dim intCounter As Integer
  AppActivate "Unbenannt", True

  For intCounter = 1 To 10
    Application.SendKeys "%(BM)", True
    Application.SendKeys "%(BK)", True
    Application.SendKeys "{DOWN}{ENTER}", True
    Application.SendKeys "%(BE)", True
  Next intCounter
End Sub

Sobald die Makroausführung fertig ist, sehen Sie im Editor den eingegebenen Text "0123456789 ", der mehrmals nebeneinander steht:

SendKeys-Demo

Das zweite Makro führt zu einem anderen Ergebnis als das erste Makro. Und dies, obwohl lediglich Application.SendKeys anstelle von SendKeys benutzt wird.

Der Grund für das abweichende Ergebnis liegt an den verwendeten Tastencodes. Die SendKeys-Methode verwendet im Gegensatz zur SendKeys-Anweisung deutsche Abkürzungen. Mit den beiden Codes {DOWN} und {ENTER} kann sie nichts anfangen. Unschön finde ich, dass diese Tastencodes einfach übergangen werden, das heisst ohne eine Fehler- oder Hinweismeldung nicht verarbeitet werden. Zumindest ist jetzt klar, warum der Text nebeneinander und nicht untereinander erscheint: Das {ENTER} wurde nicht verarbeitet und folglich keine Zeilenschaltung eingefügt.

 

Schritt 3: Testen von Application.SendKeys (zweiter Versuch)

Löschen Sie wieder den Inhalt des Editors und erfassen den Text "0123456789 ". Starten Sie nun das Makro NotepadSendKeysTest3. Dieses Makro entspricht dem zweiten Makro. Lediglich die Tastencodes {DOWN} und {ENTER} wurden mit {UNTEN} bzw. {EINGABE} übersetzt.

Sub NotepadSendKeysTest3()
  Dim intCounter As Integer
  AppActivate "Unbenannt", True

  For intCounter = 1 To 10
    Application.SendKeys "%(BM)", True
    Application.SendKeys "%(BK)", True
    Application.SendKeys "{UNTEN}{EINGABE}", True
    Application.SendKeys "%(BE)", True
  Next intCounter
End Sub

Nach Ausführung des Makros sehen Sie dieses Bild im Editor:

SendKeys-Demo

Im Notizblock steht der Text wieder nebeneinander anstatt untereinander - obwohl deutschsprachige Tastencodes verwendet wurden. Wo liegt der Fehler? Nun, der Fehler liegt an der Übersetzung des englischen Tastencodes {ENTER}. Der Code {ENTER} steht sowohl für die Eingabetaste der alphanummerischen Tastatur als auch für die Eingabetaste der Zehnertastatur. Der deutsche Code {EINGABE} dagegen bezeichnet nur die Eingabetaste der Zehnertastatur. Für die Eingabetaste der Alpha-Tastatur muss das "~"-Zeichen (Tilde) benutzt werden, und zwar ohne das geschweifte Klammernpaar "{}".

 

Schritt 4: Testen von Application.SendKeys (dritter Versuch)

Das korrekte Makro mit Application.SendKeys muss folgedessen so aussehen:

Sub NotepadSendKeysTest4()
  Dim intCounter As Integer
  AppActivate "Unbenannt", True

  For intCounter = 1 To 10
    Application.SendKeys "%(BM)", True
    Application.SendKeys "%(BK)", True
    Application.SendKeys "{UNTEN}~", True
    Application.SendKeys "%(BE)", True
  Next intCounter
End Sub

Wenn Sie dieses Makro ausführen, erhalten Sie das gleiche Ergebnis wie beim ersten Makro "NotepadSendKeysTest1", nämlich den untereinander aufgelisteten Text "0123456789 ".

 

Zusammenfassung

Wie man erkennen kann, ist das Austauschen von SendKeys durch Application.SendKeys nicht ganz so einfach wie es zuerst aussieht.

Zum Anfang


Unterschiedliches Verhalten je nach Windows-Version

Das Verhalten der beiden Befehle SendKeys und Application.SendKeys ist nicht immer gleich, da der - bei beiden Anweisungen existierende - Wait-Parameter je nach Betriebssystem (Windows-Version) unterschiedlich reagiert.

Windows-Version Empfohlene Anweisung Wait-Parameter Beispiel (Neuberechnung auslösen)
Windows 95 SendKeys True SendKeys "%^{F9}", True
Windows 98 SendKeys True SendKeys "%^{F9}", True
Windows ME SendKeys True SendKeys "%^{F9}", True
Windows NT Application.SendKeys False Application.SendKeys "%^{F9}":DoEvents
Windows 2000 Application.SendKeys False Application.SendKeys "%^{F9}":DoEvents
Windows XP Application.SendKeys False Application.SendKeys "%^{F9}":DoEvents

Zum Anfang


Verwendung von DoEvents

DoEvents übergibt wie allgemein bekannt ist die Ablaufsteuerung an das Betriebssystem. Das Programm erhält erst dann die Steuerung wieder zurück, wenn das Betriebssystem alle wartenden Ereignisse verarbeitet hat und alle wartenden Tastenanschläge in der SendKeys-Warteschlange abgearbeitet sind.

In der VBA-Hilfe steht, dass der Wait-Parameter der SendKeys-Methode - wenn auf True gesetzt - die vollständige Verarbeitung der Tastenanschläge abwartet (d.h. Application.SendKeys "...", True). Das kann man vergessen. Ich hab's in Excel 97 unter Windows NT 4 getestet: Funktioniert nicht. Daher die obige Lösung mit dem DoEvents. Bei "Wait:=True" wird die Steuerung erst wieder an das Makro übergeben, wenn Excel mit der Verarbeitung fertig ist. Das klappt jedoch bei präemptiven Multitasking-System wie Windows NT 4, Windows 2000 und Windows XP nicht, da nicht der ausgeführte Task den Zeitpunkt der Rückgabe bestimmen kann. Das entscheided bei diesen Betriebssystemen ein spezieller Systemprozess (der sogenannte "Scheduler").

Zum Anfang


Was bewirkt der Wait-Parameter von SendKeys?

Mit dem Wait-Parameter wird gesteuert, wann der Programmcode weiter ausgeführt wird:

Wie im vorangegangenen Abschnitt über die Unterschiede bereits kurz erwähnt wurde, verhält sich der auf True eingestellte Wait-Parameter der beiden Anweisungen je nach Windows-Version nicht immer gleich. Während mit "SendKeys "<Taste>", True" die Verarbeitung der gesendeten Tasten korrekt abgewartet wird, wird bei "Application.SendKeys "<Taste>", True" das VBA-Programm zu früh fortgeführt bzw. keine Pause eingelegt.

 

Ein praktisches Beispiel

Anhand eines kleines VBA-Beispiels lässt sich Zweck des Wait-Parameters gut erkennen. Starten Sie zuerst den Windows Editor (Notepad) und führen dann dieses Makro im VBA-Editor aus:

Sub NotepadTest()
  AppActivate "Unbenannt"
  SendKeys "Hallo", True

End Sub

Als Resultat sollten Sie das geöffnete Notepad mit dem Wort "Hallo" auf dem Bildschirm sehen. Im Programm wurde der Wait-Parameter auf True gestellt. Das Makro wurde somit erst weiter ausgeführt, nachdem alle Tastenanschläge (d.h. alle fünf Buchstaben des Wortes "Hallo") verarbeitet wurden. Da nach der SendKeys-Anweisung das Makro zu Ende war, also keine weiteren Befehle ausser dem "End Sub" (der das Makroende kennzeichnet), blieb der Fokus beim Notepad-Anwendungsfenster.

Nun wird Wait auf False gesetzt und das Makro nochmals ausgeführt. Löschen Sie aber zuerst das "Hallo" aus dem Notepad, sodass Sie wieder eine leere Seite sehen.

Sub NotepadTest()
  AppActivate "Unbenannt"
  SendKeys "Hallo", False

End Sub

Nach diesem Makro sehen Sie anstelle des Notepads den VBA-Editor vor sich. Wenn Sie zum Notepad wechseln, werden Sie lediglich den Buchstaben "H" des Wortes "Hallo" im Textdokument vorfinden. Wegen dem auf False gestellten Wait-Parameter hat das Makro nicht gewartet, bis alle Buchstaben an das Notepad übermittelt wurden. Doch wo sind die restlichen vier Buchstaben "allo" geblieben? Nun, da nach Senden des ersten Buchstabens das Makro bereits wieder die Kontrolle übernahm, sprich den Fensterfokus zurückerhielt, hat das Makro die restlichen Buchstaben quasi sich selbst geschickt! Das gesuchte "allo" wurde in ein Fenster des VBA-Editors eingefüllt, und zwar genau an der Stelle, wo sich der Textcursor befand, als das Makro gestartet wurde.

Zum Anfang


Wann muss der Wait-Parameter auf True gesetzt werden?

Ob die Verarbeitung der gesendeten Tastenfolgen abgewartet werden muss oder nicht, was mit dem Wait-Parameter von SendKeys gesteuert wird, lässt sich anhand von Situationen aus der Praxis gut erkennen. Diese Situationen werden im nächsten Kapitel So sendet man Tastenanschläge anhand verschiedener Beispiele erläutert.

Zum Anfang

 


So sendet man Tastenanschläge

Tastenanschläge zur Steuerung einer Dialogmaske an Excel senden

Aktion VBA-Anweisung SendKeys Wait Beispiel
Dialog wird mittels Dialogs-Auflistung geöffnet Dialogs(...).Show Vor Dialog-Aufruf False SendKeys "%z200"
Application.Dialogs(xlDialogCalculation).Show
Dialog wird mit der speziellen, dafür zuständigen Methode geöffnet Application.GetOpenFilename
Application.GetSaveAsFilename
Application.FindFile
Worksheet.ShowDataForm
Worksheet.CheckSpelling
Range.FunctionWizard
Vor Dialog-Aufruf False SendKeys "%s" & strBegriff & "%t"
Worksheet.ShowDataForm
Dialog wird durch Simulation eines Klicks auf eine Symbolleisten-Schaltfläche geöffnet CommandBars.FindControl().Execute Vor Dialog-Aufruf False SendKeys "%n" & strID & "{TAB}"
Application.CommandBars.FindControl _
   (Id:=860).Execute
Dialog wird durch eine sonstige Methode geöffnet, die ihrerseits den Dialog einblendet Workbooks.Open mit einer kennwortgeschützten Mappe Vor Dialog-Aufruf False SendKeys "Heute"
Workbooks.Open "D:\Kennwort.xls"
Dialog wird mit einer Funktionstaste oder Tastaturabkürzung geöffnet SendKeys - True SendKeys "{F5}", True
Dialog wird über einen Menübefehl geöffnet SendKeys - True SendKeys "%di", True

Zum Anfang


Sonstige Tastenanschläge an Excel senden

Aktion Wait-Parameter Bemerkung Beispiel
Makro wird in der VBE gestartet Immer True, egal ob weitere Codezeilen nach SendKeys folgen oder nicht Excel muss immer zuerst mit AppActivate aktiviert werden

Wait muss immer True sein, egal ob nach SendKeys weitere Befehle folgen oder nicht

Sub OpenNamesDialog()
  AppActivate "Microsoft Excel"
  SendKeys "^{F3}", True

  'Evtl. weiterer Code...
End Sub
Makro wird in Excel gestartet False oder True, wenn Makro nach SendKeys beendet ist - Sub OpenNamesDialog()
  SendKeys "^{F3}"
End Sub
Makro wird in Excel gestartet False, wenn die Codezeilen nach SendKeys ausgeführt werden müssen - Sub OpenNamesDialog()
  SendKeys "^{F3}"

  Application.StatusBar = "Name wählen"
End Sub
Makro wird in Excel gestartet False, wenn die Codezeilen nach SendKeys ausgeführt werden dürfen - Sub OpenNamesDialog()
  SendKeys "^{F3}"

  intZahl = intZahl + 1
End Sub
Makro wird in Excel gestartet True, wenn die Codezeilen nach SendKeys nicht ausgeführt werden dürfen - Sub OpenNamesDialog()
  SendKeys "^{F3}", True

  Application.StatusBar = "Name ok"
End Sub

Zum Anfang


Tastenfolgen an eine andere Anwendung senden

Aktion Wait Bemerkung Beispiel
Makro wird in der VBE mit F5 gestartet True Die Anwendung muss immer zuerst mit AppActivate aktiviert werden Sub OpenNamesDialog()
  AppActivate "Explorer"
  SendKeys "a", True

End Sub

Zum Anfang

 


Einschränkungen und Grenzen von SendKeys

Nicht unterstützte Tasten

SendKeys besitzt ein paar Einschränkungen. Nicht alle auf einer PC- oder Mac-Tastatur angeordneten Tasten können mit SendKeys aufgerufen werden, sprich lassen sich an eine Anwendung senden.

Hier eine Liste der nicht unterstützten Tasten mit den Tastencodes:

Taste

Code

FESTSTELLTASTE {CAPSLOCK}
HILFE {HELP}
NUM-FESTSTELL {NUMLOCK}
DRUCK {PRTSC}
ROLLEN-FESTSTELL {SCROLLLOCK}

Zudem können die Spezialtasten einer Tastatur, wie unter anderem
- SysRq (System Request),
- Pause und
- die beiden Windows-Tasten (links und rechts der Leertaste),
nicht mit SendKeys angesprochen werden.

Zum Anfang


Umgehungslösung für nicht unterstützte Tasten

Mit dem nachfolgenden VBA-Programmcode kann beispielsweise die CapsLock-Taste umgeschaltet werden:

Private Const VER_PLATFORM_WIN32_NT = 2
Private Const VER_PLATFORM_WIN32_WINDOWS = 1
Private Const VK_CAPITAL = &H14
Private Const KEYEVENTF_EXTENDEDKEY = &H1
Private Const KEYEVENTF_KEYUP = &H2

Private Type OSVERSIONINFO
  dwOSVersionInfoSize As Long
  dwMajorVersion As Long
  dwMinorVersion As Long
  dwBuildNumber As Long
  dwPlatformId As Long
  szCSDVersion As String * 128
End Type

Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" _
  (lpVersionInformation As OSVERSIONINFO) As Long
Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan _

  As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
Private Declare Function GetKeyboardState Lib "user32" (pbKeyState As Byte) As Long
Private Declare Function SetKeyboardState Lib "user32" (lppbKeyState As Byte) As Long

Public Sub ToggleCapsLock(TurnOn As Boolean)
  'To turn Caps Lock on, set TurnOn to True
  'To turn Caps Lock off, set TurnOn to False

  Dim bytKeys(255) As Byte
  Dim bCapsLockOn As Boolean
  Dim typOS As OSVERSIONINFO

  'Get state of the 256 virtual keys
  GetKeyboardState bytKeys(0)

  bCapsLockOn = bytKeys(VK_CAPITAL)

  If bCapsLockOn <> TurnOn Then   'If current state <> requested state
    If typOS.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS Then   
'=== Win95/98
      bytKeys(VK_CAPITAL) = 1
      SetKeyboardState bytKeys(0)
    Else   '=== WinNT/2000
      'Simulate Key Press
      keybd_event VK_CAPITAL, &H45, KEYEVENTF_EXTENDEDKEY Or 0, 0
      'Simulate Key Release
      keybd_event VK_CAPITAL, &H45, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0
    End If
  End If
End Sub

 

Public Sub PressAstericsKey()
  Dim bytKeys(255) As Byte
  Dim typOS As OSVERSIONINFO

  If typOS.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS Then   '=== Win95/98
    bytKeys(VK_ASTERICS) = 1
    SetKeyboardState bytKeys(0)
  Else  
'=== WinNT/2000
    keybd_event VK_ASTERICS, &H45, KEYEVENTF_EXTENDEDKEY Or 0, 0
    keybd_event VK_ASTERICS, &H45, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0
  End If
End Sub

 

Zum Anfang

 


Bestimmen der Ausführungsumgebung (Excel oder VBE)

Wie in einem Kapitel weiter oben bereits erwähnt wurde, kann ein Makro, welches mittels SendKeys Tastenfolgen an Microsoft Excel sendet, nicht so ohne weiteres im VBA-Editor bzw. aus dem VBA-Editor heraus gestartet werden. Das funktioniert aus zwei Gründen nicht:

  1. Das Anwendungsfenster von Excel muss zuerst aktiviert werden, da ansonsten die Tastenfolgen von der VBE empfangen werden und nicht von Excel.

  2. Nach Beendigung der Makroausführung wird automatisch zur VBE zurückgekehrt. Das darf erst erfolgen, nachdem alle Tastenfolgen von Excel verarbeitet wurden. Anderenfalls kann es passieren, dass zu früh zum VBA-Editor gewechselt wird und somit einzelne noch anstehende Tastenfolgen in der VBE verarbeitet werden.

Die beiden obigen Punkte bedeuten nichts anderes, als dass die Anweisung AppActivate und die Parameter-Einstellung "Wait:=True" verwendet werden müssen, wenn das Makro in der VBE gestartet wird. Damit ein und dasselbe Makro sowohl aus der VBE als auch aus Excel heraus gleichermassen funktioniert, bedient man sich am besten einer globalen Variablen, mit welcher man den Makroablauf komfortabel steuern kann.

VBA-Programmcode
Hier der entsprechende VBA-Code zum Aktivieren des Office-Programmes:

Public RunInVBE as Boolean

Sub OpenNamesDialog()
  If RunInVBE = True Then
    AppActivate "Microsoft Excel"

  End If
  SendKeys "^{F3}", RunInVBE
End Sub

Die globale Variable RunInVBE steuert den einzuschlagenden Makroablauf. Wenn das Makro in der VBE ausgeführt wird, muss RunInVBE auf True gesetzt werden. Dadurch weiss das Makro, dass vor dem SendKeys die Anwendung Excel aktiviert (Codezeile mit der AppActivate-Anweisung) und auf die vollständige Abarbeitung der Tastenfolgen gewartet werden muss (der Wait-Parameter von SendKeys steht auf RunInVBE, wobei RunInVBE den Wert True besitzt).

Zum Anfang

 


Empfänger-Anwendung starten und aktivieren

Anwendung starten mit "Shell"

Shell startet eine Anwendung asynchron und gibt die Task-ID der ausgeführten Anwendung zurück. Asynchron bedeutet, dass das VBA-Programm weiterläuft, während Windows die Anwendung startet. Es kommt häufig vor, dass in einer VBA-Codezeile eine Anwendung mittels Shell gestartet wird und unmittelbar danach, in der nächsten Codezeile, auf eben diese Anwendung zugegriffen werden soll (z.B. mit AppActivate, SendKeys oder dergleichen). Wenn die zu startende Anwendung sehr klein ist, oder die Anwendungsdatei (exe) auf einer lokalen Festplatte liegt, oder wenn sich die Anwendung noch im Arbeitsspeicher befindet, so startet sie sofort und ist folgedessen augenblicklich bereit, wenn die Codezeile nach der Shell-Funktion ausgeführt wird. Benötigt jedoch die Anwendung zum vollständigen Aufstarten etwas mehr Zeit, so ist sie noch nicht bereit, wenn die Codezeile nach der Shell-Funktion ausgeführt wird.

Zum Anfang

 


Anwendung aktivieren mit "AppActivate"

Die von Shell gelieferte Task-ID ist nützlich, wenn die Anwendung mit AppActivate aktiviert werden soll. Der AppActivate-Anweisung kann anstelle des Fenstertitels der Anwendung nämlich die Task-ID mitgegeben werden. Leider funktioniert die Aktivierung mittels Task-ID in der Praxis je nach Empfänger-Anwendung nicht in jeder Situation und nicht bei jeder Anwendung.

Die folgende Tabelle zeigt das Verhalten verschiedener Windows-Programme:

Anwendung Aktivierung mittels Task-ID Codebeispiel
Calculator (Rechner) Funktioniert korrekt TaskID = Shell("calc.exe", vbNormalFocus)
AppActivate TaskID
Paint/Paint Brush Funktioniert korrekt TaskID = Shell("mspaint.exe", vbNormalFocus)
AppActivate TaskID
Registry Editor Funktioniert korrekt bei der ersten Aktivierung
Funktioniert nicht korrekt bei allen weiteren Aktivierungen
TaskID = Shell("regedit.exe", vbNormalFocus)
AppActivate TaskID
Explorer Funktioniert nicht immer korrekt [* siehe Hinweis] TaskID = Shell("explorer.exe", vbNormalFocus)
AppActivate TaskID
Notepad (Editor) Funktioniert korrekt TaskID = Shell("notepad.exe", vbNormalFocus)
AppActivate TaskID
WordPad Funktioniert nicht korrekt TaskID = Shell("write.exe", vbNormalFocus)
AppActivate TaskID
CD Player Funktioniert korrekt bei der ersten Aktivierung
Funktioniert nicht korrekt bei allen weiteren Aktivierungen
TaskID = Shell("cdplayer.exe", vbNormalFocus)
AppActivate TaskID
Clock (Uhr) Funktioniert korrekt TaskID = Shell("clock.exe", vbNormalFocus)
AppActivate TaskID
CharMap (Zeichentabelle) Funktioniert korrekt TaskID = Shell("charmap.exe", vbNormalFocus)
AppActivate TaskID
Event Viewer (Ereignisanzeige) Funktioniert korrekt TaskID = Shell("eventvwr.exe", vbNormalFocus)
AppActivate TaskID
User Manager (Benutzerverwaltung) Funktioniert korrekt TaskID = Shell("musrmgr.exe", vbNormalFocus)
AppActivate TaskID
Task Manager Funktioniert korrekt bei der ersten Aktivierung
Funktioniert nicht korrekt bei allen weiteren Aktivierungen
TaskID = Shell("taskmgr.exe", vbNormalFocus)
AppActivate TaskID

* Hinweis zum Starten des Windows Explorers
Beschreibung folgt...

Zum Anfang

 


Anwendung starten und aktivieren mit "ActivateMicrosoftApp"

Muss mit Excel-VBA eine andere Office-Anwendung gestartet werden, bedient man sich häufig der Shell-Funktion von VBA. Damit die Anwendung jedoch gestartet werden kann, muss der Shell-Funktion der genaue Pfad der ausführbaren Datei (.exe) mitgegeben werden. Solange die zu startende Anwendung aus der gleichen Office-Version wie Excel stammt, könnte man behelfsmässig den Pfad von Excel verwenden (d.h. Application.Path) und voraussetzen, dass die exe-Datei der anderen Anwendung im gleichen Verzeichnis wie Excel.exe steht. Sobald es sich um eine Anwendung einer anderen Office-Version handelt, weicht der Programmpfad sehr wahrscheinlich ab. Damit nicht ein (eher schwierig zu programmierender) Zugriff auf die Windows Registry vorgenommen werden muss, um den Pfad der gesuchten Anwendung herauszufinden, stellt Excel eine spezielle Methode zum Starten von Office-Anwendungen bereit: Die ActivateMicrosoftApp-Methode.

Der wohl grösste Vorteil von ActivateMicrosoftApp ist - verglichen mit der Shell-Funktion - das synchrone Starten der angegebenen Anwendung. Das VBA-Programm läuft somit erst dann weiter, wenn die andere Anwendung vollständig aufgestartet und bereit ist.

VBA-Syntax
  Application.ActivateMicrosoftApp(Index As XlMSApplication)

Konstanten für XlMSApplication
  xlMicrosoftAccess  (Wert 4)
  xlMicrosoftFoxPro  (5)
  xlMicrosoftMail  (3)
  xlMicrosoftPowerPoint  (2)
  xlMicrosoftProject  (6)
  xlMicrosoftSchedulePlus  (7)
  xlMicrosoftWord  (1)

Wenn die als Argument angegebene Office-Anwendung nicht auf der Arbeitsstation installiert ist, erscheint der Laufzeitfehler 1004 mit einem entsprechenden Fehlertext (Beispiel FoxPro for Windows):

FoxPro kann nicht ausgeführt werden
Abbildung: Laufzeitfehler bei nicht auffindbarer Programmdatei foxprow.exe

Zum Anfang

 

Das Geheimnis von ActivateMicrosoftApp

Übrigens besitzt ActivateMicrosoftApp ein gut verstecktes und höchst interessantes Geheimnis: Die beiden boolschen Werte True (Wahr bzw. -1) und False (Falsch bzw. 0) können nebst den XlMSApplication-Konstanten ebenfalls als Argument eingesetzt werden.

Mit der Programmzeile

  Application.ActivateMicrosoftApp False

kann der Taschenrechner von Windows (calc.exe) gestartet werden.

Mit der Codezeile

  Application.ActivateMicrosoftApp True

lässt sich das Kartenspiel Solitär von Windows (sol.exe) ausführen.

 

Handelt es sich um einen Zufall, dass für True bzw. False genau die beiden Programme Solitär bzw. Rechner gewählt wurden? Oder steht vielleicht etwa der Rechner für das "falsche" Programm (symbolisiert die Arbeit), während das Kartenspiel Solitär die "wahre" oder "richtige" Anwendung darstellt (symbolisiert das Spielen/den Spass)?

Der Parameterwert True bzw. -1 ist VBA-intern fix mit der ausführbaren Datei sol.exe des Kartenspiels Solitär verknüpft. Wenn sich weder im Windows- oder Windows System-Verzeichnis noch in den mit der Systemumgebungsvariable "Path" definierten Verzeichnissen eine Datei namens sol.exe befindet, tritt der Laufzeitfehler 1004 auf:

Anwendung SOL.EXE kann nicht gestartet werden
Abbildung: Laufzeitfehler bei nicht auffindbarer Programmdatei sol.exe

Das gleiche gilt für den False bzw. 0; dieser Wert ist fest mit der Datei 'calc.exe' verbunden.

 

XL: Custom Button Images Start Solitaire or Calculator
http://support.microsoft.com/default.aspx?scid=kb;en-us;112374

Zum Anfang

 


Eine alltägliche Aufgabe: Anwendung starten, Fenster aktivieren, Tasten senden

Diese versteckte Möglichkeit zum Starten von Solitär hat mich auf eine Idee gebracht, wie man ein in der Praxis häufig anzutreffende schwierige Aufgabe sehr einfach lösen könnte. Die Aufgabe, die schwierig zu lösen ist, definiert sich wie folgt:
- Eine Nicht-Office-Anwendung soll von einem Server-Laufwerk gestartet werden
- Nach dem Start ist die Anwendung zu aktivieren, damit Tastenfolgen gesendet werden können

Sie fragen sich jetzt vielleicht, wo denn das Problem liegt. Schliesslich muss man lediglich mit Shell die Anwendung starten und dann mit AppActivate den Fokus setzen. Der VBA-Code würde dann lediglich zwei Zeilen umfassen und ungefähr so aussehen:

Sub AnwendungAktivieren()
  x = Shell("P:\Programme\FeuerwehrPlaner.exe", vbNormalFocus)
  AppActivate "Feuerwehr-Planer 1.0 - Administrator"

End Sub

Grundsätzlich haben Sie recht, denn genau so würden viele Programmierer diese Aufgabe lösen. Aber seien Sie auf der Hut! In der Praxis sieht das Ganze nämlich gar nicht mehr so einfach aus. Bis der Programmcode - für diese eigentlich simple Aufgabe - fehlerfrei und stabil läuft, müssen Sie noch ein paar ganz interessante Probleme lösen:
- Woher kennen Sie den bei Shell erforderlichen Pfad zur Anwendung, sprich zur Datei FeuerwehrPlaner.exe?
- Was machen Sie, wenn der Programmstart misslingt (fehlende Berechtigung, Pfad falsch usw.)?
- Nach Shell wird das Makro weiter ausgeführt, ohne den vollständigen Programmstart abzuwarten. AppActivate wird daher höchstwahrscheinlich fehlschlagen. Was können Sie dagegen tun?
- Bei AppActivate ist im Anwendungstitel die Version der Anwendung angegeben. Was tun Sie, wenn die Versionsnummer ändert?
- Bei AppActivate ist ebenfalls im Titel der angemeldete Benutzer mit "Administrator" angegeben. Was machen Sie, damit die Aktivierung bei allen Benutzern funktioniert?

Zum Anfang

 


ActivateMicrosoftApp für eigene Zwecke missbrauchen

Wie unter "Das Geheimnis von ActivateMicrosoftApp" zu lesen ist, können anstelle eines offiziellen Konstantenwertes auch die Werte True oder False als Argument verwendet werden.

- Nach Shell wird das Makro weiter ausgeführt, ohne den vollständigen Programmstart abzuwarten. AppActivate wird daher höchstwahrscheinlich fehlschlagen. Was

Application.ActivateMicrosoftApp True
AppActivate "Feuerwehr"

Zum Anfang

 


Aktivieren einer bereits laufenden Empfänger-Anwendung

Wenn die Empfänger-Anwendung bereits läuft, verfügt man über keine Task-ID (da die Shell-Funktion nicht verwendet wurde, welche die Task-ID liefern würde). In diesem Fall muss man die Anwendung aktiviert werden, indem man AppActivate einsetzt und als Argument den Titel des zu aktivierenden Anwendungsfensters übergibt.

 

VBA-Syntax
  AppActivate Title [, Wait]

Die Syntax der AppActivate-Anweisung verwendet die folgenden benannten Argumente:

Argument

Beschreibung

Title Erforderlich. Ein Zeichenfolgenausdruck, der den Titel in der Titelleiste des zu aktivierenden Anwendungsfensters angibt. Die von der Shell-Funktion zurückgegebene Task-ID kann anstelle von title verwendet werden, um eine Anwendung zu aktivieren.
Wait Optional. Ein Wert vom Typ Boolean, der angibt, ob die aufrufende Anwendung den Fokus hat, bevor sie eine andere Anwendung aktiviert. Beim Wert False (Voreinstellung) wird die angegebene Anwendung mit sofortiger Wirkung aktiviert, auch wenn die aufrufende Anwendung nicht den Fokus hat. Beim Wert True wartet die aufrufende Anwendung, bis sie den Fokus erhält, und aktiviert dann die angegebene Anwendung.

Bemerkungen
Die AppActivate-Anweisung setzt den Fokus auf die angegebene Anwendung oder das angegebene Fenster, hat aber keinen Einfluss darauf, ob diese maximiert oder minimiert dargestellt werden. Das aktivierte Anwendungsfenster verliert den Fokus, wenn der Benutzer das Fenster schliesst oder den Fokus auf ein anderes Fenster setzt. Verwenden Sie die Shell-Funktion, wenn Sie eine Anwendung starten und den Fensterstil festlegen möchten.

Welche Anwendung aktiviert werden soll, wird bestimmt, indem Title mit der Zeichenfolge des Titels jeder einzelnen momentan ausgeführten Anwendung verglichen wird. Wenn es keine genaue Übereinstimmung gibt, wird eine beliebige Anwendung, deren Zeichenfolge mit Title beginnt, aktiviert. Wenn mehr als eine Instanz dieser Anwendung mit Title bezeichnet ist, wird willkürlich eine dieser Instanzen aktiviert.

Zum Anfang

 


Der Wait-Parameter von AppActivate

Die AppActivate-Anweisung wird oft zusammen oder genauer gesagt nach der Shell-Funktion verwendet.

TaskID = Shell("Calc.exe", 1)
AppActivate TaskID, True

Zum Anfang

 


Programm-Stabilität und -Fehlerfreiheit

Makro-Unterbrechung verhindern

Wenn Sie mit SendKeys oder Application.SendKeys arbeiten, ist es wichtig, dass die Ausführung des Programmcodes möglichst nicht unterbrochen wird bzw. nicht unterbrochen werden kann. Insbesondere beim Senden von Tastenfolgen an eine andere Anwendung kann es - untertrieben ausgedrückt - sehr unangenehm sein, wenn das VBA-Programm aufgrund eines Fehlers oder einer Intervention durch den Benutzer irgendwo abbricht. Der Programmabbruch infolge eines Laufzeitfehlers kann man recht einfach abfangen, indem im Code eine Fehlerbehandlungsroutine hinzugefügt wird. Innerhalb des Error Handlers kann fehlerverursachende Situation bereinigt werden, sodass das Programm fortgesetzt werden kann.

 

Weil die zu steuernde Anwendung zum Empfangen von Tastenfolgen aktiviert sein muss, lässt sich die Ausführung eines unterbrochenen VBA-Makros nicht so einfach fortsetzen. Dies, weil man sich bei der weiteren Ausführung des Programmcodes im VBA-Editor befindet, und folgedessen nicht das Fenster der Empfänger-Anwendung aktiv ist sondern das Hauptfenster des VBA-Editors. Die für die korrekte Code-Fortführung benötigte Anweisung AppActivate muss somit zuerst ausgeführt werden.

Ausführung wurde durch den Benutzer unterbrochen
Abbildung: Hinweismeldung "Ausführung des Codes wurde unterbrochen"

Zum Anfang

 


Makro-Abbruch verhindern

Beschreibung folgt...

Anwendung kann nicht mit AppActivate aktiviert werden

-> Laufzeitfehler Nr. 5

Laufzeitfehler 5
Abbildung: Laufzeitfehler 5

Zum Anfang

 


Unterbrochenes Makro fortsetzen

Beschreibung folgt...

Zum Anfang

 


Checkliste für die Programmierung

Diese Checkliste hilft Ihnen bei der Programmierung von Anwendungen, mit denen Sie Tastenfolgen senden. Überprüfen Sie anhand der Fragen, ob allenfalls wichtige Punkte bei der Realisierung ungenügend beachtet oder sogar vergessen wurden.

Nr. Themenbereich Frage Wenn Antwort 'Nein' ist...
1 Programmabbruch verhindern Besitzt die Prozedur einen Error Handler, damit bei Auftreten eines Laufzeitfehlers das Programm nicht abgebrochen wird bzw. abstürzt? Fügen Sie in die Prozedur die Anweisung "On Error Goto <ErrorHandler>" ein und fangen Sie alle Laufzeitfehler ab.

Muster siehe VBA Codebeispiele

2 Programmunterbrechung verhindern Wurde die Tastenkombination Strg+Unterbrechen (Ctrl+Break) sowie die Escape-Taste (Esc) abgefangen, damit die Codeausführung nicht durch die Benutzer unterbrochen werden kann? Leiten Sie mit der Codezeile "Application.EnableCancelKey = xlErrorHandler" die Codeunterbrechung an den Error Handler weiter.

Muster siehe VBA Codebeispiele

3 VBE-Fehlerbehandlungsoptionen prüfen Ist sichergestellt, dass die Fehlerbehandlungsoption "Bei jedem Fehler unterbrechen" nicht eingestellt ist? Wenn Sie nicht davon ausgehen können, dass die Optionen immer wie erwartet eingestellt sind, sollte dies im Programm berücksichtigt werden. Anderenfalls bricht die Ausführung des VBA-Codes bei einem Laufzeitfehler trotz korrekter Fehlerbehandlungsroutine ab.

Muster siehe VBA Codebeispiele

4 Timing-Probleme berücksichtigen Wurde im Code berücksichtigt, dass in bestimmten Situationen Timing-Probleme auftreten könnten, z.B. wenn die Empfänger-Anwendung sehr lange benötigt, bis sie vollständig gestartet und bereit zum Empfangen von Tastenfolgen ist?

Zum Anfang

 


Programmverhalten testen

Die folgenden Testmakros rufen den Eigenschaften-Dialog über das Menü Datei auf und setzen die Texteinfügemarke in das Eingabefeld "Hyperlink-Basis". Wenn das Dialogfenster korrekt geöffnet wird, ohne dass die Meldung "Das war ..." erscheint, funktioniert die im Makro benutzte Lösungsvariante zum Senden von Tastenfolgen.

Sub SendKeysTest1()
  SendKeys "%di{tab 8}", True
  MsgBox "Das war SendKeys mit Wait=True."
End Sub

Sub SendKeysTest2()
  SendKeys "%di{tab 8}"
  DoEvents
  MsgBox "Das war SendKeys mit Wait=False und DoEvents."
End Sub

Sub SendKeysTest3()
  Application.SendKeys "%di{tab 8}", True
  MsgBox "Das war Application.SendKeys mit Wait=True"
End Sub

Sub SendKeysTest4()
  Application.SendKeys "%di{tab 8}"
  DoEvents
  MsgBox "Das war Application.SendKeys mit Wait=False und DoEvents."
End Sub

Zum Anfang

 


VBA Codebeispiele

Beispiel aus der VBA-Hilfe

Dim Ergebnis, I
Ergebnis = Shell("CALC.EXE", 1)     ' Rechner starten.
AppActivate Ergebnis                ' Rechner aktivieren.
For I = 1 To 100                    ' Zählschleife beginnen.
  SendKeys I & "{+}", True          ' Tastenanschläge senden, um die
Next I                              ' Werte von I zu addieren.
SendKeys "=", True                  ' Gesamtsumme abrufen.
SendKeys "%{F4}", True              ' Rechner mit ALT+F4 beenden.

Zum Anfang

 


Begriffserklärungen

Synchron

Asynchron

Task-ID

VBE

Präemptives Multitasking

Kooperatives Multitasking

Zum Anfang

 


Tasten-Namen

In general, spell key names as they appear in the following list, whether the name appears in text or in a procedure. Use all caps unless otherwise noted.

Note This list applies to Microsoft and IBM-type keyboards unless otherwise noted. Differences with the Macintosh keyboard are noted.

Key Comment
ALT -
ALT GR -
Application key Microsoft Natural Keyboard only
arrow keys Not direction keys, directional keys, or movement keys.
BACKSPACE -
BREAK -
CAPS LOCK -
CLEAR -
COMMAND Macintosh keyboard only. Use the bitmap to show this key whenever possible, because the key is not named on the keyboard.
CONTROL Macintosh keyboard only. Does not always map to the CTRL key on the PC keyboard. Use correctly.
CTRL -
DEL Macintosh keyboard only. Use to refer to the forward delete key.
DELETE Use to refer to the back delete key on the Macintosh keyboard.
DOWN ARROW Use the and key with the arrow keys except in key combinations or key sequences. Always spell out. Do not use graphical arrows.
END -
ENTER On the Macintosh, use only when functionality requires it.
ESC Always use ESC, not ESCAPE or Escape, especially on the Macintosh.
F1–F12 -
HELP Macintosh keyboard only. Always use "the HELP key" to avoid confusion with the Help button.
HOME -
INSERT -
LEFT ARROW Use the and key with the arrow keys except in key combinations or key sequences.
NUM LOCK -
OPTION Macintosh keyboard only.
PAGE DOWN -
PAGE UP -
PAUSE -
PRINT SCREEN -
RESET -
RETURN Macintosh keyboard only.
RIGHT ARROW Use the and key with the arrow keys except in key combinations or key sequences.
SCROLL LOCK -
SELECT -
SHIFT -
SPACEBAR Precede with the except in procedures, key combinations, or key sequences.
SYS RQ -
TAB Use the and key except in key combinations or key sequences.
UP ARROW Use the and key with the arrow keys except in key combinations or key sequences.
Windows logo key Microsoft Natural Keyboard only.

Zum Anfang


Zuletzt aktualisiert am 27.01.2006 / 21:00 Uhr

© 2002-2006 by Philipp von Wartburg, CH-8916 Jonen
Alle Rechte vorbehalten