【VBA】データを複数条件で自動並び替えする方法(コピペOK)

VBA
スポンサーリンク
スポンサーリンク

この記事でできること

  • VBAで単一条件(1列)のデータ並び替えを自動化できる
  • 複数条件(部門→日付→金額など3つ)での並び替えをボタン1つで実行できる
  • セルの背景色で並び替える方法も分かる
  • 確認ダイアログ付きで安全にソートを実行できる

対象: Excel 2016以降 / Microsoft 365、Windows 10/11


完成イメージ(Before / After)

Before(手動ソート):

  1. データ範囲を選択
  2. 「データ」タブ →「並べ替え」をクリック
  3. 条件1(部門・昇順)を設定
  4. 「レベルの追加」→ 条件2(日付・降順)を設定
  5. 「レベルの追加」→ 条件3(金額・降順)を設定
  6. 「OK」で実行
  7. 毎回この5ステップを繰り返す

After(自動ソート):

  1. ボタンを押す(またはマクロを実行)
  2. 確認ダイアログが表示される → 「はい」をクリック
  3. 3つの条件で自動的に並び替え完了(3秒)

売上データを部門→金額の順で並び替えるのを毎日やっていた。ソートの条件を毎回手で設定するのが地味にストレスだった。VBAで自動化してからはボタン1つで3秒。毎日の並び替え作業から解放されたい人に、この記事で同じ快適さを手に入れてほしい。

データの並び替えは、VBAに任せれば毎回の手動設定が不要になる。


実行前の準備

バックアップを取る

ソートはデータの行順を変更する操作。元に戻せない場合があるため、マクロ実行前にExcelファイルのコピーを別フォルダに保存しておく。

Excelをマクロ有効ブック(.xlsm)で保存する

拡張子が .xlsx のままだとマクロが保存できない。

  1. 「ファイル」→「名前を付けて保存」
  2. ファイルの種類を「Excelマクロ有効ブック (*.xlsm)」に変更
  3. 保存

手順(コピペ → 実行まで約5分)

VBE(コードを書く画面)を開く

  1. Excelで Alt + F11 を押す
  2. VBE(Visual Basic Editor)が開く

標準モジュールを挿入する

  1. VBEのメニュー →「挿入」→「標準モジュール」
  2. 白い画面(コードウィンドウ)が表示される

コードを貼り付けて実行する

  1. コードウィンドウに、下のコードをそのままコピペする
  2. Alt + F8 → マクロ名を選んで「実行」

ボタンに割り当てれば毎回Alt+F8を押さなくて済む。方法は マクロをボタン1つで実行する方法 を参照。


コード(最小版)– 単一条件で並び替え

まずは1つの列だけで並び替える最小コード。最終行の取得には Cells(Rows.Count, 1).End(xlUp).Row を使う。詳しくは 最終行を正確に取得する方法 を参照。


'============================================================
' ■ 単一条件でデータを並び替え(最小版)
'   → A列を昇順で並び替え
'============================================================
Sub データを並び替える()
    Dim ws As Worksheet
    Dim lastRow As Long

    Set ws = ActiveSheet
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row

    ' ソート条件をクリア(前回の条件が残るのを防止)
    ws.Sort.SortFields.Clear

    ' A列を昇順で並び替え
    ws.Sort.SortFields.Add2 _
        Key:=ws.Range("A2:A" & lastRow), _
        Order:=xlAscending

    With ws.Sort
        .SetRange ws.Range("A1:D" & lastRow)
        .Header = xlYes
        .Apply
    End With

    MsgBox "並び替えが完了しました。"
End Sub

書き換えポイント

変数・箇所 説明 初期値
Range("A2:A" & lastRow) ソート基準の列。B列にしたければ "B2:B" に変更 A列
xlAscending ソート順。降順なら xlDescending に変更 昇順
Range("A1:D" & lastRow) ソート対象の範囲。列数に応じて "A1:F" などに変更 A〜D列

コードの流れ

  1. ActiveSheet で現在のシートを取得
  2. Cells(Rows.Count, 1).End(xlUp).Row でA列の最終行を取得
  3. SortFields.Clear で前回のソート条件をクリア(重要)
  4. SortFields.Add2 でソート条件を追加(A列・昇順)
  5. .SetRange でソート対象範囲を指定し、.Header = xlYes でヘッダーを除外
  6. .Apply でソートを実行

コード(実務版)– 複数条件(3つ)で並び替え + 確認ダイアログ

実務では「部門→日付→金額」のように複数条件で並び替えることが多い。この実務版では、確認ダイアログで件数と条件を表示してから実行する。

自分はこのコードを毎日の売上レポートに使っている。部門別→日付の新しい順→金額の大きい順で並ぶので、報告書がそのまま完成する。ScreenUpdating = False で画面のちらつきも抑えている。画面ちらつき防止の詳細は 処理の高速化テクニック を参照。

確認ダイアログには MsgBoxの使い方 で紹介しているYes/Noダイアログを使っている。

