Excel (VBA)

Excel VBAに関するフォーラムです。
  • 掲示板への投稿には会員登録(無料)が必要です。会員登録がまだの方はこちら
  • 掲示板ご利用上のお願い」に反するご記入はご遠慮ください。
  • Q&A掲示板の使い方はこちらをご覧ください
トピックに返信
質問

 
(Windows 7 Professional : Excel 2013)
sendkeysでshift+F10を送る。
投稿日時: 18/05/11 17:40:27
投稿者: kito110

右クリックさせるため、 SendKeys "+{F10}"でVBAを動かすと、{F10}押下の状態となります。
SHIFTが効いてない様に思います。
多くのネット記事では、SendKeys "+{F10}"と説明してありますが、実際に動くのでしょうか。
なんらかのタイミングでshiftを認識しないのでしょうか。
実際に、右クリックができた方、お教えください。
できない原因、解決策がわかれば、お教えください。
当方、windows7,EXCEL2016です。
 
 

回答
投稿日時: 18/05/11 18:03:29
投稿者: WinArrow
投稿者のウェブサイトに移動

Sendkeys "+{F10}"
は、
「シートのセルを右クリックした時のショートカットメニューを表示する」
ということを実現したい
ということでしょうか?
 
なぜ、こんな面倒くさいことするんですか?
 
Sendkeysは、思わぬ誤動作をすることがあるんので、
注意して使うようお勧めします。

投稿日時: 18/05/11 18:34:50
投稿者: kito110

sendkeysが誤動作をした結果だとは、思えません。
このコマンドが正常に動いた方は、お教えください。
正常に動かないのは、原因があるはずで、
改善方法をお教えください。
 
 

回答
投稿日時: 18/05/11 19:21:26
投稿者: よろずや

SendKeys が不安定であることは有名です。
 
https://oshiete.goo.ne.jp/qa/3006119.html

回答
投稿日時: 18/05/11 19:22:12
投稿者: WinArrow
投稿者のウェブサイトに移動

誤動作と書いたのは、正確な表現ではなかったようです。
 
正しくは、不安定ちというべきでした。
 
私のところでは、正常に動作しましたが・・・・

回答
投稿日時: 18/05/11 19:27:04
投稿者: WinArrow
投稿者のウェブサイトに移動

質問者に質問です。
 
このマクロをどのように実行していますか?
 
若しかして、VBEの画面から起動させていませんか?
 
VBEの画面から起動した場合、意図した動きにならないことがあります。

投稿日時: 18/05/11 19:27:39
投稿者: kito110

SendKeys "+{F10}"を正常に動かした方にお聞きします。
上記記述が誤りなら、そこをご指導ください。
よろしくお願いいたします。
 
 

回答
投稿日時: 18/05/11 19:36:15
投稿者: WinArrow
投稿者のウェブサイトに移動

kito110 さんの引用:
SendKeys "+{F10}"を正常に動かした方にお聞きします。
上記記述が誤りなら、そこをご指導ください。
よろしくお願いいたします。
 

 
コードそのものが誤っているとは思いません。
 
どのようなシチュエーションで、使おうとしているかわかりません。
 
そのあたりを説明したほうがよいでしょね・・・
 
 

投稿日時: 18/05/11 19:37:18
投稿者: kito110

VBEから起動していません。
sendkeysで、他の機能たとえば、DEL,ESCAPE、F2(ダブルクリック)、ENTERは、正常に動いています。
+でSHIFTが認識されていません(F10として機能しているので)。正常に動いている方は、そのままのコードを教えてください。
このPCで動かない原因がわかりません。
 

回答
投稿日時: 18/05/11 19:38:43
投稿者: WinArrow
投稿者のウェブサイトに移動

最初の質問時に
>、{F10}押下の状態となります。
これは、どのような方法で確認したのでしょう?

投稿日時: 18/05/11 19:47:34
投稿者: kito110

SendKeys "+{F10}"というコードを記述し、実行しました。
F10の機能は、働いています。
と言うことは、+が効いてません。
原因がわかりません。
 

投稿日時: 18/05/11 20:01:20
投稿者: kito110

F10は、コマンドモードとなり、画面にショートカットの英文字が現れます。
この現象で確認しました。

