Excel (VBA)

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

 
(指定なし : 指定なし)
解決済み「UserForm上のコマンドボタンでのダブルクリック」について
投稿日時: 24/05/22 14:36:03
投稿者: hatena
投稿者のウェブサイトに移動

言い足りないことがあったのでここに追記しておきます。
 
質問内容をまとめると、
Form1→Form2→Form3 とコマンドボタンクリックで移動するUIで、
コマンドボタンをダブルクリック(短時間で複数回クリック)すると、次のフォームのコマンドボタンをクリックしたことになり、次の次のフォームへ移動してしまう。これを防ぎたい。
 
原因は、
それぞれのフォームのコマンドボタンの位置が同じなので、複数回クリックの後のクリックが次のフォームのコマンドボタンをクリックしたことになる。
 
回答としては、
各ワームのコマンドボタンの位置をずらす。 → デザイン上の制約で無理
Form2 のInitializeで、Waitする → タイミングによってForm3が開かれてしまうことがある
APIでカーソルの位置を無理矢理ずらす → 採用
 
ということで私の回答が採用されました。
ただ、この方法も完全とはいえないと思います。
カーソルが勝手にずれることに違和感がある。
また、絶対Form3へ移動しないという保証はない。
カーソルを移動させながら複数回クリックすると偶然、次フォームのコマンドボタン上でクリックしたことになることがあるかもしれない。
 
で、この質問の根本的な意図は、下記のようなことだと思われます。
Form2の内容を読んで理解してから次へ移動してほしい。
あるいは、なんらかの操作をしてから、次へ移動してほしい。
 
 
だとしたら、適切な対策は下記のようなことになると思います。
内容を読んで理解してほしいのなら、読みおわるのにかかる時間が経過するまではコマンドボタンをクリックできないようにしておく。
あるいはしてほしい操作が終了するまでは、コマンドボタンをクリックできないようにしておく。
 
前者の場合、読み終わる時間は人によって異なりますので、どのくらいの時間にすればいいか難しいです。
一番適切だと思われるUIは、下記のようなものではないかと思います。
ユーザーが読み終わって確認したら、チェックボタンをクリックする。
チェックボタンがクリックされたらコマンドボタンがクリックできるようにする。
 
なんらかの操作の場合、
例えばテキストボックスなどのコントロールへの入力などなら、そのコントロールのAfterUpdate(更新後処理)あたりでコマンドボタンをクリックできるようにすればいいでしょう。
 
前者の場合のサンプル
Form2 のコマンドボタン(md1) Enableプロパティを False に設定しておく
チェックボックス(CheckBox1)を配置
キャプションは「内容を確認した」など適切なものに設定
 

Private Sub CheckBox1_AfterUpdate()
    cmd1.Enabled = CheckBox1.Value 'チェックが入ったらコマンドボタン使用可能
End Sub

Private Sub cmd1_Click()
    Unload Me
    UserForm3.Show vbModal
End Sub

投稿日時: 24/05/22 14:56:14
投稿者: hatena
投稿者のウェブサイトに移動

投稿してから、 Suzuさんからのレスに気づきました。
 
フォーム移動ではなく
Suzuさん提案のタブページ(マルチページ)のページ移動を利用したUIもありだと思います。
 
マルチページの各ページにForm1, Form2, Form3と同じようにコントロールを配置。
マルチページのStyleプロパティを fmTabStykeNone に設定してタブを非表示にする。
 
このような設計すると、戻るボタンを配置して、前のページに戻って確認するというUIも簡単に構築できます。
 
ダブルクリック操作による弊害を対症療法的に防止するのではなく、
ユーザーにとって適切なUIを考えるという根本に立ち返って考えるべきだと思いました。
 

投稿日時: 24/05/22 16:50:39
投稿者: hatena
投稿者のウェブサイトに移動

関連リンク
 
UserForm上のコマンドボタンでのダブルクリック
https://www.moug.net/faq/viewtopic.php?t=82771
 
Re:UserForm上のコマンドボタンでのダブルクリック
https://www.moug.net/faq/viewtopic.php?t=82772

投稿日時: 24/05/22 17:55:19
投稿者: hatena
投稿者のウェブサイトに移動

マルチページを使った場合のサンプルを作成してみました。
 
マルチページでもコマンドボタンの配置を各ページ同じにすると、ダブルクリックでページが跳んでしまうという同じ現象が発生するので、フォーム移動と同じ対策が必要。
 