マクロ実行中にエラーが発生すると、ScreenUpdating = False のまま画面更新が停止した状態になることがある。その場合はVBEの「イミディエイトウィンドウ」で Application.ScreenUpdating = True を実行すれば復帰する。


'============================================================
' ■ 複数条件(3つ)でデータを並び替え(実務版)
'   → 条件1: A列(部門)昇順
'   → 条件2: B列(日付)降順
'   → 条件3: C列(金額)降順
'   → 実行前に確認ダイアログを表示
'============================================================
Sub 複数条件で並び替える()
    Dim ws As Worksheet
    Dim lastRow As Long

    Set ws = ActiveSheet
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row

    '--- データがない場合は終了
    If lastRow < 2 Then
        MsgBox "データがありません。", vbExclamation
        Exit Sub
    End If

    '--- 確認ダイアログ(件数と条件を表示)
    If MsgBox((lastRow - 1) & " 件のデータを並び替えます。" & vbCrLf & _
              "条件: 部門(昇順) → 日付(降順) → 金額(降順)" & vbCrLf & vbCrLf & _
              "実行しますか?", vbYesNo + vbQuestion) = vbNo Then
        Exit Sub
    End If

    '--- 画面更新を停止(高速化)
    Application.ScreenUpdating = False

    '--- ソート条件をクリア(★これを忘れると前回の条件が残る)
    ws.Sort.SortFields.Clear

    '--- 条件1:A列(部門)を昇順
    ws.Sort.SortFields.Add2 _
        Key:=ws.Range("A2:A" & lastRow), _
        Order:=xlAscending

    '--- 条件2:B列(日付)を降順
    ws.Sort.SortFields.Add2 _
        Key:=ws.Range("B2:B" & lastRow), _
        Order:=xlDescending

    '--- 条件3:C列(金額)を降順
    ws.Sort.SortFields.Add2 _
        Key:=ws.Range("C2:C" & lastRow), _
        Order:=xlDescending

    '--- ソート実行
    With ws.Sort
        .SetRange ws.Range("A1:D" & lastRow)
        .Header = xlYes
        .MatchCase = False
        .Apply
    End With

    '--- 画面更新を再開
    Application.ScreenUpdating = True

    MsgBox "並び替えが完了しました。"
End Sub

書き換えポイント

変数・箇所 説明 初期値
Range("A2:A" & lastRow) 条件1の対象列 A列(部門)
Range("B2:B" & lastRow) 条件2の対象列 B列(日付)
Range("C2:C" & lastRow) 条件3の対象列 C列(金額)
xlAscending / xlDescending 各条件のソート順 部門:昇順、日付:降順、金額:降順
Range("A1:D" & lastRow) ソート対象の全範囲。列が多ければ "A1:H" などに変更 A〜D列

コードの流れ

  1. データ存在チェック: 最終行が2未満ならデータなしで終了
  2. 確認ダイアログ: 件数とソート条件を表示し、「いいえ」なら中止
  3. 画面更新を停止: ScreenUpdating = False でちらつきを防止
  4. SortFields.Clear: 前回のソート条件をクリア(これを忘れると大事故)
  5. 条件を追加: Add2 を3回呼び出し、優先度順に条件を設定
  6. ソート実行: .SetRange で範囲指定、.Header = xlYes でヘッダー除外、.Apply で実行
  7. 画面更新を再開: ScreenUpdating = True

SortFields.Add2 は呼び出した順が優先度になる。最初に追加した条件が第1ソートキー。


応用:色(セルの背景色)で並び替え

セルの背景色で並び替えたい場面もある。たとえば「赤色のセルを先頭に持ってくる」という使い方。

セルに設定した色のRGB値を確認するには、セルを右クリック →「セルの書式設定」→「塗りつぶし」→「その他の色」→「ユーザー設定」タブで赤・緑・青の値を確認する。コード内の RGB() にはこの値を指定する。値が一致しないとソートされないため注意。


'============================================================
' ■ セルの背景色で並び替え(応用)
'   → 赤色(RGB 255,0,0)のセルを先頭に並べる
'============================================================
Sub 色で並び替える()
    Dim ws As Worksheet
    Dim lastRow As Long

    Set ws = ActiveSheet
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row

    ws.Sort.SortFields.Clear
    ws.Sort.SortFields.Add2 _
        Key:=ws.Range("A2:A" & lastRow), _
        SortOn:=xlSortOnCellColor, _
        Order:=xlAscending, _
        DataOption:=xlSortNormal
    ws.Sort.SortFields(ws.Sort.SortFields.Count).SortOnValue.Color = RGB(255, 0, 0)

    With ws.Sort
        .SetRange ws.Range("A1:D" & lastRow)
        .Header = xlYes
        .Apply
    End With

    MsgBox "色で並び替えました。"
End Sub

書き換えポイント

変数・箇所 説明 初期値
SortOn:=xlSortOnCellColor ソート基準を「セルの背景色」に設定 色ソート
RGB(255, 0, 0) 対象色。黄色なら RGB(255, 255, 0)、青なら RGB(0, 0, 255)

