EventChangeValueFromDropdownlist|ダブルクリックでドロップダウンの値を切り替える
- yuji fukami
- 2 日前
- 読了時間: 6分

この部品でできること
EventChangeValueFromDropdownlist は、ドロップダウンリスト(データの入力規則)を設定したセルを、リストを開かずにダブルクリックするだけで次の候補へ切り替えられるようにするExcel VBAの汎用プロシージャです。
ダブルクリックするたびに、ドロップダウンリストの選択肢を順番に切り替える
最後の候補まで行くと、先頭の候補に戻る(循環する)
ドロップダウンリストが設定されていないセルでは何も起きない(自動で判定する)
リストの指定方法(セル参照・カンマ区切り・単一の値)を問わず、そのまま使える
YES/NO や ON/OFF のような2択の設定セルであれば、ダブルクリック1回で切り替わるので、リストを開いて選ぶ操作が不要になります。
下の動画は、実際にセルをダブルクリックして値が切り替わる様子のデモです。
使いどころ
YES/NO、ON/OFF、有効/無効 のような2択の設定セルを、ワンアクションで切り替えたいとき
チェックボックスの代わりに、セルの値で状態を管理しているとき
入力規則のリストは残したまま(手入力を防いだまま)、選択の操作だけを速くしたいとき
担当者名やステータスなど、決まった候補を順に切り替えながら入力していくとき
コード
使い方・引数
引数は3つです。Opt_CancelEvent は省略可能です。
Target(Range)・・・ダブルクリックされたセル(イベントの Target をそのまま渡す)
Cancel(Boolean)・・・ダブルクリックの既定動作をキャンセルするかどうか(イベントの Cancel をそのまま渡す)
[Opt_CancelEvent](Boolean)・・・値を書き込むときに Worksheet_Change イベントを止めるなら True(既定値)
導入は、ワークシートのコードウィンドウにダブルクリック時のイベントプロシージャを用意し、その中でこのプロシージャを呼ぶだけです。実質1行で設置できます。

このように書いておけば、あとは対象にしたいセルに「データの入力規則」でドロップダウンリストを設定するだけです。VBA側で対象セルを指定する必要はありません。

