VBAサンプル集
ヘッダーに合わせて列をソートして値貼り付けするスマートな方法

ExcelマクロVBAの実用サンプル、エクセルVBA集と解説
公開日:2026-05-20 最終更新日:2026-05-20

ヘッダーに合わせて列をソートして値貼り付けするスマートな方法


Excel VBAでヘッダー(項目名)に合わせて列の順序を自動で並べ替え、値貼り付けするスマートな実装方法を解説します。
ループ処理で1列ずつコピペするのではなく、配列とSortBy関数を組み合わせた、高速で可読性の高い「きれいなコード」をご紹介します。



ヘッダーに合わせて列をソートして値貼り付けするVBAコード

Option Explicit

'================================================================================
' プロシージャー名: SortColumnsAndPasteValues
' 概要: 転送元と転送先のヘッダー(1行目)を比較し、列の並び順を一致させて値貼付する
' 前提条件:
'  - ブック「A.xlsm」のシート「A」(転送元)が開いていること
'  - ブック「B.xlsm」のシート「B」(転送先)が開いていること
'  - 双方のシートの1行目には、比較対象となるヘッダー(項目名)が存在すること
' 処理特徴:
'  - WorksheetFunction.SortBy を使用して、列単位の並べ替えを高速に実行
'  - 転送先に存在しない列のデータは除外して出力
'================================================================================
Sub SortColumnsAndPasteValues()
  ' --- 1. ワークシートの定義とセット >---
  Dim wsF As Worksheet: Set wsF = Workbooks("A.xlsm").Sheets("A") ' 転送元シート
  Dim wsT As Worksheet: Set wsT = Workbooks("B.xlsm").Sheets("B") ' 転送先シート
  
  ' --- 2. 転送元(From)のデータ範囲の取得 ---
  ' 転送元の1行目(ヘッダー行)を範囲として取得
  Dim keyF As Range: Set keyF = wsF.Range("A1").CurrentRegion.Resize(1)
  ' 転送元のデータ全体(ヘッダー含む)を取得
  Dim dataF As Range: Set dataF = wsF.Range("A1").CurrentRegion
  ' データ全体からヘッダー行を除外し、純粋なデータ行のみ(2行目以降)を抽出
  Set dataF = Intersect(dataF, dataF.Offset(1))
  
  ' --- 3. 転送先(To)の準備とヘッダー範囲の取得 ---
  ' 転送先シートの2行目以降(既存データ)をクリア
  wsT.Range("A1").CurrentRegion.Offset(1).ClearContents
  ' 転送先の1行目(ヘッダー行)を基準となる並び順として取得
  Dim keyT As Range: Set keyT = wsT.Range("A1").CurrentRegion.Resize(1)
  
  ' --- 4. 列の並び替え順序(マッピング構造)の作成 ---
  ' 転送元の列数と同じ大きさの、1行×N列の配列を準備(ソート順の数値を格納する)
  Dim sortOrder() As Long: ReDim sortOrder(1 To 1, 1 To dataF.Columns.Count)
  Dim i As Long, matchRes As Variant
  
  ' 転送元の各列をループ処理し、転送先のどこに配置すべきかを判定
  For i = 1 To keyF.Count
    If keyF.Item(i) <> "" Then ' ヘッダーが空文字でない場合のみ処理
      ' 転送元のヘッダー文字列が、転送先のヘッダーの何番目にあるか検索
      matchRes = Application.Match(keyF.Item(i), keyT, 0)
      
      ' 検索結果の格納:見つからなければ「転送先の最大列数+1」(後方除外用)、見つかればその列番号
      sortOrder(1, i) = IIf(IsError(matchRes), keyT.Count + 1, CLng(matchRes))
    End If
  Next
  
  ' --- 5. データの並び替えとサイズ調整 ---
  ' Excel関数の SORTBY を呼び出し、作成したソート順配列(sortOrder)に基づいて列を並び替えて配列に格納
  Dim sortedData As Variant: sortedData = WorksheetFunction.SortBy(dataF, sortOrder, 1)
  ' 並び替えた結果のデータ行数を取得
  Dim rowCount As Long: rowCount = UBound(sortedData, 1)
  ' 配列の列数を「転送先の列数」に合わせて再定義(転送先にない不要な列データをここでカットする)
  ReDim Preserve sortedData(1 To rowCount, 1 To keyT.Columns.Count)
  
  ' --- 6. 転送先シートへの値の書き込み(値貼り付け) ---
  ' 転送先シートの2行目から、データの行数・列数に合わせた範囲へ配列を一括代入
  wsT.Cells(2, 1).Resize(rowCount, keyT.Columns.Count).Value = sortedData