色ソートは「指定した色のセルを先頭に集める」動作。複数色で段階的に並べたい場合は、SortFields.Add2 を色ごとに複数回呼び出す。


よくある落とし穴5選

1. SortFields.Clear を忘れて前回の条件が残る

原因: SortFields.Clear を書かないと、前回実行時のソート条件が残ったまま新しい条件が追加される。意図しない並び順になる。

自分もこれでやらかした。SortFields.Clear を書き忘れて、前回の日付ソート条件が残ったまま実行。部門順で並べたつもりが日付順になっていて、提出した報告書が「並び順おかしくない?」と上司に指摘された。それ以来、Clearは必ず最初に書くようにしている。

対策: ソート条件を追加する前に、必ず ws.Sort.SortFields.Clear を実行する。

2. .Header = xlYes を忘れてヘッダーもソート対象になる

原因: .Header = xlYes を指定しないと、1行目のヘッダー(「部門」「日付」「金額」など)もデータとしてソートされる。ヘッダーが行の途中に混ざる。

対策: .Header = xlYes を必ず指定する。ヘッダーがない場合は .Header = xlNo を指定。

3. 結合セルがあるとソートエラーになる

原因: ソート範囲に結合セルが含まれていると、実行時にエラー(「この操作を行うには、すべての結合セルを同じサイズにする必要があります」)が出る。

対策: ソート前に結合を解除する。シート全体の結合を解除するなら ws.Cells.UnMerge を実行する。結合セルとソートは相性が悪いため、データ範囲では結合を使わないのが基本。

4. 日付が文字列として保存されていると並び順がおかしい

原因: セルに入力された日付が「日付型」ではなく「文字列」として保存されている場合、ソートすると「10月」が「1月」の後ではなく「2月」の前に来る(文字列の辞書順で比較されるため)。

見分け方: セルを選択して右クリック →「セルの書式設定」→「表示形式」タブで分類が「文字列」になっていたら、日付型への変換が必要。

対策: 日付列を選択 →「データ」→「区切り位置」→ 列のデータ形式で「日付」を選択。これでセルの値が日付型に変換される。VBAで変換するなら CDate(セル.Value) を使う。

5. ソート範囲に空白列があると範囲がズレる

原因: データの途中に空白列があると、Excelが自動認識する範囲が空白列の手前で切れてしまう。結果、一部の列だけがソートされてデータの対応がずれる。

対策: .SetRange でソート範囲を明示的に指定する。このコードでは ws.Range("A1:D" & lastRow) と範囲を明示しているため、空白列があっても問題ない。自動認識に頼らず、必ず SetRange を使う。


FAQ

Q1: 降順で並び替えたい場合は?

Order:=xlAscendingOrder:=xlDescending に変更する。


ws.Sort.SortFields.Add2 _
    Key:=ws.Range("A2:A" & lastRow), _
    Order:=xlDescending   ' ← 降順

Q2: ソート対象の列を変えたい(B列やC列で並び替えたい)

KeyRange を変更する。B列なら "B2:B" & lastRow、C列なら "C2:C" & lastRow


ws.Sort.SortFields.Add2 _
    Key:=ws.Range("B2:B" & lastRow), _   ' ← B列に変更
    Order:=xlAscending

Q3: ソート後に元の順番に戻したい

ソートは行の並び順を直接変更するため、元に戻す機能(Undo)は使えない。事前に連番のID列を追加しておき、戻すときはID列でソートする。


' 事前にE列に連番を振っておく
Dim i As Long
For i = 2 To lastRow
    ws.Cells(i, 5).Value = i - 1   ' E列に連番
Next i

Q4: ボタンに割り当てて実行したい

手順セクションで紹介した「マクロをボタン1つで実行する方法」の手順でシート上にボタンを設置し、このマクロを割り当てる。自分はこの方法で並び替えマクロをボタンに割り当てて、チームメンバーにも使ってもらっている。

Q5: ソート後に重複データを削除したい

並び替え後の重複削除は 重複データを一括削除して一意のリストを作る を参照。ソートで同じ値を隣接させてから重複削除すると、結果の確認がしやすい。


まとめ

  • SortFields.ClearSortFields.Add2.Apply がVBAソートの基本の流れ
  • 複数条件は Add2 を複数回呼び出すだけ。呼び出し順が優先度になる
  • .Header = xlYes を忘れるとヘッダーもソート対象になる
  • SortFields.Clear を忘れると前回の条件が残る。これが最大の落とし穴

関連記事


次にやりたくなること


もっとカスタマイズしたい場合

「部門ごとに小計行を自動挿入したい」「ソート→抽出→PDF出力を一連で自動化したい」「複数シートを一括でソートしたい」など、業務に合わせたカスタマイズが必要な場合は、ココナラで相談できる。

相談時に伝えると話が早い情報:

  • Excel のバージョン / OS
  • ソート対象のデータ構成(列名、行数)
  • ソート条件(何列目を昇順/降順にしたいか)
  • ソート後にやりたい処理(抽出、PDF出力など)

コメント

タイトルとURLをコピーしました