EventSelectChangeUpDownRow|選択行の右に▲▼ボタンを出して行を入れ替える
- yuji fukami
- 20 時間前
- 読了時間: 7分
この部品でできること
EventSelectChangeUpDownRow は、シート上の表の中でセルを選択すると、その行の右(または左下)に▲▼のボタンを自動で表示し、ボタンを押すだけでその行を一つ上・一つ下の行と入れ替えられるようにするExcel VBAの部品です。
表の中でセルを選択すると、その行に対応する▲▼ボタンが自動で現れる
▲を押すとその行が一つ上の行と、▼を押すと一つ下の行と入れ替わる(値も書式もまとめて入れ替え)
表の一番上の行では▲を、一番下の行では▼を表示しないので、範囲の外へはみ出さない
表の範囲外のセルを選択したときはボタンを消す
表の行数が「可変(自動判定)」でも「固定(合計行などがある)」でも使える
イベント(選択の変更)から呼ぶ補助プロシージャなので、シートモジュールの Worksheet_SelectionChange に1行足すだけで設置できます。
下の動画は、表の行数が可変(下に合計行などがない)の表での動作デモです。セルを選ぶと▲▼が出て、ボタンで行が上下に動く様子が確認できます。
使いどころ
並び順を手で入れ替えたい明細表(作業リスト・持ち物リスト・優先順位表など)で、行の並べ替えをボタン操作で行いたいとき
「切り取って上の行に挿入」のような操作が面倒で、選択した行をワンクリックで上下に動かしたいとき
数式や書式ごと行を入れ替えたいとき(値だけでなく、その行の見た目も一緒に動く)
合計行や見出しなど、動かしたくない行を巻き込まずに、表の本体だけを並べ替えたいとき
コード
宣言セクションの Enum はモジュールの先頭に配置してください。本体(EventSelectChangeUpDownRow と UpDownRow_ByEventButton)に加え、依存する GetEndRow / GetEndCellRow / GetSelectionCell / GetCellFromRowColCells / DrawRectangleRound / DeleteShapeNameLike などの部品もすべて含めています。下記をそのまま標準モジュールに貼り付ければ動作します。
使い方・引数
この部品は、ボタンやショートカットから直接呼ぶのではなく、シートモジュールの選択変更イベント Worksheet_SelectionChange から呼びます。セルを選ぶたびに EventSelectChangeUpDownRow が動いて、選択行に対応する▲▼ボタンを描き直す仕組みです。
EventSelectChangeUpDownRow の引数は次のとおりです。
Target(Range):選択中のセル。Worksheet_SelectionChange の引数 Target をそのまま渡します
StartCell(Range):表の左上の基準セル(ヘッダーのセル)。行・列の基準になります
ColCount(Long):表の列数
EndCell(Range・省略可):表の最終行のセル(合計行など「表の本体の下」にあるセル)。省略すると最終行を自動判定します
Position(省略可):ボタンの表示位置。vbセルの左下(既定)または vbセルの右上
設置手順(シートモジュールに1行足すだけ)
上の「コード」ブロックを標準モジュールに貼り付けたら、対象シートのシートモジュールを開き、次のように Worksheet_SelectionChange から EventSelectChangeUpDownRow を呼びます。シートモジュールは、プロジェクトエクスプローラーで対象シート(例:Sheet1)をダブルクリックすると開けます。
表の行数が可変の場合(EndCell を省略)
下に合計行などがなく、表の行数がデータ量に応じて増減する場合は、EndCell を省略します。省略すると GetEndCellRow で最終行を自動判定するので、行数を気にせず使えます。

上の図のように、表の左上のセルに名前定義(例:ヘッダー1)を付けておき、次のように書きます。
EndCell を渡していないので、ColCount の一列目(StartCell の列)を下にたどって最終行を自動判定します。この動きは上の動画(動作デモ1)のイメージです。
表の行数が固定の場合(EndCell を明示)
表の下に合計行や備考欄など「動かしたくない固定の行」がある場合は、EndCell に表本体の最終行の一つ下のセル(合計行など)を渡します。これで合計行を巻き込まずに、表の本体だけを並べ替えられます。

