EventShowMoveSpinButton_Value|選んだセルの下に◀▶ボタンを出して入力規則の値を切り替える
まずは動画で、実際の動きをご覧ください(動画内のデータはサンプルです)。
この部品でできること
EventShowMoveSpinButton_Value は、指定した範囲のセルを選ぶと、そのセルの下に◀▶ボタンを表示し、ボタンを押すたびにセルの値を入力規則のリストの前後の値へ切り替えるExcel VBAの汎用プロシージャです。
指定した範囲のセルを選ぶと、セルのすぐ下に◀▶ボタンが現れる
別のセルを選ぶと、ボタンが作り直されずに、そのセルの下へ動いて移動する
▶で次の候補へ、◀で前の候補へ切り替わる
数値の増減ではなく、入力規則のリストの順番で切り替えるので、文字の候補にも使える
範囲の外のセルを選ぶと、ボタンは消える
下の動画は、セルを選ぶとボタンが移動し、押すたびに「出勤・欠勤・有休」が切り替わる様子のデモです。
使いどころ
シフト表の「出勤/欠勤/有休」のように、決まった候補を繰り返し入力するとき
進捗の「未対応/対応中/完了」のように、順番のある状態を一つずつ進めたり戻したりするとき
たくさんのセルに入力するので、ドロップダウンを毎回開く操作を減らしたいとき
シートにボタンを並べて置かず、操作するセルの近くにだけボタンを出したいとき
コード
本体(EventShowMoveSpinButton_Valueと、ボタンを押したときに動くChangeUpValue_MoveSpinButton/ChangeDownValue_MoveSpinButton)に加え、依存するプロシージャもすべて含めています。下記をそのまま標準モジュールに貼り付ければ動作します。
使い方・引数
引数は2つです。
Target(Range)・・・選択されたセル(イベントのTargetをそのまま渡す)
CellArea(Range)・・・ボタンを表示する対象のセル範囲
まず、対象のセルに「データの入力規則」でリストを設定します。サンプルでは、B2:D11に入力規則のリスト(元の値は=$F$3:$F$5、F3:F5に「出勤・欠勤・有休」)を設定し、B2:D11に「処理範囲」という名前を付けています。
次に、対象シートのコードウィンドウにWorksheet_SelectionChangeを用意して、この部品を呼びます。
実際に使用すると、下記の様に選んだセルの下に◀▶ボタンが表示されます。押した瞬間は、ボタンの色が一瞬変わります。

別のセルを選ぶと、同じボタンがそのセルの下へ移動します。

仕組み(技術解説)
この部品は「セルを選んだとき」と「ボタンを押したとき」の2つの処理に分かれています。
1. セルを選んだとき:ボタンを作るか、移動するか
Worksheet_SelectionChangeからEventShowMoveSpinButton_Valueが呼ばれると、まず「減少ボタン」「増加ボタン」という名前の図形がシートにあるかをGetShapeByNameで調べます。その後の分かれ方は次の3通りです。
選んだセルがCellAreaの外なら、ボタンがあれば消して終わる(Intersectで判定)
CellAreaの中で、まだボタンが無ければ、角丸の図形を2つ作って名前とOnActionを登録する
CellAreaの中で、すでにボタンがあれば、作り直さずに選んだセルの下へ移動する
ボタンを毎回作り直さないので、シートに図形が増えていきません。移動はMove__UpDownButtonで4コマに分けて座標を変え、間にDoEventsを入れることで、一瞬で飛ばずに動いて見えるようにしています。
2. ボタンを押したとき:対象のセルは「今選んでいるセル」
図形のボタンは、押してもセルの選択が変わりません。そこで、ChangeUpValue_MoveSpinButton/ChangeDownValue_MoveSpinButtonはGetSelectionCellで今選ばれているセルを取得し、そのセルを対象にします。ボタン側に対象セルの情報を持たせる必要がないので、1組のボタンをどのセルでも使い回せます。
複数のセルが選ばれているときは、ModifyTargetCountで先頭の1セルに絞っています。
3. 入力規則のリストを配列にする
GetCellValidationは、セルのValidation.Formula1からリストの中身を1始まりの一次元配列にして返します。
セル範囲を参照している場合(例 =$F$3:$F$5)・・・=を除いた文字列をRangeに渡して、セルの値を配列に入れる
カンマ区切りで直接書いている場合(例 未対応,対応中,完了)・・・Splitで分けて、ConvArray1D_Start1で1始まりにする
4. 今の値の位置から、前後の値を書き込む
Change__CellValueByListは、GetNumFromArray1Dで今の値がリストの何番目かを調べ、次の値か前の値を書き込みます。
最後の候補で▶を押しても、最初の候補で◀を押しても、値はそのままです。リストに無い値や空欄のときは、どちらのボタンでも先頭の候補が入ります。
依存プロシージャ
このコードは次の自作プロシージャに依存します。上の「コード」ブロックにすべて含めているので、そのまま貼り付ければ動作します。
DrawRectangleRound:ボタンにする角丸の図形を描きます。詳しくはDrawRectangleRoundを参照してください。
ChangePushedButtonColor(内部でGetShapePushed・WaitByDoEventsを使用):押したボタンの色を一瞬変えます。詳しくはChangePushedButtonColor・WaitByDoEventsを参照してください。
GetSelectionCell:選択中のセルを取得します。詳しくはGetSelectionCellを参照してください。
ConvArray1D_Start1(内部でIsArray1Dを使用):配列を1始まりに変換します。詳しくはConvArray1D_Start1・IsArray1Dを参照してください。
GetCellValidation・GetNumFromArray1D・GetShapeByName・ModifyTargetCount:入力規則の取得、配列の検索、図形の取得、対象を1セルに絞る処理です。
応用・注意点
CellAreaのセルには、すべて入力規則のリストを設定してください。入力規則が無いセルでボタンを押すと、Validation.Typeの参照でエラーになります。
セル参照の入力規則はRange(Mid(Formula, 2))で読み取っています。別のシートの参照や名前定義を使う場合は、動作を確かめてから使ってください。
ボタンの名前は「減少ボタン」「増加ボタン」に固定しているので、1枚のシートに出せるのは1組です。同じ名前の図形が他にあると、正しく動きません。
ボタンの大きさはWidth = 30で、高さも同じです。変えたいときはEventShowMoveSpinButton_Valueの中の値を直してください。
マクロで値を書き換えるので、元に戻す操作(Ctrl+Z)では戻せません。
数値を増減したい場合はEventShowSpinButton_Multi、ボタンを出さずにダブルクリックで切り替えたい場合はEventChangeValueFromDropdownlistが向いています。
サンプルブック(ダウンロードして試せます)
まず動かして試したい場合は、下記のサンプルブックをダウンロードして、表のセルを選んでボタンを押すだけで動作を確認できます。
まとめ
EventShowMoveSpinButton_Value は、Worksheet_SelectionChangeから呼ぶだけで、選んだセルの下に◀▶ボタンを出し、入力規則のリストの値を前後に切り替えられるようにする汎用プロシージャです。ボタンは1組だけを移動して使い回すので、シートに図形が増えません。対象のセルを増やすときも、入力規則を設定してCellAreaに含めるだけで対応できます。



