TL;DR — データを消さずに行を移動するには、切り取ってから Insert します — 貼り付けてはいけま せん。
Rows(5).Cut Destination:=Rows(20)は行を行 20 の 上に 落とし、そこにあったものを上書きしま す。Rows(5).CutのあとRows(20).Insertなら、行 20 にすき間を空けて行を差し込み、元あった場所の穴 を閉じます — 何も壊れません。移動は シフト です。だから罠に注意してください。行を 下へ 動かす と、残された穴が下にあるすべての行 — あなたの対象も含めて — を一つずつ繰り上げます。
Sub MoveRow()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Data")
ws.Rows(5).Cut ' 行を持ち上げる(回る点線)、元はまだ消えていない
ws.Rows(20).Insert Shift:=xlDown ' 切り取った行を行 20 の前に INSERT し、残りを下へずらす
Application.CutCopyMode = False ' 終わったらクリップボードの状態をクリアする
End Sub
行の移動、列の移動、そしてその下で動いている Cut という動詞は、一つの考え方です — データを持ち上げ、
それをどう置くかを選ぶ。Insert はすき間を空けてすべてを保ち、Paste は上に落として上書きします。行
のケースをきちんと押さえれば — 切り取り、挿入、シフトに気をつける — 列の移動は同じ動きを 90 度回転させ
ただけのものになり、どちらも同じ Range.Cut に支えられています。
この記事で学べること
- 考え方の軸 — 移動とは 切り取って挿入する ことであり、挿入は シフト であって貼り付けではない
- 第一の罠 —
Cut Destination:=と貼り付けは対象を 上書き してデータを失う - 行を 下へ 動かすと元の行より下がすべて番号を振り直され、対象が一つ繰り上がる理由
- 複数の行を間違った順序で着地させずに一度に移動する方法(下から上へ)
- なぜ数式の参照は削除のように
#REF!に砕けず、切り取った行に 追従する のか
考え方の軸:移動はシフトであって、貼り付けではない
「この行を移動する」という言葉には、二つの動作が隠れています。まず 持ち上げる — Rows(5).Cut は行
を切り取りモードでクリップボードに載せます(回る点線、marching ants)。次に 置く のですが、データ喪
失の物語はすべてここから始まります。置き方がまったく異なる二通りあるからです。
- 貼り付ける(
Cut Destination:=Rows(20)、あるいは手動の.Cutのあと.Paste)は、行を行 20 の 上に 落とします。行 20 の元の中身は、警告もなく、静かに消えます。 - 挿入する(
Rows(5).CutのあとRows(20).Insert)は、行 20 に新しいすき間を空け、切り取った行を そこに落とし、行 5 にできた穴を閉じます。残りはすべて場所を空けるためにずれます。何も失われません。
行の移動は、常に後者の動作です。これは、行の 挿入 や 削除 ですでに知っているのと同じ シフト です。グリッドが物理的に開いて閉 じ、変更より下がすべて番号を振り直されます。ここを離さないでください — この記事のすべては「移動とは切 り取って 挿入 すること(すき間を空ける)であって、貼り付けではない」から導かれます。
第一の罠:上に貼り付けると対象を上書きする
これは行を移動しているように見えますが、マクロでデータを壊す最もありふれた方法です。
ws.Rows(5).Cut Destination:=ws.Rows(20) ' 移動には誤り - これは行 20 の上に PASTE する
Cut Destination:= は 貼り付け です。行 5 のセルを行 20 の上にコピーし、行 20 のデータを上書きしてか
ら、行 5 を空にします。行 20 に何かあったなら、それは消えます。行 20 が本当に空の作業スペースなら問題あ
りませんが、「この行を他の行の間に差し込む」つもりだったなら大惨事です。
データを保つ移動は、切り取ってから Insert することです。
ws.Rows(5).Cut ' 持ち上げる
ws.Rows(20).Insert Shift:=xlDown ' 正しい - すき間を空けて差し込む、何も上書きしない
クリップボードに切り取ったセルがあるとき、.Insert は 切り取ったセルの挿入 を行います — 上に落とす
のではなく、場所を空けます。ルールは身も蓋もありません。移動するなら、切り取ったものを挿入する。決し
て貼り付けない。 Cut Destination:= に手を伸ばすのは、空の対象を本当に上書きしたいときだけです。
シフトの罠:下へ動かすと対象の番号が変わる
ヘルプフォーラムを埋め尽くす驚きがこれです — 「行を切り取って下の方に挿入したら、データが全部上に動い た」。これはバグではありません。シフトが一貫しているだけです。
切り取りと挿入は一つの操作として起こります。行 5 を行 20 まで下へ動かすと、行 5 の穴は同じ移動の一部と
して閉じるので、行 6 から 20 はそれぞれ 一つずつ繰り上がり — 20 だった行は今 19 にいます。あなたの
行は、20 と書いたときに頭に描いていた行番号ではなく、ずれたあとの グリッドを基準に着地します。
直し方は、べた書きの行番号で移動するのをやめることです。その番号は足元で動いてしまうからです。目印を 値 で見つけ、それを基準に挿入すれば、シフトに騙されません。
Dim target As Range
Set target = ws.Columns("A").Find("Subtotal", LookAt:=xlWhole) ' 番号ではなく WHERE を見つける
ws.Rows(5).Cut
target.EntireRow.Insert Shift:=xlDown ' シフトの有無にかかわらず、本物の "Subtotal" 行の上に挿入する
Application.CutCopyMode = False
どうしても番号を使うなら、向きを覚えておいてください。上へ 動かす(元が対象より下)と対象の番号は そのまま、下へ 動かす(元が対象より上)と対象は一つ繰り上がります。迷ったら、見つけた目印の上に挿入 しましょう。
複数行を移動する:下から上へ
前進ループで行を一つずつ移動すると、移動のたびにまだ触れていない行の番号が振り直され、二回目の移動は間 違った行をつかみます。これはループで行を削除するときと同じ規律です — 下から上へ処理する ことで、シ フトはカーソルの 下 で起こり、これから移動する行を乱しません。
Dim i As Long
For i = lastRow To firstRow Step -1 ' 下から上へ:シフトは上ではなく下で起こる
If ws.Cells(i, "D").Value = "Archive" Then
ws.Rows(i).Cut
ws.Rows(archiveTop).Insert Shift:=xlDown
End If
Next i
Application.CutCopyMode = False
連続したブロックなら、五回ループして五回のシフトと格闘するのではなく、一度で移動します —
ws.Rows("5:9").Cut のあと一回の .Insert。一回の切り取り、一回の挿入、ループの途中で番号が振り直され
る驚きもありません。
Cut は参照を運ぶ、削除は壊す
Cut + Insert が安全な移動である理由がもう一つあります。Excel がそれに 追従する からです。どこか別
の場所にある =Data!B5 という数式は、移動後に行の新しい住所を指すよう書き換えられ、同じデータを読み続
けます。これは 行を削除する ときの逆です。削除された行を 指していた 数式は
=#REF! に潰れ、壊れたままになります。移動はデータを引っ越しさせ、その参照も一緒に連れていきます。削除
はデータを壊し、参照を宙ぶらりんにします。目標が「同じ数字を、別の場所に」なら、それがまさに望む挙動で
す。
ExcelMaster の活用
行の移動は、一行に見えて三つの判断を隠しています — 挿入か貼り付けか(データを保つか壊すか)、シフトが どちら向きに進むか(そして対象の番号がまだ思った通りの意味かどうか)、そしてブロックを一回の呼び出しで 移動するか下から上へループするか、です。どれか一つでも間違えると、静かに失敗します。対象の行が黙って上 書きされる、行が一つずれて着地する、あるいはループの半分が間違った枠に移動される、といった具合です。
ExcelMaster には、望むことをその まま伝えられます — 「すべての Archive 行をアーカイブブロックの先頭へ、すでにあるデータは残したまま移動 して」 — すると、貼り付けではなく切り取って 挿入 し、シフトに騙されないよう目印を値で見つけ、複数あ るときは下から上へループします。ブックとコードはあなたの手元に残ります。
よくある質問
VBA で行を上書きせずに移動するには?
行を切り取ってから Insert します。貼り付けてはいけません。ws.Rows(5).Cut のあと
ws.Rows(20).Insert Shift:=xlDown。Insert は移動先にすき間を空けて他の行を下へずらすので、何も上書き
されません。Rows(5).Cut Destination:=Rows(20) は行 20 の上に貼り付けて中身を壊します — 使うのは対象が
空のときだけにしましょう。
行を切り取って挿入したのに、なぜデータが上に動くのですか?
移動が一つのシフトだからです。行を切り取って下の方に挿入すると、その行が残した穴は同じ操作の一部として 閉じるので、元の行より下のすべての行 — 狙った行も含めて — が一つずつ繰り上がります。べた書きの行番号で はなく、値で見つけた目印を基準に挿入すれば、シフトは問題でなくなります。
VBA で複数の行を一度に移動するには?
連続したブロックなら、範囲全体を切り取って一度で挿入します。ws.Rows("5:9").Cut のあと .Insert。条件
で選んだ散らばった行なら、最後の行から最初の行へ向かってループします(Step -1)。そうすれば、移動のた
びにシフトはあなたの位置の 下 で起こり、これから移動する行には決して影響しません。
行を別のワークシートに移動するには?
行を切り取って、別のシートで挿入します。ThisWorkbook.Worksheets("Data").Rows(5).Cut のあと
ThisWorkbook.Worksheets("Archive").Rows(2).Insert Shift:=xlDown。同じ切り取って挿入する操作で、変わる
のは移動先のシートだけです。両方のシートを修飾しておけば、マクロはどのシートがアクティブかに依存しなく
なります。
行を移動するとき Cut と Copy はどう違いますか?
Cut は移動です — 行が着地すると元を空にするので、手元には一つだけ残ります。Copy は複製です — 元は
そのまま残り、自分で削除しなければならず、それは間違えやすい作業です。行を移動するには Cut を使いま
しょう。詳しい仕組みは VBA 切り取り を参照してください。
検証環境
動作確認: Excel 365 (Windows 11), VBA 7.1 — 最終確認 2026-09-17.
関連ガイド: VBA 切り取り · VBA 列の移動 · VBA 行の挿入 · VBA 行の削除 · VBA コピー&貼り付け