上の図と動画(動作デモ2)のように、合計行のあるセルに名前定義(例:最終位置)を付けておき、次のように書きます。
このとき、StartCell と EndCell は、必ず名前定義(名前付き範囲)で渡してください。Range("B10") のようなアドレス直指定にすると、行を挿入・削除したときにアドレスがずれ、別のセルを指してしまいます。名前定義にしておけば、レイアウトが変わっても同じ論理セル(表の最終行など)を指し続けます。
仕組み(▲▼ボタンが動く流れ)
この部品は、選択変更イベントとボタンのクリックの二段構えで動いています。
セルを選ぶと Worksheet_SelectionChange が発火し、EventSelectChangeUpDownRow が動きます。まず DeleteShapeNameLike で古い▲▼ボタン(名前が「上下」で始まる図形)を消し、選択セルが表の範囲内なら▲▼ボタンを新しく描きます
描いた▲▼ボタンには、表の本体範囲のアドレスを含んだ名前(例:上下_Up_$B$3:$F$7)を付け、OnAction に UpDownRow_ByEventButton を割り当てます
▲▼ボタンをクリックすると UpDownRow_ByEventButton が動きます。ボタンの名前から「上か下か」と「表の範囲」を読み取り、選択行と入れ替え先の行の値(FormulaR1C1)を丸ごと交換します。交換の間は Application.EnableEvents = False にして、イベントの連鎖を止めています
入れ替えは値・数式ごと行われ、最後に移動先の行のセルを選択し直すので、続けて同じ方向のボタンを押していけます
表の一番上の行では▲を、一番下の行では▼を描かないようにしているため、ボタンで表の範囲外へはみ出すことはありません。EndCell を省略したか明示したかで、この「一番下の行」の判定が自動判定か固定かに変わります。これが「表の行数が可変/固定」の使い分けの正体です。
依存プロシージャ
このコードは次の自作プロシージャに依存します。上の「コード」ブロックにすべて含めているので、そのまま貼り付ければ動作します。宣言セクションの Enum EnumCellNearPosition はモジュールの先頭に置いてください。
GetSelectionCell:選択中のセルを取得する部品です。詳しくは GetSelectionCell を参照してください。
GetEndRow:指定セルを基準に最終行番号を取得する部品です。詳しくは GetEndRow を参照してください。EndCell 省略時の自動判定に使っています。
DeleteShapeNameLike:指定した名前で始まる図形をまとめて消す部品です。詳しくは DeleteShapeNameLike を参照してください。古い▲▼ボタンの消去に使っています。
GetEndCellRow:GetEndRow を使って最終行のセルそのものを返す部品です。
GetCellFromRowColCells:行基準のセルと列基準のセルから、行と列を組み合わせた一つのセルを取得する部品です。選択行の開始・終了セルを求めるのに使っています。
DrawRectangleRound:角が丸い長方形(▲▼ボタン)を作図する部品です。
ModifyTargetCount:イベント処理用に、複数セル選択時の Target を先頭の1セルに絞る部品です。
ChangePushedButtonColorAuto / ChangePushedButtonColor / GetShapePushed / GetShapeByName / WaitByDoEvents / 色変換系(GetRGB_Array / ConvLighterColor / ConvDarkerColor):ボタンを押したときに一瞬色を変える演出のための部品です。
応用・注意点
StartCell と EndCell は、必ず名前定義(名前付き範囲)で渡してください。行の並べ替えや挿入・削除でセルのアドレスがずれても、名前定義なら同じ論理セルを指し続けます。特に EndCell はアドレス直指定を避けてください。
入れ替えは FormulaR1C1 で値・数式ごと行います。相対参照の数式は入れ替え後も同じ相対関係を保ちますが、他のセルから絶対参照している場合は、参照先の中身が入れ替わる点に注意してください。
入れ替え中は Application.EnableEvents = False でイベントを止めています。もし途中でエラーが出て True に戻る前に処理が止まると、以降イベントが発火しなくなります。実運用ではエラー処理を足しておくと安全です。
ボタンの大きさは Width = 30(高さも同じ)で決めています。行の高さやフォントに合わせて調整したい場合はこの値を変えてください。
選択した行を上下に動かすだけでなく、行そのものを増やしたい・減らしたいときは、選択行の上に行を挿入する InsertRowSelectCell_Table や、選択行を削除して上に詰める DeleteRowSelectCell_Table と組み合わせると、明細表の編集がボタン操作だけで完結します。
サンプルブック(ダウンロードして試せます)
コードとテストコードのとおりですが、まず動かして試したい場合は、下記のサンプルブックをダウンロードしてください。表の中でセルを選ぶと▲▼ボタンが現れ、そのボタンを押すだけで行の入れ替えの動作を確認できます。可変・固定の両方のシートを用意しています。
まとめ
EventSelectChangeUpDownRow を Worksheet_SelectionChange から呼ぶだけで、表の中でセルを選ぶと▲▼ボタンが自動で現れ、クリックひとつでその行を上下に入れ替えられるようになります。表の行数が可変なら EndCell を省略、下に合計行などがある固定の表なら EndCell を名前定義で渡す、という使い分けだけ覚えておけば、明細表の並べ替えをボタン操作で完結できる実務向けの部品です。
