【VBA】配列で並び替え処理を自動化!手動での並び替えは時間のムダ!

毎日のエクセル作業で、並び替えをいつも手動でやっていませんか?
「今日も同じ手順で並び替えて、また5分、10分と時間を取られてしまった……」そんな経験、きっと思い当たる方が多いのではないでしょうか。
実は、エクセルの並び替えはVBAと配列を組み合わせることで、ボタン1クリックで完了させることができます。
私はこれまで年間50件以上のマクロ開発を受注してきましたが、「並び替え処理を自動化したい」というご依頼は本当によく届きます。
依頼者の方々に共通しているのが、「毎回同じ手順なのに、なぜか時間がかかる」という悩みです。
この記事では、エクセルVBAと配列を使って並び替え処理を完全自動化する方法を、プログラミング初心者の方でも理解できるよう丁寧に解説していきます。
読み終えたころには、「これ、明日の仕事にすぐ使える!」と感じていただけるはずです。
手動の並び替えが引き起こす3つの問題
エクセルの並び替えを毎回手動で行っていると、仕事の効率に大きな影響が出てきます。
VBAによる自動化を検討するにあたって、まずは手動作業が引き起こす問題を整理しておきましょう。
問題①:毎回同じ手順に時間を取られている
「データ→並び替え→列を指定→昇順 or 降順→OK」という手順を、毎日繰り返している方はかなり多いです。
1回あたり5分の作業でも、毎日繰り返せば月20日で100分、年間で1,200分もの時間が消えていきます。
「たったそれだけ」と思いがちですが、塵も積もれば山となるという言葉があるように、これはかなりのロスです。
私が受注したマクロ開発の案件でも、「並び替えに毎回10分以上かかっていて、その時間が完全に無駄だと感じていた」というご相談を多くいただきました。
問題②:複数条件の並び替えはミスが発生しやすい
「まず部署名で並び替えて、次に日付順に並び替える」といった複数条件の並び替えは、手順を間違えると意図しない順番になってしまいます。
「部署→日付」の順で並べたいのに、操作順序を逆にしてしまい、全部やり直しになった経験がある方も少なくないはずです。
手動操作では「どの列をキーにして、どの順序で並び替えたか」が残らないため、同じ処理を再現するのが難しいという問題もあります。
VBAを使えば、並び替えの条件をコードとして記録しておけるので、毎回同じ結果を確実に再現することが可能です。
問題③:業務独自の並び替えルールに対応できない
エクセル標準の並び替え機能は「昇順」「降順」が基本であり、業務独自の順番には対応していません。
たとえば「未処理→処理中→完了」という状態管理を、この順番通りに並び替えたい場合、標準機能では実現が難しいです。
「東京→大阪→名古屋→福岡」という地域の優先順位を独自に設定したい場合も同様です。
このような業務固有の並び替えルールを実現するには、配列を使ったVBAが最も効果的な手段となります。
VBAで並び替えを自動化する基本|Sortメソッドを理解する
VBAで並び替えを実装する方法は複数ありますが、まずは基本となるSortメソッドから理解しておきましょう。
SortメソッドはRangeオブジェクトに対して使えるメソッドで、指定した列のデータを昇順または降順に並び替えることができます。
基本を押さえた上で、配列を使った応用へとステップアップしていくのが、習得の近道です。
1列をキーにした基本の並び替えVBA
まずは最もシンプルなケースとして、A列のデータを昇順で並び替えるサンプルコードを見ていきましょう。
Sub 基本の並び替え()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1")
' データ範囲を自動取得
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
' A1:C行末 の範囲を並び替え対象に設定
Dim rng As Range
Set rng = ws.Range("A1:C" & lastRow)
' A列(1列目)を昇順で並び替え
With rng.Sort
.SortFields.Clear
.SortFields.Add Key:=ws.Range("A2:A" & lastRow), _
SortOn:=xlSortOnValues, _
Order:=xlAscending
.Header = xlYes ' 1行目はヘッダーとして除外
.Apply
End With
MsgBox "並び替えが完了しました。", vbInformation
End Sub
コードの流れを解説します。
まず lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row でA列の最終行を自動取得しています。
データが増減してもコードを変更する必要がなく、使い回しができる書き方です。
With rng.Sort ブロックの中で、並び替えの条件を設定しています。
SortFields.Clear でいったん並び替え条件をリセットし、SortFields.Add で新しい条件を追加するという流れになります。
Order:=xlAscending が昇順を意味し、降順にしたい場合は xlDescending に変更するだけで対応可能。
Header = xlYes を設定することで、1行目のヘッダー行を並び替えの対象から除外することができます。
複数列をキーにした並び替えVBA
実務では1列だけでなく、「まず部署名で並び替え、同じ部署内では日付順に並べる」という複数条件の並び替えが求められることがよくあります。
Sub 複数条件の並び替え()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1")
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
Dim rng As Range
Set rng = ws.Range("A1:D" & lastRow)
With rng.Sort
.SortFields.Clear
' 第1キー:B列(部署名)を昇順
.SortFields.Add Key:=ws.Range("B2:B" & lastRow), _
SortOn:=xlSortOnValues, _
Order:=xlAscending
' 第2キー:C列(日付)を昇順
.SortFields.Add Key:=ws.Range("C2:C" & lastRow), _
SortOn:=xlSortOnValues, _
Order:=xlAscending
.Header = xlYes
.Apply
End With
MsgBox "複数条件の並び替えが完了しました。", vbInformation
End Sub
コードの流れを解説します。
SortFields.Add を2回呼び出すことで、第1キーと第2キーを設定しています。
先に追加した条件が優先度の高いキーとなるため、記述する順番が重要です。
この例では「B列(部署名)でまず並び替え、同じ部署名の中ではC列(日付)の順に並べる」という処理が実現されます。
標準機能の並び替えダイアログでは「レベルの追加」ボタンで同じことができますが、VBAにすれば毎回ダイアログを操作する手間がなくなります。
関連記事「並び替えに毎回10分ロス!?VBAで一瞬で完了させる4つのソート術」では、今回の記事でも紹介したカスタム並び替えVBAが設定されたエクセルファイルをダウンロードすることができます。
まずはそのファイルを動かして試してみるところから始めてみてください。
配列を使った並び替えVBA|業務独自の順番を実現する
ここからが本記事のメインテーマです。
配列(Array)を使った並び替えVBAを使えば、「昇順・降順では実現できない、業務独自の優先順位」を設定した並び替えが可能になります。
私が実際に依頼を受けて開発した案件でも、この配列を使ったカスタム並び替えのニーズが最も多く、効果も絶大でした。
配列で優先順位を定義するカスタム並び替えVBA
下記のサンプルは「ステータス列」に「未処理」「処理中」「完了」「保留」という値が入っており、この順番で並び替えるコードです。
エクセルの標準機能では「未処理→処理中→完了→保留」という独自順序での並び替えができませんが、配列を使ったVBAで実現します。
Sub カスタム順序で並び替え()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1")
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
' 並び替えの優先順位を配列で定義
Dim sortOrder() As String
sortOrder = Split("未処理,処理中,完了,保留", ",")
' 作業用列(E列)に並び替え用の数値を書き込む
Dim i As Long
Dim j As Integer
Dim matchFound As Boolean
For i = 2 To lastRow
matchFound = False
For j = 0 To UBound(sortOrder)
If ws.Cells(i, 4).Value = sortOrder(j) Then
' 配列のインデックス番号を作業列に書き込む
ws.Cells(i, 5).Value = j
matchFound = True
Exit For
End If
Next j
' リストにない値は末尾に回す
If Not matchFound Then
ws.Cells(i, 5).Value = 999
End If
Next i
' E列の数値を基準に並び替え
Dim rng As Range
Set rng = ws.Range("A1:E" & lastRow)
With rng.Sort
.SortFields.Clear
.SortFields.Add Key:=ws.Range("E2:E" & lastRow), _
SortOn:=xlSortOnValues, _
Order:=xlAscending
.Header = xlYes
.Apply
End With
' 作業用のE列を削除(後始末)
ws.Columns(5).Delete
MsgBox "カスタム順序の並び替えが完了しました。", vbInformation
End Sub
コードの流れを解説します。
まず sortOrder = Split(“未処理,処理中,完了,保留", “,") で並び替えの優先順位を配列として定義しています。
Split 関数はカンマ区切りの文字列を配列に変換する関数で、「未処理」が0番、「処理中」が1番、「完了」が2番、「保留」が3番というインデックスが振られます。
次のForループで、D列のステータス値と配列の各要素を照合し、一致したインデックス番号をE列(作業用列)に書き込んでいきます。
配列に存在しない値が入っていた場合は 999 を書き込み、並び替えの末尾に回すようにしています。
E列に数値が揃ったら、その数値を基準に昇順で並び替えることで、配列で定義した通りの順番に並び替えることができます。
最後に ws.Columns(5).Delete でE列を削除し、作業用列の跡が残らないよう後始末をしています。
この手法のポイントは、「並び替えの優先順位を変えたいときは配列の中身を書き換えるだけ」という点です。
業務のルール変更に対応するのが非常に簡単で、メンテナンスしやすいコードになっています。
複数条件 × 配列の組み合わせVBA
より実務に近いケースとして、「部署の独自順序」と「ステータスの独自順序」を組み合わせた並び替えも紹介します。
Sub 複数カスタム順序で並び替え()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1")
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
' 部署の並び替え優先順位(B列)
Dim deptOrder() As String
deptOrder = Split("営業部,開発部,総務部,経理部", ",")
' ステータスの並び替え優先順位(D列)
Dim statusOrder() As String
statusOrder = Split("未処理,処理中,完了,保留", ",")
Dim i As Long
Dim j As Integer
For i = 2 To lastRow
' B列(部署)の優先順位をE列に書き込む
Dim deptFound As Boolean
deptFound = False
For j = 0 To UBound(deptOrder)
If ws.Cells(i, 2).Value = deptOrder(j) Then
ws.Cells(i, 5).Value = j
deptFound = True
Exit For
End If
Next j
If Not deptFound Then ws.Cells(i, 5).Value = 999
' D列(ステータス)の優先順位をF列に書き込む
Dim statusFound As Boolean
statusFound = False
For j = 0 To UBound(statusOrder)
If ws.Cells(i, 4).Value = statusOrder(j) Then
ws.Cells(i, 6).Value = j
statusFound = True
Exit For
End If
Next j
If Not statusFound Then ws.Cells(i, 6).Value = 999
Next i
' E列(部署順)→ F列(ステータス順)の複数条件で並び替え
Dim rng As Range
Set rng = ws.Range("A1:F" & lastRow)
With rng.Sort
.SortFields.Clear
.SortFields.Add Key:=ws.Range("E2:E" & lastRow), _
SortOn:=xlSortOnValues, _
Order:=xlAscending
.SortFields.Add Key:=ws.Range("F2:F" & lastRow), _
SortOn:=xlSortOnValues, _
Order:=xlAscending
.Header = xlYes
.Apply
End With
' 作業用のE列・F列を削除
ws.Columns(6).Delete
ws.Columns(5).Delete
MsgBox "複数カスタム順序の並び替えが完了しました。", vbInformation
End Sub
コードの流れを解説します。
部署の順序をE列、ステータスの順序をF列という、2本の作業用列を一時的に追加しています。
それぞれの配列と照合して優先度の数値を書き込み、E列→F列の順で並び替えることで「部署の独自順序を守りながら、同じ部署内ではステータスの独自順序で並べる」という処理が実現できます。
列の削除は番号の大きい列(F列)から先に行うのがポイントです。
F列を削除してからE列を削除する順番で実行しないと、削除時に列番号がずれてしまうため注意が必要になります。
並び替えVBAを実務で使いやすくする応用テクニック
基本と配列の使い方を理解できたら、実務でさらに使いやすくするための応用テクニックを押さえておきましょう。
ここで紹介する3つのテクニックは、私がマクロ開発の現場で実際に取り入れているものです。
応用①:並び替え前にデータのバックアップを取るVBA
並び替えは元の順番を変えてしまう操作なので、万が一のために元データのバックアップを取っておく処理を組み込むと安心です。
Sub バックアップ付き並び替え()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1")
' バックアップシートを作成(既存の場合は削除して再作成)
Dim bkSheet As Worksheet
Application.DisplayAlerts = False
On Error Resume Next
ThisWorkbook.Worksheets("バックアップ").Delete
On Error GoTo 0
Application.DisplayAlerts = True
ws.Copy After:=ThisWorkbook.Worksheets(ThisWorkbook.Worksheets.Count)
ActiveSheet.Name = "バックアップ"
' Sheet1をアクティブに戻す
ws.Activate
' 並び替え処理(ここに並び替えコードを追加)
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
Dim rng As Range
Set rng = ws.Range("A1:D" & lastRow)
With rng.Sort
.SortFields.Clear
.SortFields.Add Key:=ws.Range("A2:A" & lastRow), _
SortOn:=xlSortOnValues, _
Order:=xlAscending
.Header = xlYes
.Apply
End With
MsgBox "バックアップを作成し、並び替えが完了しました。", vbInformation
End Sub
コードの流れを解説します。
ws.Copy After:=… でSheet1を丸ごとコピーし、「バックアップ」という名前のシートを自動生成します。
毎回実行するたびに古いバックアップを削除して新しく作り直す仕組みにしているため、シートが際限なく増えていくことがありません。
万が一並び替えを誤って実行してしまった場合も、バックアップシートを見れば元の状態に戻すことができます。
応用②:複数シートを一括で並び替えるVBA
月次レポートなど、複数のシートを同じ条件で並び替えたいケースに対応したコードです。
Sub 全シート一括並び替え()
Dim ws As Worksheet
Dim lastRow As Long
For Each ws In ThisWorkbook.Worksheets
' バックアップシートはスキップ
If ws.Name <> "バックアップ" Then
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
If lastRow >= 2 Then ' データが2行以上ある場合のみ実行
Dim rng As Range
Set rng = ws.Range("A1:D" & lastRow)
With rng.Sort
.SortFields.Clear
.SortFields.Add Key:=ws.Range("A2:A" & lastRow), _
SortOn:=xlSortOnValues, _
Order:=xlAscending
.Header = xlYes
.Apply
End With
End If
End If
Next ws
MsgBox "全シートの並び替えが完了しました。", vbInformation
End Sub
コードの流れを解説します。
For Each ws In ThisWorkbook.Worksheets でブック内のすべてのシートを順番に処理します。
If ws.Name <> “バックアップ" という条件を入れることで、バックアップシートだけを処理対象から除外しています。
If lastRow >= 2 の条件で、データが1行(ヘッダーのみ)のシートは並び替えをスキップするようにしています。
この処理がないと、データのないシートで並び替えを実行しようとしてエラーが発生することがあります。
応用③:並び替えの条件をセルから読み込むVBA
毎回コードを変更せずに、エクセルのセルに入力した値を並び替え条件として読み込む方法です。
Sub セル指定の並び替え()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1")
' G1セルに並び替えのキー列番号、H1セルに昇順/降順を入力しておく
' 例:G1=2(B列)、H1=昇順 or 降順
Dim keyCol As Long
keyCol = ws.Range("G1").Value ' 並び替えのキーにする列番号
Dim orderStr As String
orderStr = ws.Range("H1").Value ' "昇順" または "降順"
Dim sortOrder As XlSortOrder
If orderStr = "昇順" Then
sortOrder = xlAscending
Else
sortOrder = xlDescending
End If
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
Dim lastCol As Long
lastCol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column
Dim rng As Range
Set rng = ws.Range(ws.Cells(1, 1), ws.Cells(lastRow, lastCol))
With rng.Sort
.SortFields.Clear
.SortFields.Add Key:=ws.Range(ws.Cells(2, keyCol), ws.Cells(lastRow, keyCol)), _
SortOn:=xlSortOnValues, _
Order:=sortOrder
.Header = xlYes
.Apply
End With
MsgBox keyCol & "列目を" & orderStr & "で並び替えました。", vbInformation
End Sub
コードの流れを解説します。
G1セルに列番号(例:2なら2列目=B列)、H1セルに「昇順」か「降順」を入力しておくことで、マクロを実行するたびにその設定が読み込まれます。
セルの値を変えるだけで並び替えの条件を切り替えられるため、コードを触ることなく柔軟に運用することが可能。
これを発展させると、条件入力専用の「設定シート」を作成し、より複雑な運用にも対応できるようになります。
並び替えVBAを使う際の注意点
並び替えVBAは非常に便利ですが、事前に把握しておきたい注意点がいくつかあります。
私が実際のマクロ開発で経験した注意点を3つ紹介するので、ぜひ参考にしてください。
注意点①:並び替え前にSortFields.Clearを必ず入れる
並び替えを実行する前に SortFields.Clear を呼び出して、前回の並び替え条件をリセットすることが重要です。
リセットしないままSortFields.Addで条件を追加すると、前回の条件が残ったまま新しい条件が上乗せされ、意図しない複数条件での並び替えになることがあります。
「なぜか思った通りの順番にならない」という場合は、この原因であることが多いです。
必ず処理の先頭にClearを入れる習慣をつけておきましょう。
注意点②:Header設定を間違えるとデータが壊れる
.Header = xlYes はヘッダー行(1行目)を並び替えの対象から除外する設定です。
これを xlNo にすると、ヘッダー行もデータとして並び替えられてしまいます。
「項目名の行が途中に混ざって消えてしまった」という事故は、このHeader設定のミスが原因であることがほとんどです。
ヘッダーがある表であれば、常に xlYes を設定するようにしましょう。
注意点③:配列のインデックスは0から始まる
VBAの配列は、特別な設定をしない限りインデックスが「0」から始まります。
Split 関数で作成した配列の最初の要素は sortOrder(0) であり、sortOrder(1) ではありません。
ループの中で For j = 0 To UBound(sortOrder) と書くのは、0から始まる配列の全要素を正しく処理するためです。
配列の扱いに慣れていない方は、特にこのインデックスの開始番号に注意しておく必要があります。
まとめ ~ 並び替えはVBAと配列の組み合わせで完全自動化できる ~
エクセルの並び替えを毎回手作業で行っていると、時間のロスとミスの積み重ねが業務効率を下げていきます。
VBAのSortメソッドを使えば、毎回の手動操作をボタン1クリックで完結させることができます。
さらに配列を組み合わせることで、「昇順・降順では実現できない業務独自の並び替え順序」まで自動化できるようになります。
この記事で紹介したコードをまとめると、「基本の並び替え」「複数条件の並び替え」「配列を使ったカスタム並び替え」「バックアップ付き並び替え」「全シート一括並び替え」という5つの
VBAが、並び替え処理の自動化に直結する実務的なコードです。
これらを自分の業務フローに合わせてカスタマイズしていくことで、毎日の並び替え作業がみるみる効率化されていきます。
もし「自分の業務に合わせた複雑なチェック処理を実装したい」「既存のマクロを改良したい」といったご要望がありましたら、マメBlogのエクセルマクロ開発依頼にご相談ください。
業務内容に合わせたオーダーメイドマクロを設定させていただきます。
最後まで読んでいただきありがとうございました。
エクセルVBAを使って面倒なルーティーン作業を自動化しちゃいましょう。






