ヘッダーに合わせて列をソートして値貼り付けするスマートな方法
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つのステップ
- ワークシートの定義
- 転送元データの取得と切り分け
- 転記先のクリアとヘッダー取得
- 列の並び替え順序(マップ)の作成
- SortByによる列ソートと不要列のカット
- 値貼り付け(一括代入)
① ワークシートの定義
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
③ 転記先のクリアとヘッダー取得
wsT.Range("A1").CurrentRegion.Offset(1).ClearContents
Dim keyT As Range: Set keyT = wsT.Range("A1").CurrentRegion.Resize(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した値(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
そこで、配列の列数を「転記先の列数(keyT.Columns.Count)」でリサイズ(制限)することで、右端に追いやった不要な列を一文字もループを回さずに一斉に切り落としています。
- ソート直後の状態(不要な列が右端にある)
SortBy をかけた直後、不要な列はロジックによってすべて右端(最下位の次元の末尾)に集まっています。 - ReDim Preserve で右端を切り落とす
ここで ReDim Preserve を使い、列のサイズを「必要な列数」に縮めます。行数はそのまま、列数(最後の次元)だけをキュッと縮める
ReDim Preserve sortedData(1 To rowCount, 1 To keyT.Columns.Count)
- 実行後の状態(必要な列データだけが残る)
VBAの仕様上、最後の次元(列)であれば中身を壊さずに縮めることができるため、右端の不要な列だけが切り落とされて一瞬で消え去ります。
⑥ 値貼り付け(一括代入)
wsT.Cells(2, 1).Resize(rowCount, keyT.Columns.Count).Value = sortedData
解説
このコードが「スマート」と言える理由(まとめ)
同じテーマ「マクロ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入門
- ホーム
- マクロVBA応用編
- マクロ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.
