• ベストアンサー

KeyDownイベントが機能しない

エクセル2003を使用しています。 フォームを表示中に、エスケープキーを押したらフォームを閉じたいのですが KeyDownイベントが反応しません。 http://homepage1.nifty.com/tsware/tips/tips_251.htm を見てやってみたのですが 新ブックに新規フォームを挿入し、 Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) If KeyCode = vbKeyEscape Then Unload Me End If MsgBox "" End Sub と記載し、フォームを実行しエスケープキーを押してみました。 しかし何も起こりません。 実験用のMsgBoxも表示されません。 「エスケープキーを押したらフォームを閉じる」以前に、 KeyDownイベントが反応しないのですが 何が原因なのでしょうか? 新ブックを作ってテストしているので 余計な動作に邪魔されていないと思います。 ご指摘よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • hige_082
  • ベストアンサー率50% (379/747)
回答No.1

リンク先はアクセスの場合です エクセルとは少し違うようです エクセルのヘルプによると form上のフォーカスのあるコントロールのKeyDownイベントが実行対象のようです formのKeyDownイベントを使用するにはform上にコントロールを一つも配置しないか form上のコントロールにフォーカスを持たせないような処理をしないとならない したがって、質問のような処理をするならば form上のすべてのコントロールのKeyDownイベントに処理を書かなければならない 詳細はヘルプを参照してください

eurytdd
質問者

お礼

アクセスとエクセルでは違うのですね。 コマンドボタンを設置して コマンドボタンのKeyDownイベントにコードをコピペしたらできました。 ありがとうございました。

その他の回答 (3)

  • takana_
  • ベストアンサー率44% (21/47)
回答No.4

画面にコマンドボタンを1個配置し、 プロパティからCancelを選択して、値をTrueにします。 ボタンクリックイベントを Private Sub CommandButton1_Click()   Unload Me End Sub とします。 以上でクリックしてもEscキーを押しても、フォームを閉じるようになります。 キャプションを「閉じる」か「キャンセル」にすれば普通の閉じるボタンとして使えますし、 表示したくなければ、フォームのInitializeイベントでボタンの位置を画面から追い出せば 見えなくなります。 Private Sub UserForm_Initialize()   CommandButton1.Top = -100 End Sub 蛇足ですが、ボタンのDefaultプロパティをTrueにすれば、Enterキーで反応するボタンになります。

eurytdd
質問者

お礼

仕組みは良くわかりませんができました。 takana_様有難うございます。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.3

こんにちは。 Excel の場合は、オブジェクト名は、Form ではなく、UserForm ですが、#1さんのおっしゃるとおり、それぞれのコントロールのイベントの配下に入るので、通常、UserForm のKeyDown イベントが利きません。これは、Access のForm でも、プロパティでForm のキー・イベントの取得をしないと、キー・イベントを取得できません。 以前、私が書いた方法で、Application.Onkey で取る方法も、UserForm モーダルモードがOff であることが条件で、UserForm がアクティブな状態ですと、Esc キー・イベントが働きません。 http://oshiete1.goo.ne.jp/kotaeru.php3?qid=3447388 そこで、新たにコードを書いてみました。RaiseEvent で、イベントを設け、UserForm表示中にキーイベントを取得するようにしました。ただ、直接、Unload Me をしてしまうと、入力最中なども終わってしまうので、メッセージを付けました。 '------------------------------------------- ' UserForm Module '------------------------------------------- Private Sub UserForm_Activate()   myClass.inKeyChange vbKeyEscape End Sub Private Sub UserForm_Initialize()   Set myClass = New Class1 End Sub Sub myClass_keyEvent()  If MsgBox("終了してよろしいですか?", vbQuestion + vbOKCancel, "終了メッセージ") = vbOK Then   Unload Me  Else   myClass.inKeyChange vbKeyEscape  End If End Sub Private Sub UserForm_Terminate()  'イベント自体は終わっていますが、オブジェクトが残っています。  Set myClass = Nothing End Sub '------------------------------------------- 'Class Modlue, Module Name(Defalt): Class1 '------------------------------------------- Public Event myKeyEvent(ByVal mykey As Integer) Public Event keyEvent() Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer Public Sub inKeyChange(ByVal inkey As Long)   On Error Resume Next   Do Until GetAsyncKeyState(inkey) <> 0    DoEvents  Loop  RaiseEvent keyEvent  On Error GoTo 0 End Sub

eurytdd
質問者

お礼

クラスモジュールも使うのですね!試してみます。ありがとうございました。

  • DreamyCat
  • ベストアンサー率56% (295/524)
回答No.2

Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) これはご自分で記述を「変更」したのでしょうか? 自分で「書いた」のでしょうか? userformをダブルクリックすると左上のオブジェクト枠に UserFormと表示されるので、右上のモジュール枠から KeyDownを選び、その中にif以下を記述するだけです。 Private Sub UserForm_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer) If KeyCode = vbKeyEscape Then MsgBox "esc" End Sub

eurytdd
質問者

お礼

リンク先のコードを自分で一部変更しました。 どうもこの方法だとうまく行きませんでした。

関連するQ&A