Excel (VBA)

Excel VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(Windows 7 Professional : Excel 2010)
BeforeRightClick時の動作
投稿日時: 20/11/14 08:05:16
投稿者: ロードランナー
投稿者のウェブサイトに移動

現在、右クリックイベント処理を作りこんでいます。
 
個人用マクロブックのクラスに以下のように記述しています。
 
#If Win64 Then
'64ビットAPI関数
Private Declare PtrSafe Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Integer
#Else
'32ビットAPI関数
Private Declare Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Integer
#End If
 
Private Sub apl_SheetBeforeRightClick(ByVal Sh As Object, ByVal Target As Range, Cancel As Boolean)
    'Ctrl+右クリックのときにユーザーフォームを表示する
    If GetAsyncKeyState(vbKeyControl) Then
        UF1.Show
        Cancel = True
    End If
End Sub
 
Ctrl+右クリックでユーザーフォーム(UF1)は表示するのですが、2回目はCtrlを押さなくてもユーザーフォームを表示してしまいます。(3回目は正常に右クリックメニューがでます)
 
なぜ2回目でCtrlを押さなくても処理が走ってしまうのでしょうか。
この現象を止めることはできないのでしょうか?
 
みなさまのお知恵拝借したいです。
 
よろしくお願いいたします。
 
※クラスではなく、普通のシートイベントに作りこんでも同じ現象でした。

回答
投稿日時: 20/11/14 10:34:59
投稿者: WinArrow
投稿者のウェブサイトに移動

こちら
Windows10 Excel2019 の環境です。
  
シートモジュールでテストしてみました。
但し、ユーザーフォームではなくMsgboxを使いました。
  
掲示のコードでは、
Ctrlを押さずに〜〜〜〜
の症状は発生しませんでした。
 
  
問題を切り分けましょう。
ユーザーフォームを外してテストしてみてください。
 

投稿日時: 20/11/14 11:09:08
投稿者: ロードランナー
投稿者のウェブサイトに移動

WinArrowさん、ありがとうございます。
 
UF1.Show を MsgBox "???" に置き換えたところ、正常に動作しました。
 
なぜユーザーフォームの時だけ???
 
ちなみに
UF1.Show vbModeless
とモードレス表示にしても、現象は同じでしたね。
 
なお、この不思議な現象は、Win10 & Excel2016 の環境でも同じでした。
 
ユーザーフォームのInitialzeで、Keycodeを操作するような作りはありません。
なぜ一回だけ???

投稿日時: 20/11/14 11:16:52
投稿者: ロードランナー
投稿者のウェブサイトに移動

追加です。
 
試しに
 
Private Sub UserForm_Initialize()
 
をすべてはずしても、現象は同じでした。
 
でもMsgBoxではおきない、う〜ん・・・。

回答
投稿日時: 20/11/14 12:14:23
投稿者: WinArrow
投稿者のウェブサイトに移動

こちらで
ユーザーフォームを使ったテストをしてみました。
 
ユーザーフォームモジュールには、何もコードを記述していません。
 
Crtlキーを押さない状態の右クリックでは、ユーザーオーム表示されません。
 

投稿日時: 20/11/14 12:31:37
投稿者: ロードランナー
投稿者のウェブサイトに移動

Ctrl+右クリックでユーザーフォームを表示
 
一旦×で閉じて、右クリックだけでは表示しなかった(普通の右クリックメニュー表示)
 
ということでしょうか???
 
うーん、分からないですね。何が(どこが)違うのでしょうか…。
 
実はこちらでも新しいブックに、WinArrowさんと同じような状況でやってみたのですが、やはり2回目が表示されてしまいました。
 
あとはExcelのバージョンの違いだけでしょうか。
ちなみにVBAのバージョン情報は Application 7.0 で Version 1647 です。
 
もしこの違いということなら、もうどうしようもないですね。 もう少し他の方からの情報も待ってみます。
お手数をおかけしました。ありがとうございました。

回答
投稿日時: 20/11/14 15:14:02
投稿者: なと

・新たに作成した空のUserFormでテストしてください。
もちろん、UserForm_Initialize無しで。
これで再現しなければ、設置しているコントロールが影響しているかもしれません。
 
・あちこちの行に Debug.Print GetAsyncKeyState(vbKeyControl) を、埋め込んでログを取ってください。
もしかしたら、不自然な結果が出るかもしれません。

回答
投稿日時: 20/11/14 15:23:58
投稿者: WinArrow
投稿者のウェブサイトに移動

ロードランナー さんの引用:

Ctrl+右クリックでユーザーフォームを表示
一旦×で閉じて、右クリックだけでは表示しなかった(普通の右クリックメニュー表示)
ということでしょうか???

はい、その通りです。
ロードランナー さんの引用:

ちなみにVBAのバージョン情報は Application 7.0 で Version 1647 です。

 
こちらは、
VBAのバージョン情報は Application 7.1
です。
>1647
は、どこに書いてあるのでしょうか?

回答
投稿日時: 20/11/14 15:27:18
投稿者: WinArrow
投稿者のウェブサイトに移動

>1647
が、Excelのバージョンでしたら
こちらは、1808 です。

投稿日時: 20/11/14 15:49:21
投稿者: ロードランナー
投稿者のウェブサイトに移動

なとさんもアドバイスありがとうございます。
 
おもしろい現象がでました。
 
Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)
    If GetAsyncKeyState(vbKeyControl) = False Then
        Debug.Print GetAsyncKeyState(vbKeyControl)
        UserForm1.Show
        Cancel = True
    End If
End Sub
 
これでやってみたら、Ctrl+右クリックで 最初に −32768 が
次に右クリックだけで 0 が返ってきます。
 
ところが UserForm1.Show をMsgBox にすると −32768 しか返りません。
つまり2回目の右クリックで 0 が返ってこないことが分かりました。 なぜ???
 
釈然としませんが、
 
If GetAsyncKeyState(vbKeyControl) = -32768 Then
 
として対処する手しかなさそうです。
 
WinArrowさんと比べると、VBAのバージョンが明らかに違ってますね。
これのせい???
 
とりあえず、対処療法ですが、上記判定で回避したいと思います。
 
ありがとうございました。