Excel (VBA)

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

 
(Windows 11 Pro : Excel 2021)
UserForm上のコマンドボタンでのダブルクリック
投稿日時: 24/05/21 15:29:36
投稿者: ナバ

初めまして。
 
複数のUserFormで順に入力(のコマンドボタンのクリック)をしていくツールを作っています。
UserFormがForm1、Form2、Form3とあり、それぞれコマンドボタンをcmd1〜cmd4、配置しています。
ボタンの位置と大きさはそれぞれのフォームでほぼ同じです。
 
Form1からForm2への切り替えは
 

Private Sub cmd1_click()
    〜〜個別処理〜〜
    Unload Me
    Form2.Show vbModal
End Sub

としています。
 
困っていることは、Form1上のcmd1をダブルクリックされるとForm2のcmd1_Clickイベントが発生してしまい、Form3まで進んでしまうことです。
クリックが次のフォームまで残ってしまう、とでもいうんですかね。
 
Sleepを挟んでみたり、Timerのクラスを使ってみたりしましたがどうしてもこの動きを回避できません。
なにかいい方法はありませんでしょうか?[/code]

回答
投稿日時: 24/05/21 16:18:15
投稿者: sk

引用:
ボタンの位置と大きさはそれぞれのフォームでほぼ同じです

引用:
Form1上のcmd1をダブルクリックされるとForm2のcmd1_Clickイベントが発生

1. [Form1]の[cmd1]を Click イベントが発生し、
   イベントプロシージャにより[Form2]が表示される。
   ( 1 回目のマウスクリック)
 
2. [Form2]が表示された時点において、[Form2]の[cmd1]のある位置に
   ちょうどマウスポインタ―が重なっている
 
3. その状態で[Form2]の[cmd1]がクリックされる。
   ( 2 回目のマウスクリック)
 
以上のような流れの操作が行われているのが原因なのではないかと。
 
例えば、[Form1]の[cmd1]と[Form2]の[cmd1]の位置を大きく
ずらせば発生しないのではないでしょうか。

回答
投稿日時: 24/05/21 17:05:30
投稿者: Suzu

Private Sub CommandButton1_Click()
  Debug.Print "Form1_cmd_Click"
  Unload Me
  Form2.Show vbModal
End Sub
 
Private Sub CommandButton1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
  Debug.Print "Form1_cmd_DoubleClick"
End Sub
 
とでもすれば判ると思いますが
 
 
・Click と Doubleclick では、先に Click イベントが発生します。
 
・さらに、Click イベントの処理が終了するまで Doubleclickイベントは 発生しません。
 
ですので、
コマンドボタンに、ダブルクリックイベントを仕込んでも
クリックイベントの段階で、Form1 が 閉じてしまうので Doubleclickイベントが発生しません。
 
さらに、Unload メソット を 発しても、
Clickイベント内のプロシージャを実行し終えるまでは、Unloadされません。
 
なので、発生した現象の様に、
 
1回目のクリックで、Form1 が閉じる
同じ位置に、Form2が開く
 
Form1 が 閉じられる
ダブルクリックと思っている クリックが、シングルクリック扱いで、Form2 の ボタンがクリックされる
 
という事で、Form3 が開かれる事になります。
 
対策としては、
Form2 の Initialize あたりで、Wait すれば良いかと。
 

引用:
Private Sub UserForm_Initialize()
  Dim newHour, newMinute, newSecond, waitTime
 
  newHour = Hour(Now())
  newMinute = Minute(Now())
  newSecond = Second(Now()) + 1
  waitTime = TimeSerial(newHour, newMinute, newSecond)
  Application.Wait waitTime
End Sub

回答
投稿日時: 24/05/21 18:52:57
投稿者: hatena
投稿者のウェブサイトに移動

原因は既にお二方から提示されてる通りだと思います。
 
一番シンプルな解決法はskさんの方法でしょう。
 
Suzuさんの方法を試してみましたが、Form2 の表示が遅れるということと、場合によってはForm3が開かれてしまうことがありました。
 
どうしても、コマンドボタンの位置は同じ位置にしておきたいという場合は、無理やりですが、
APIでマウスカーソルの位置をずらす方法を考えてみました。
 
標準モジュール

Option Explicit
Type POINTAPI
        x As Long
        y As Long
End Type
Declare PtrSafe Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long
Declare PtrSafe Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long

 
Form1のモジュール
 
Private Sub cmd1_Click()
   '〜〜個別処理〜〜

    Dim p As POINTAPI
    GetCursorPos p
    SetCursorPos p.x, p.y - cmd1.Height - 20
    Unload Me
    UserForm2.Show vbModal
End Sub

 
まあ、これもマウスカーソルが勝手にずれるので違和感はありますが。

投稿日時: 24/05/22 11:12:24
投稿者: ナバ

最初の質問で説明不足な点があり、申し訳ありません。
 
skさん

sk さんの引用:

例えば、[Form1]の[cmd1]と[Form2]の[cmd1]の位置を大きく
ずらせば発生しないのではないでしょうか。

それができるといいのですが、デザイン上の制約があり大きくずらすことは難しいです。
 
Suzuさん
ダブルクリックでなにかさせたいのではなくシングルクリックだけで使ってほしいのですが、不特定多数に使ってもらうツールのため、あやまってダブルクリックをしてしまうことを考えなければなりませんでした。
Application.Wait waitTime
は、hatenaさんご指摘のようにForm3が開かれてしまうことがありました。
 
hatenaさん
hatena さんの引用:

どうしても、コマンドボタンの位置は同じ位置にしておきたいという場合は、無理やりですが、
APIでマウスカーソルの位置をずらす方法を考えてみました。

hatenaさんに教えていただいた方法で今回の現象は回避できました。
 
みなさま、回答いただきありがとうございました。