End Sub


ヘッダーに合わせて列をソートして値貼り付けするVBAの解説

全体像:処理の6つのステップ

このマクロは、大きく分けて以下の6つのステップで動いています。
  1. ワークシートの定義
  2. 転送元データの取得と切り分け
  3. 転記先のクリアとヘッダー取得
  4. 列の並び替え順序(マップ)の作成
  5. SortByによる列ソートと不要列のカット
  6. 値貼り付け(一括代入)

① ワークシートの定義

Dim wsF As Worksheet: Set wsF = Workbooks("A.xlsm").Sheets("A")
Dim wsT As Worksheet: Set wsT = Workbooks("B.xlsm").Sheets("B")

転送元(wsF)と転送先(wsT)のシートを変数にセットします。
このように変数名に対比(FとT)を持たせることで、以降のコードの可読性が格段に向上します。

② 転送元データの取得と切り分け

Dim keyF As Range: Set keyF = wsF.Range("A1").CurrentRegion.Resize(1)
Dim dataF As Range: Set dataF = wsF.Range("A1").CurrentRegion
Set dataF = Intersect(dataF, dataF.Offset(1))

keyF
CurrentRegion(表全体)の行数を .Resize(1) で1行に縮小し、「1行目のヘッダー(項目名)だけ」を抽出しています。
dataF
表全体を下に1行ずらした(Offset(1))範囲と、元の表全体の重なる部分(Intersect)を取ることで、「1行目のヘッダーを除いた、純粋なデータ行(2行目以降)だけ」を綺麗に抜き出します。

③ 転記先のクリアとヘッダー取得

wsT.Range("A1").CurrentRegion.Offset(1).ClearContents
Dim keyT As Range: Set keyT = wsT.Range("A1").CurrentRegion.Resize(1)

既存データのクリア
転記先シートの2行目以降(Offset(1))のデータを、事前に ClearContents で綺麗に消去します(値貼り付けなので、古いデータが残るのを防ぐため)。

keyT
転記先シートの基準となる「理想の並び順(1行目のヘッダー)」を取得します。

④ 列の並び替え順序(マップ)の作成

ここがこのロジックの心臓部へ向かう準備段階です。

Dim sortOrder() As Long: ReDim sortOrder(1 To 1, 1 To dataF.Columns.Count)
Dim i As Long, matchRes As Variant

For i = 1 To keyF.Count
  If keyF.Item(i) <> "" Then
    matchRes = Application.Match(keyF.Item(i), keyT, 0)
    sortOrder(1, i) = IIf(IsError(matchRes), keyT.Count + 1, CLng(matchRes))
  End If
Next

sortOrder() の準備
転送元の列数と同じだけの、1行×N列の「ソート順格納用」の2次元配列を作ります。

Application.Match
転送元のヘッダー文字列が、転送先のヘッダーの「左から何番目にあるか」を検索します。

IIf(IsError...) の活用技巧
転記先に同じヘッダーが見つかった場合(例: 3番目)は、配列に 3 を入れます。
もし見つからなかった場合(不要な列の場合)、転記先の最大列数にプラス1した値(keyT.Count + 1)をあえて仕込みます。
これにより、不要な列を強制的に「一番右端」へ追いやるソート順が完成します。

⑤ SortByによる列ソートと不要列のカット

Dim sortedData As Variant: sortedData = WorksheetFunction.SortBy(dataF, sortOrder, 1)
Dim rowCount As Long: rowCount = UBound(sortedData, 1)
ReDim Preserve sortedData(1 To rowCount, 1 To keyT.Columns.Count)

WorksheetFunction.SortBy
Excel 365等で追加された強力なワークシート関数をVBA内で呼び出しています。通常、行のソートに使われますが、このように2次元配列(1行×N列)を基準に指定することで、「列単位の並び替え」をメモリ上で一瞬で実行します。

ReDim Preserve
ソートした結果、転記先に存在しなかった不要な列は、先ほどのロジックによってすべて右端に集まっています。
そこで、配列の列数を「転記先の列数(keyT.Columns.Count)」でリサイズ(制限)することで、右端に追いやった不要な列を一文字もループを回さずに一斉に切り落としています。