ユーザーフォームにマルチページ(MultiPage1)を配置
タブ部分をクリックして「新しいページ」をクリックしてページを追加(3ページになる)
 
Page1 に下記のコントロールを配置
コマンドボタン cmdNext1
 Caption: 次へ
 
Page2 に下記のコントロールを配置
 
チェックボックス chkConfirm
 Caption: 確認しました
 
コマンドボタン cmdNext2
 Caption: 次へ
 
コマンドボタン cmdBack1
 Caption: 前へ戻る
 
Page3 に下記のコントロールを配置
コマンドボタン cmdBack2
 Caption: 前へ戻る
 
コマンドボタン cmdFinish
 Caption: 終了
 
フォームモジュールのコード
 

Option Explicit

Private Sub UserForm_Initialize()
    Me.MultiPage1.Style = fmTabStyleNone
    Me.MultiPage1.Value = 0
    Me.cmdNext2.Enabled = False
End Sub

'// Page1 //
Private Sub cmdNext1_Click() '次へ
    Me.MultiPage1.Value = 1
End Sub

'// Page2 //
Private Sub chkConfirm_Click() '確認しました
    Me.cmdNext2.Enabled = Me.chkConfirm.Value
End Sub

Private Sub cmdBack1_Click() '前へ戻る
    Me.chkConfirm.Value = False
    Me.MultiPage1.Value = 0
End Sub

Private Sub cmdNext2_Click() '次へ
    Me.MultiPage1.Value = 2
End Sub

'// Page3 //
Private Sub cmdBack2_Click() '前へ戻る
    Me.MultiPage1.Value = 1
End Sub

Private Sub cmdFinish_Click() '終了
    If MsgBox("終了します。", vbOKCancel) = vbOK Then Unload Me
End Sub

回答
投稿日時: 24/05/22 20:20:36
投稿者: たらのり

こんばんは
 
# ずいぶん昔の話なので記憶違いがあるかもしれません
 
やはりユーザーフォームに表示されたボタンをクリックして
ある程度実行時間を要する処理をしている途中で Enterキーを
押下すると,処理が終わってユーザーフォームに戻るやいなや,
Enterキーが押下されたとみなされて不本意に処理が推移して
しまうといったことがあり,
 
そのときにはたしか,実行時間を要する処理(クリックイベント)
の最後に APIの PeekMessage() でメッセージキューからキーの
入力を削除する処理を入れて対応したような……
 
Visual Basic 6.0(.NET でない) だったかと。
 
# あ,ここは給湯室ではないのか…!?
 
 

投稿日時: 24/05/23 10:05:52
投稿者: hatena
投稿者のウェブサイトに移動

たらのりさん、こんにちは。
 
その手の問題はあるあるですが、ユーザーの操作ミスや無意識の操作が原因ですよね。
 
処理中にキーを押してしまう、マウスクリックしてしまうということはありえるので、
処理中に、あるいは想定される状況になるまでは、ユーザーがどのような操作をしても、別の処理が実行されないようなUI設計にするというのがマストではないかと思いました。
 
元質問の複数回クリック対策として、マウス操作に対する対策をしたとしても、コマンドボタンにフォーカスがある状態で、EnterキーやSpaceキーの連打でも同じ問題が発生しますので、それに対する対策が必要になってきます。
このようにそれぞれの想定外の操作に対して個別に対策をしていてはきりがないので、コマンドボタンを使用不可にしておいて、クリックされてもいい状況になったら使用可能にするという設計にすべきでしょうね。

回答
投稿日時: 24/05/23 14:03:18
投稿者: たらのり

hatena さん、こんにちは
 
ご指摘のとおりだと思います。
 
ほとんどの場合において UI設計で問題は回避可能で、裏技的な手法の使用は
避けるべきだと思います。
 
機能的に設計された UIの実装(プログラム)は、よりシンプルで堅牢なものになる
傾向があると思います。
 

投稿日時: 24/05/23 14:31:45
投稿者: hatena
投稿者のウェブサイトに移動

たらのりさん
その通りだと思います
 
元スレでは私の回答が採用されましたが、APIでカーソル位置をずらすなどという方法は悪手ですね。
 
質問者さんが、このスレに気づいてくれることを祈るばかりです。
 
このスレは一日ぐらい置いてから閉じます。
 

投稿日時: 24/05/24 15:17:08
投稿者: hatena
投稿者のウェブサイトに移動

閉じます。