アプリ版:「スタンプのみでお礼する」機能のリリースについて

エクセルVBAでプログラムをしています。
Application.Onkeyでショートカットを指定したいのですがフォーム上ではうまく指定できません。
フォーム上での指定は不可能なんでしょうか?

ショートカットを認識するケース
標準モジュールに
Sub test2()
MsgBox "test2"
End Sub
Sub Auto_Open()
Application.OnKey "{b}", "test2"
End Sub
としてシート上で「b」を押した場合はうまくいきます。

ショートカットを認識しないケース
標準モジュールに
Sub test()
MsgBox "test"
End Sub

UserForm1フォームに
Private Sub UserForm_Initialize()
Application.OnKey "{a}", "test"
End Sub
としてフォームをロード(表示)して「a」を押しても何もおきません。
またフォームが表示されている状態で「b」を押しても何もおきません。

上記のコードはテストで作ったものなのでこれ以外はフォームを開く文以外何も書いておりませんので他との兼ね合いではないと思います。

どうすれば思ったとおりの動作になるのでしょうか?
そもそもOnkeyはユーザフォームがアクティブのときは動かないのでしょうか?
動かない場合、フォームがアクティブなときのみフォームごとに違う関数を呼ぶショートカットを作る方法はありませんでしょうか?
(コントロールごとにkey_downイベントで確認する方法はコントロールの数が各100個ほどあるのと、フォームが10個以上あるため出来ればやりたくありません。)

環境はwinXP、excel2003です。
よろしくお願いいたします。

A 回答 (7件)

こんにちは。



> keypressまたはkeydownイベントを使用するしか方法はないのでしょうか。
基本的にはそのとおりです。

> 1000回書くのはナンセンスだと思い何か言い方法が無いか探している状況です。
VB とか Access のように Userform に KeyPreview プロパティーがあれば
話は簡単なのですが、残念ながら Excel にはありません。

  # 何故 Access にあって、Excel には KeyPreview がないん
  # でしょうね。。^^;

解決法としては、クラスモジュールを使うことになります。下記参考 URL
に記事があります。一度クラスを書いてしまえば、コントロール数が増え
ても減ってもコードの修正は非常に容易です。

  Visual Basic 中学校
  http://homepage1.nifty.com/rucio/main/main.htm
  第30回 同じコードを2度書くな
  http://homepage1.nifty.com/rucio/main/shokyu/jug …

その他の方法としては、

  ・SetWindowsHookEx api でキーボードフックする
  ・RegisterHotKey api でホットキーを設定する

などでも実現可能ですが、難易度は高めです。
    • good
    • 0

本格的にするなら、クラス化して、イベントまで作らなければなりませんが、今回のコードはそこまで詰めていません。



当該ユーザーフォームのモジュールに

'===========================================================
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function GetAsyncKeyState Lib _
    "User32.dll" (ByVal vKey As Long) As Long
Private e_l As Boolean
'===========================================================
Private Sub UserForm_Activate()
  e_l = False
  Do Until e_l = True
   Sleep 100
   DoEvents
   If key_code(66) Then '{b}が押された?
'    実際には、ここに{b}が押されたときの処理を記述する
' または、ここで別のプロシジャーを呼び出す
     Range("a1").Value = Range("a1").Value & "b"
'    ここではセルA1にbを繋げている
     End If
   Loop
End Sub
'===========================================================
Function key_code(key As Long) As Boolean
' keyの値は、コントロールのKeyDownイベントのKeycodeと同値
 Dim inkey As Long
 key_code = False
 inkey = GetAsyncKeyState(key)
 If inkey <> 0 Then
   key_code = True
   End If
End Function
'===========================================================
Private Sub UserForm_Terminate()
  e_l = True
End Sub
    • good
    • 0

ああ、すみません。


#4ですが、読み落としというか、錯誤があって頓珍漢な回答(?)でした。
#3さんのご回答に私が上書きするような話はありません。
いくつか考えついたのはありますが、どれもダミーのコントロールにフォーカスを置く方法ばかりでした。

大変失礼しました。
    • good
    • 0

こんにちは



詳細はよくわかりませんが、
ご要望はこういうことではないでしょうか?

Private Sub UserForm_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)

  If KeyAscii = 98 Then Application.Run "test2"

End Sub

私自身、滅多に使わないイベントですから、詳しい訳ではありませんが、
このイベントがある以上は、
―OnKey が優先される―ことはないだろうな、とは思います。

※フォームはModal表示、コントロールにフォーカスを置かない状態で確認済。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
keypressまたはkeydownイベントを使用するしか方法はないのでしょうか。
質問にも書きましたが本番環境には、ボタンやテキストボックスなどコントロールがざっと1000以上(システム全体で)あります。
1000回書くのはナンセンスだと思い何か言い方法が無いか探している状況です。

お礼日時:2008/07/15 21:05

Formヘルプの[Microsoft Forms オブジェクト モデルの全体像]


を見てもらったらわかるかもしれませんが、
ExcelとMicrosoft Formsは、言わば別Applicationなので、
FormがActiveになっている時はExcel.ApplicationのOnkeyメソッドは機能しません。

[Alt]キーとの組み合わせで良ければ、[Accelerator プロパティ]を調べてみてはいかがでしょう。

ダミーでもいいので、CommandButton を追加し、そのボタンに[Accelerator プロパティ]を設定します。
Me.CommandButton1.Accelerator = "A"
などとコードでも設定できますが、[プロパティウィンドウ]でも可。
[Alt]キー+[設定したキー]で、その CommandButton_Click イベントが実行できます。

その CommandButton はUserFormの非表示エリアに置いて、TabStopをFalseにしておけば
あまり気にならないでしょう。
その場合はクリックイベントの最後に他のコントロールにSetFocusするようにしておいたほうがいいです。
    • good
    • 0

#1です。


あと、ユーザーフォームにフォーカスがあると
起動しないようです。
シートにフォーカスを移してからキーを打つと
起動します。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
現在作っているプログラムはユーザがシートにフォーカスを当てる瞬間がまったくありません。
フォームがアクティブなときにいつでもショートカットキーを使用するいい方法はないでしょうか?
よろしくお願いいたします。

お礼日時:2008/07/15 19:00

全角/半角


の違いでは?
半角に切り替えたらどうなりますか?
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
テキストボックスなどのコントロールは一切ありませんので常に半角です。
あえて全角にして見ましたがうまくいきません。

お礼日時:2008/07/15 18:58

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A