上の例では「元の値」に YES,NO とカンマ区切りで直接入力しています。この状態でセルをダブルクリックすると、YES → NO → YES … と順に切り替わります。
仕組み(1行で設置できる理由)
このプロシージャは、対象セルの指定をコード側に持たせず、シート側の「データの入力規則」の設定をそのまま使う設計になっています。これが実質1行で導入できる理由です。
処理は大きく3段階です。
1. ドロップダウンリストが設定されたセルかを判定する
まず、ダブルクリックされたセルの入力規則の数式(Validation.Formula1)を取得します。
入力規則が設定されていないセルでは Validation.Formula1 の取得自体がエラーになるため、On Error Resume Next でエラーを無視し、ValidationFormula が空のままなら Exit Sub で何もせずに抜けます。この判定があるおかげで、シート上のどのセルをダブルクリックしても安全で、「このセルだけ対象にする」という指定をコードに書かずに済みます。
冒頭の If Target.CountLarge > 1 Then Set Target = Target(1) は、複数セルが選択された状態でダブルクリックされたときに、先頭の1セルだけを対象にするための処理です。
2. 入力規則から選択肢の一覧を取り出す
ここがこの部品の中で最も手が込んでいる部分です。Excelの入力規則は、リストの指定方法がいくつもあり、Validation.Formula1 から返ってくる文字列の形もそれぞれ違います。この部品では、次の4パターンに分岐して対応しています。
セル範囲を参照している場合(例 =$H$3:$H$5)・・・Range として取得し、WorksheetFunction.Transpose で一次元配列に変換する
単一のセルを参照している場合(例 =$H$3)・・・要素1つの配列を作ってその値を入れる
カンマ区切りで直接指定している場合(例 YES,NO)・・・Split で分割する
単一の値だけを指定している場合(例 YES)・・・要素1つの配列を作る
セル参照かどうかの判定には、Range(Mid(ValidationFormula, 2)) を On Error Resume Next の中で試し、Nothing でなければセル参照だった、という方法を使っています。先頭の = を Mid で取り除いてから Range に渡すのがポイントです。
なお、カンマ区切りの場合に WorksheetFunction.Transpose を2回続けて呼んでいるのは、Split が返す0始まりの一次元配列を、他の分岐と同じ「1始まりの配列」に揃えるためです。こうしておくことで、この後の切り替え処理をパターンごとに書き分けずに済みます。
3. 現在の値から次の値を決めて書き込む
取得した選択肢の一覧を先頭から順に見ていき、現在のセルの値と一致した位置の「次」を新しい値にします。最後の要素と一致した場合は先頭に戻るので、ダブルクリックを繰り返すとリストを循環します。
一致の判定は、選択肢と現在値の両方が数値なら Val で数値として比較し、そうでなければ文字列として比較しています。"01" と 1 のように、見た目が違っても数値としては同じ値を正しく扱うための工夫です。
現在の値がリストのどれにも一致しなかった場合(空欄のときなど)は、IsEmpty(NextValue) の判定でリストの先頭の値が入ります。
最後に Cancel = True を設定して、ダブルクリック本来の動作(セルの編集モードに入る)をキャンセルしています。これがないと、値が切り替わった直後に編集モードへ入ってしまいます。
依存プロシージャ
このコードは自作の依存プロシージャを持たない、自己完結した部品です。上のコードブロックをそのまま標準モジュールに貼り付ければ動作します。
応用・注意点
Opt_CancelEvent を True(既定)にすると、値を書き込む前後で Application.EnableEvents を切り替え、Worksheet_Change イベントが発生しないようにします。値の変更をトリガーに別の処理を動かしているブックで、切り替えのたびにその処理まで走ってしまうのを防ぐためのオプションです。逆に、切り替えと連動して再計算や再描画をしたい場合は False を渡してください。
ダブルクリックだけでなく、右クリック時のイベント(Worksheet_BeforeRightClick)から呼び出すこともできます。引数の形が同じなので、同じように1行で設置できます。
対象セルに「データの入力規則」の入力時メッセージを設定しておくと、セルを選択したときに「ダブルクリックで値切替」といったポップアップを表示できます。この機能を知らない人にも操作方法が伝わるので、実運用では設定しておくと親切です。

入力規則の「元の値」に名前定義(例 =リスト名)を指定している場合、Range として解決できずに Exit Sub で抜けてしまうことがあります。名前定義を使いたい場合は、セル範囲を直接参照する形に変えるか、名前定義を解決する処理を足してください。
セルの値を書き換える処理なので、元に戻す操作(Ctrl+Z)では戻せません。重要な値を扱うセルで使う場合は注意してください。
同じイベントプロシージャの中に他の処理も書いている場合は、Cancel の扱いに注意してください。このプロシージャは値を切り替えたときだけ Cancel = True にするので、切り替えが起きなかった場合は後続の処理をそのまま続けられます。
サンプルブック(ダウンロードして試せます)
コードの詳しい動きは上のコードブロックと解説のとおりですが、まず動かして試したい場合は、下記のサンプルブックをダウンロードして、セルをダブルクリックするだけで動作を確認できます。
まとめ
EventChangeValueFromDropdownlist は、Worksheet_BeforeDoubleClick から1行呼ぶだけで、ドロップダウンリストを設定したセルをダブルクリックで順送りできるようにする汎用プロシージャです。対象セルの指定をコードに持たせず、シート側の入力規則をそのまま利用する設計なので、あとから切り替えたいセルが増えても、入力規則を設定するだけで対応できます。リストの指定方法(セル参照・カンマ区切り・単一値)も自動で判別するため、既存のブックにそのまま組み込みやすい部品です。