回答
投稿日時: 18/05/11 20:43:17
投稿者: simple

こんばんは。
 
私の場合、勤務先も自宅もWin7のExcel2010ですが、
勤務先はF10相当、自宅ではSHift+F10相当(正常処理)となりました。
 
皆さん既に指摘されているように、
SendKeysは不安定であることは定評があるところです。
 
環境によって、上手くいくときもあれば行かないときもあるなんて、
そんなバカな、という気持ちでしょうが、それが現実だから認めるしかありません。
ユーザーが原因追及できる範囲を超えています。
 
内部のタイミングの問題ですからユーザーができることは、
・できるだけSendKetsに頼らない手法を工夫する(あれば)
・うまくいけばラッキーくらいに思うこと
などだけです。
 
どうしても許せないということでしたら、
マイクロソフト社にあなたが掛け合うしかありません。
昔からそうですから、たぶんマイクロソフトも承知していますが、
事態はたぶん変わらないはずです。

回答
投稿日時: 18/05/11 20:47:55
投稿者: simple

むろん、コードは勤務先も自宅も全く同じものです。
コードの問題ではないんです。

回答
投稿日時: 18/05/11 21:41:58
投稿者: WinArrow
投稿者のウェブサイトに移動

>sendkeysが誤動作をした結果だとは、思えません。
コードはは間違っていないのに、意図した通り動かないことを、誤動作というのではないかな?
 
ところで、右クリックで表示するショートカットメニューは、
その場所・・といっていいのか?・・・だけど・・・
つまり、セルが選択されている場合、行が選択されている場合、列が選択されえいる場合、
シート見出しが選択されている場合、はたまた、図形が選択されている場合
(他にもあるかもしれませんが・・)
で、異なるメニューが表示されるって、ご存知ですよね?
 
すべてのケースを判断したコードになっているのでしょうか?
 
Sendkeysを使わない方法を検討したほうが確実で早いと思います。

回答
投稿日時: 18/05/11 22:52:47
投稿者: MMYS

ベテランの意見に耳を傾けず
俺は正しい。だから
動くコードを教えてくれ
 
って考えは改めるべきかと。
 
 
他の方が言っている通り、Sendkeysは
キーボードをシュミレートです。
つまり、キーボード押す「だけ」です。
目をつぶってキーボードを触るようなもの。
 
そんな不安定なものに頼らず、他の方法を取るべきです。
 
Sendkeysを使うケースはほかに方法がなく、
リスクを承知て使う場合のみです。
 
 
経験上、Sendkeysが必要なケースは稀です。
なので使用目的を説明すべきです。
 

回答
投稿日時: 18/05/11 23:28:43
投稿者: よろずや

あなたの作るプログラムにバグがあるのと同様に
Microsoftの作るEXCELにもバグがあります。
そのバグを回避する策を考えるのもSE(プログラマ)の仕事です。
42年コンピュータと付き合ってきた中でのEXCELのバグ回避も何回かあります。

回答
投稿日時: 18/05/12 00:03:55
投稿者: sy

今回の問題に対して明確な原因があるか検証する為にも、
あなたが実行した手順をもう少し詳しくご説明ください。
 
私の現在の環境はwin10(64bit)、EXCEL2016(Office365)ですが、
単純に、SendKeys "+{F10}" 1行だけを記述したコードで検証してみました。
 
 

シート上で表示→マクロ→マクロ名を実行すると、[Shift]+[f10]になり、右クリックメニューが表示。
20回くらい試行して全て正常動作。
フォームコントロールボタンを配置してクリックしても同じ。
 
 
ショートカットキーを割り当てて実行すると[f10]だけが有効になりフォーカスがメニュー側に移行。
プラスたまにNumLockが無効になりました。(発生タイミングなど不明)
ActiveXコントロールボタンを配置してクリックしても同じ。
 
 
ちなみにVBE上で[f5]で実行やステップ実行すると、VBEの右クリックメニューが表示されました。
 
 
私の自宅PCでしか検証してないので、どのPCでも同じ動作になるかは保障の限りではないです。
 
