VBA: Wie funktionieren Event Handler?

Hallo zusammen,

ich entwickle gerade ein ziemlich umfangreiches VBA-Projekt für MS-Word, wobei ich manchmal bestimmte Tasten(kombinationen) abfangen muss.

Dabei handelt es sich unter anderem um ENTER, BACKSPACE und ENTF, die ich mit Hilfe von KeyBindings abfange und damit jeweils eine bestimmte Prozedur von mir auslöse. Eigentlich müssen diese Tasten aber nur in seltenen Ausnahmebedingungen wirklich abgefangen werden. Mein Problem ist jetzt aber, dass das entsprechende Event natürlich stets „feuert“ und meine Prodzedur aufruft sobald eine dieser Tasten gedrückt wird, auch wenn diese Bedingung gar nicht zutrifft.

Leider scheint es aber keinen Befehl bzw. Paremeter zu geben, um VBA mitzuteilen, den Tastendruck in so einem Fall „ganz normal“ abzuarbeiten. Zwar kann ich natürlich eine „SendKeys“-Anweisung benutzen, allerdings führt das dann natürlich einfach zu einem weiteren (rekursiven) Aufruf eben dieser Funktion durch den hinterlegten Event Handler.

Ich bräuchte also eine Art

IF (meine Bedingung) = true then
call meine_spezialprozedur
ELSE
[TASTE-AN-WORD-WEITERREICHEN]
END IF

Wenn ich einfach das KeyBinding kurzfristig deaktiviere („FindKey(KEY_CODE).disable“) um ein „SendKeys“-Kommando abzuschicken löse ich damit bizarrerweise trotzdem das Event aus (obwohl das Binding tatsächlich nicht mehr existiert, auch eine gewisse Wartezeit bringt hier nichts).

Allgemein habe ich also massiv das Problem, dass ich Event Handler nur sehr allgemein formulieren kann und dann sehr viele Ausnahmebedingungen schreiben muss und dabei längst nicht alles glatt läuft.

Auch gelingt es mir nicht, zuverlässig zu unterscheiden, ob nun ein abgefangenes Event wirklich vom Anwender ausgelöst wurde oder nur von mir selbst. Ich setzte dann immer manuell Unmengen von Flags um sowas herauszufinden. Wenn ich während umfangreicher Operationen die Überwachung von Events abschalten könnte, wäre mir das schon eine Hilfe.

Ein weiteres Problem: In Word selbst lassen sich die genannten drei Tasten nicht als Tastenkürzel für ein Makro hinterlegen (BACKSPACE löscht die Kombination einfach, ENTFERNEN wird nicht erkennt und ENTER schließt das Fenster). Aus diesen Grund muss ich diese KeyBindings per VBA-Code setzen. Dummerweise scheinen so gesetzte KeyBindings allerdings global zu sein, beinflussen also die gesamte Anwendung und bleiben selbst nach einem Neustart erhalten. Ist nicht irgendwie möglich, diese Tastenkürzel nur auf die verwendete Vorlage einzugrenzen, ähnlich wie es mit den Symbolleisten möglich ist? Für alle über das entsprechende Word-Menu selbst gesetzten Tastenkürzel scheint genau das zu gelten…

Kann mir jemand da mal ein paar Tipp geben? Ich habe gelesen, mit einer Klasse bzw. einem Klassemodul liese sowas event. besser eingrenzen? Wäre wirklich für Hilfe dankbar, da stecken jetzt schon einige Monate Arbeit drin. :frowning:

spyro

Hi Rupert,

spontan würde ich dir Spotlight empfehlen aber das gibt es leider nicht mehr. Sicher, grundsätzlich gehört deine Anfrage ins hiesige Wordbrett, aber das würde dir nix nutzen, Word-Vba mäßig ist da nix los.
Von daher biste da schon hier richtig, das Dumme ist, weder VB noch ExcelVba kennen Keybinding.

Und dein WordVba kennt nicht meinen ExcelVba Befehl Onkey um da dieses Keybinding evtl. zu umhehen.

Sendkeys sollte man eh nur nehmen wenn wirklich nix anderes geht, da du das benutzt, geht wohl wirklich nix anderes :frowning:

Von daher kann es durchaus sein daß deine monatelange Arbeit nicht zum Ziel führen wird, da es halt mit keybinding nicht geht.

Soweit zum worst case.

Jetzt komme aber ich mit meinem Optismismus, ich denke mir halt, es kann doch gar nicht sein daß man mit WordVba nicht paar banale Tastatureingaben abfangen kann und dementsprechend reagiert.

Bastle bitte mal eine kleine doc, wo du z.B. jetzt das Enter-Event abfängst und lade das hoch mittels FAQ:2861 , dann versuche ich mich mal dran.

Wenn ich alles richtig verstanden habe, so soll bei Betätigung der Enter-Taste sofern deine „Bedingung“ nicht zutrifft der normale Word-Vorgang bei Enter ausgelöst werden, trifft deine „Bedingung“ (welche?) zu soll dein Code irgendwas (was?) machen.

Gruß
Reinhard

Hi spyro,

Deine Frage bezieht sich ja im Wesentlichen auf Klassen und das feuern von Events.

Von VBA habe ich keine Ahnung, im Zusammenhang mit Word erst Recht nicht.
Wenn ich Dich richtig verstehe, genügt es Dir aber im Moment, wenn Du aus einem Klassenmodul ein Event feuern kannst.

Ich habe ein Minimalbeispiel, das lauffähig ist. Zwar für VB6, aber ich denke, das wird Dir als Erklärung reichen.

Der Code für die Form …

'Das hier gehört in eine Form, die Form1 heißt.
'Auf die Form muß ein Timer 'Timer1' und ein Label 'Label1'.

Option Explicit
Private WithEvents SchedDay As Scheduler

Private Sub Form\_Load()
 Set SchedDay = New Scheduler
 Label1.Caption = "Nicht ausgelöst"
 Timer1.Interval = 1000
End Sub

Private Sub SchedDay\_ChangeText()
 Label1.Caption = "Ausgelöst"
End Sub


Private Sub Timer1\_Timer()
 Label1.Caption = "Nicht ausgelöst"
 Call SchedDay.Schedule(4)
End Sub

Und der Code für das Klassenmodul:

'Das hier gehört in eine Klasse, die 'Scheduler' heißen muß!

Option Explicit
Public Event ChangeText()

Public Sub Schedule(ByVal Tg As Integer)
 Static Flag As Boolean
 If Flag = False Then
 If Weekday(Date, vbSunday) = Tg Then
 Flag = True
 RaiseEvent ChangeText
 End If
 Else
 If Weekday(Date, vbSunday) Tg Then
 Flag = False
 End If
 End If
End Sub

Auf noch weniger Code wird sich ein funktionierendes Beispiel kaum reduzieren lassen. :smile:

Du siehst aber, der Code muss laufen um ein Event feuern zu können.
Was nicht geht, ist ein Event nur ‚festzulegen‘, der Code tut nichts und wartet auf dieses Event.

Gruß Rainer

Bastle bitte mal eine kleine doc, wo du z.B. jetzt das
Enter-Event abfängst und lade das hoch mittels FAQ:2861 , dann
versuche ich mich mal dran.

Danke dir!

Ich habe was zusammengebastelt und hier hochgeladen:
http://pagina-online.de/downloads/sonstiges/Key_Even…

Es ist praktisch alles kommentiert, so dass du wohl sehr schnell siehst, wo genau mein Problem liegt bzw. was nicht so funktioniert wie es soll.

spyro