🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

Excel VBA で行を移動する — 上書きせずに切り取って挿入する(貼り付けではない)

|

Excel VBA で行を移動する — 上書きせずに切り取って挿入する(貼り付けではない)

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:=xlDownInsert は移動先にすき間を空けて他の行を下へずらすので、何も上書き されません。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 コピー&貼り付け