VBAの2次元配列 (行, 列) は、列(最後の次元)なら、データを残したままサイズを縮められます。
  1. ソート直後の状態(不要な列が右端にある)
    SortBy をかけた直後、不要な列はロジックによってすべて右端(最下位の次元の末尾)に集まっています。

  2. ReDim Preserve で右端を切り落とす
    ここで ReDim Preserve を使い、列のサイズを「必要な列数」に縮めます。

    行数はそのまま、列数(最後の次元)だけをキュッと縮める
    ReDim Preserve sortedData(1 To rowCount, 1 To keyT.Columns.Count)

  3. 実行後の状態(必要な列データだけが残る)
    VBAの仕様上、最後の次元(列)であれば中身を壊さずに縮めることができるため、右端の不要な列だけが切り落とされて一瞬で消え去ります。

⑥ 値貼り付け(一括代入)

wsT.Cells(2, 1).Resize(rowCount, keyT.Columns.Count).Value = sortedData

解説
メモリ上で完璧に並び替え・トリミングが完了した配列(sortedData)を、転記先シートの2行目以降のセル範囲に .Value = で一発代入します。

セルへのアクセスがこの最後の1回だけであるため、画面のちらつきもなく、数万行データがあっても爆速で処理が終わります。

このコードが「スマート」と言える理由(まとめ)

セルへの書き込み回数が最小限(1回だけ)
従来の「1列見つけてはコピペ」を繰り返す方法に比べ、画面更新やセルアクセスの負荷が一切ないため非常に高速です。

SortBy を列方向に使う発想
Excelの標準関数を上手くVBAの配列操作に組み込むことで、複雑な並び替えアルゴリズムを自作することなく、わずか1行でソートを完了させています。

ReorderAndPasteValues(値貼り付け)の体現
書式(色や罫線)を一切巻き込まず、純粋なデータ(Value)だけを高速に同期させる、実務においても堅牢でトラブルの少ない設計になっています。




同じテーマ「マクロVBAサンプル集」の記事

増殖した条件付き書式を整理統合する
条件付き書式で変更された書式を取得する
セル結合/解除でセル値を退避/回復
セル結合なんて絶対に許さないんだからね
セルの数式をネスト色分けしてコメント表示
セル結合して表を見やすくする(非推奨)
シートを削除:不定数のシート名に対応
セル番地でバラバラに指定されたセルの削除
シート内に散在する複数表の縦結合
スピル範囲の自動色付け(強調表示)
ヘッダーに合わせて列をソートして値貼り付けするスマートな方法


新着記事NEW ・・・新着記事一覧を見る

2つのシート名を交換するVBAをGeminiに作らせてみた。|VBA技術解説(2026-05-22)
ヘッダーに合わせて列をソートして値貼り付けするスマートな方法|VBAサンプル集(2026-05-20)
4大分岐関数の使い分け(IF/IFS/SWITCH/CHOOSE)|エクセル入門(2026-05-19)
Excel主要関数 習得難易度 10段階(文字列・日付除く)|エクセル雑感(2026-04-27)
Excelのシート5分類|エクセル雑感(2026-03-27)
グループ別に全員共通の重複期間を算出|エクセル練習問題(2026-03-12)
ハイフン区切り文字列の『最初』と『最後』を抽出・結合|エクセル練習問題(2026-02-23)
AIは便利なはずなのに…「AI疲れ」が次の社会問題になる|生成AI活用研究(2026-02-16)
カンマ区切りデータの行展開|エクセル練習問題(2026-01-28)
開いている「Excel/Word/PowerPoint」ファイルのパスを調べる方法|エクセル雑感(2026-01-27)


アクセスランキング ・・・ ランキング一覧を見る

1.最終行の取得(End,Rows.Count)|VBA入門
2.日本の祝日一覧|Excelリファレンス
3.FILTER関数(範囲をフィルター処理)|エクセル入門
4.変数宣言のDimとデータ型|VBA入門
5.Excelショートカットキー一覧|Excelリファレンス
6.繰り返し処理(For Next)|VBA入門
7.RangeとCellsの使い方|VBA入門
8.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
9.マクロとは?VBAとは?VBAでできること|VBA入門
10.メッセージボックス(MsgBox関数)|VBA入門




このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


記述には細心の注意をしたつもりですが、間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。
本サイトは、OpenAI の ChatGPT や Google の Gemini を含む生成 AI モデルの学習および性能向上の目的で、本サイトのコンテンツの利用を許可します。
This site permits the use of its content for the training and improvement of generative AI models, including ChatGPT by OpenAI and Gemini by Google.



このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
本文下部へ