今回のNumLockが無効になる誤動作や、描画タイミングなどで意図した動作にならないなど、
SendKeysが不安定と言うのは事実なので、使わずに済むならそれに越した事はないですけどね。

回答
投稿日時: 18/05/12 08:03:28
投稿者: K.Hiwasa
投稿者のウェブサイトに移動

おはようございます。
 
経験上、SendKeysよりAPIのキーボードイベントの方が安定するようです。
キー送信を使わなくても済むようならそちらの方法で、
どうしても必要ならキーボードイベントを使うのをおすすめします。
 
参考
https://www.moug.net/tech/exvba/0150121.html

回答
投稿日時: 18/05/12 12:06:56
投稿者: simple

Windows APIを使う話がでましたので、参考にコードを挙げておきます。
試してみて下さい。(標準モジュールに入れて下さい。)
 

Option Explicit

Declare Sub keybd_event Lib "user32.dll" (ByVal bVk As Byte, _
                                          ByVal bScan As Byte, _
                                          ByVal dwFlags As Long, _
                                          ByVal dwExtraInfo As Long)

Const VK_F10 = &H79                 '' F10キー ' 他は「仮想キーコード」で検索のこと
Const VK_SHIFT = &H10               '' シフトキー
Const KEYEVENTF_EXTENDEDKEY = &H1   ''キーを押す
Const KEYEVENTF_KEYUP = &H2         ''キーを放す

Sub Sample1()
    'Shiftキーを押す
    keybd_event VK_SHIFT, 0, KEYEVENTF_EXTENDEDKEY, 0
    
    keybd_event VK_F10, 0, KEYEVENTF_EXTENDEDKEY, 0
    
    'Shiftキーを放す
    keybd_event VK_SHIFT, 0, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0
End Sub

回答
投稿日時: 18/05/12 13:25:09
投稿者: よろずや

エクセルシートをマクロでいじると、Undo ができません。
しかし SendKeys でシートをいじった場合は、Undo 可能です。
でも、SendKeys でのシート操作は、遅くて使い物になりませんでした。

回答
投稿日時: 18/05/12 17:27:19
投稿者: WinArrow
投稿者のウェブサイトに移動

余計な心配かもしれませんが、
 
シュートカットメニューを表示するまでは、問題ありませんが、
 
シュートカットメニューのどのコマンドをクリックしたかを
VBAで判断するつもりなのかな?
 
"まさか"とは思いますが、気になったので質問してみました・・・・

回答
投稿日時: 18/05/12 22:40:38
投稿者: simple

右クリックだけが目的なら、

Sub test()
    Application.CommandBars("Cell").ShowPopup
End Sub
なんていうのが利用できるかもしれません。
 
ただし、質問者さんがやりたいことは、単に右クリックだけが目的とは
思えません。それなら、手で右クリックすればいいだけですから。
質問にあたっては、全体としてどういうことをしたいのかを説明するほうが
よいと思います。
最初から、手段だけ決めうちしてしまって、「この方法を教えて」というよりも、
全体の目的を明確にしたほうがよいと思います。
そうすれば、別の手段も含めて幅広い助言が得られるはずです。

回答
投稿日時: 18/05/15 01:09:05
投稿者: Abyss2

お邪魔します。
最終手段としてキーストロークしかない時は存在します。(例えば対ゲームアプリ)
 
今回のケースはPC環境に影響されているように見えますので
【Shift + F10】 の仮想キーを送るのではなく、
直接ハードウェアスキャンコードを送るのが正しいでしょうね。
 
Shift + F10 ==> [Scancode] 0xe0 0x5D
 
以下、サンプルです。

Declare Sub keybd_event Lib "User32" _
    (Optional ByVal bVk As Byte, _
     Optional ByVal bScan As Byte, _
     Optional ByVal dwFlags As Long, _
     Optional ByVal dwExtraInfo As LongPtr)

Const KEYEVENTF_EXTENDEDKEY = 1&
Const KEYEVENTF_KEYUP = 2&
Const KEYEVENTF_SCANCODE = 8&

Sub Main()
    Dim flg As Long
    
    flg = KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_SCANCODE
    keybd_event , &H5D, flg
    keybd_event , &H5D, flg Or KEYEVENTF_KEYUP
    
End Sub

トピックに返信