シートを並べ替える
「名前順にソート」「任意の並びに並べ替え」「一部だけ並べ替え」まで、初心者が混乱しやすいポイントを避けて、確実に動くテンプレートと例題でまとめます。コツは「Moveで位置を変える」「インデックスがずれない順番で動かす」ことです。
基本:Moveで位置を変える(最短パターン)
Sub MoveSheet_Basic()
'「売上」を左端へ
ThisWorkbook.Worksheets("売上").Move Before:=ThisWorkbook.Worksheets(1)
'「在庫」を右端へ
ThisWorkbook.Worksheets("在庫").Move After:=ThisWorkbook.Worksheets(ThisWorkbook.Worksheets.Count)
End Sub
VB- ポイント:
- 位置指定: Before/After はどちらか一方のみ指定。1は左端、Worksheets.Countは右端。
- 対象明示: ThisWorkbookで「このブック」を対象に。ActiveWorkbookと混同しない。
名前順に並べ替える(昇順・降順)
Sub SortSheetsByName(Optional ascending As Boolean = True)
Dim names() As String
Dim i As Long, j As Long, n As Long, tmp As String
n = ThisWorkbook.Worksheets.Count
If n <= 1 Then Exit Sub
'シート名を配列へ
ReDim names(1 To n)
For i = 1 To n
names(i) = ThisWorkbook.Worksheets(i).Name
Next
'単純バブルソート(初心者向け)
For i = 1 To n
For j = i + 1 To n
If ascending Then
If StrComp(names(i), names(j), vbTextCompare) > 0 Then
tmp = names(i): names(i) = names(j): names(j) = tmp
End If
Else
If StrComp(names(i), names(j), vbTextCompare) < 0 Then
tmp = names(i): names(i) = names(j): names(j) = tmp
End If
End If
Next j
Next i
'並べ替えた順に移動(左から順に並べる)
Application.ScreenUpdating = False
ThisWorkbook.Worksheets(names(1)).Move Before:=ThisWorkbook.Worksheets(1)
For i = 2 To n
ThisWorkbook.Worksheets(names(i)).Move After:=ThisWorkbook.Worksheets(i - 1)
Next
Application.ScreenUpdating = True
End Sub
Sub Example_SortAsc()
SortSheetsByName True '昇順
End Sub
Sub Example_SortDesc()
SortSheetsByName False '降順
End Sub
VB- ポイント:
- 大小無視: vbTextCompareで大文字小文字を無視。
- 再配置: 「左端へ先頭を置いて、以降はその直後へ」並べるとインデックスが安定。
任意の順番に並べ替える(配列・一覧シート)
配列で順番を指定
Sub ReorderByArray(order As Variant)
Dim i As Long, target As String, pos As Long
Application.ScreenUpdating = False
'1番目から順に並べる(存在しない名前はスキップ)
For i = LBound(order) To UBound(order)
target = CStr(order(i))
If SheetExists(target) Then
If i = LBound(order) Then
ThisWorkbook.Worksheets(target).Move Before:=ThisWorkbook.Worksheets(1)
Else
'現在の並びの i 番目の直後に置く
pos = i - LBound(order) + 1
ThisWorkbook.Worksheets(target).Move After:=ThisWorkbook.Worksheets(pos - 1)
End If
End If
Next
Application.ScreenUpdating = True
End Sub
Function SheetExists(name As String) As Boolean
Dim t As Worksheet
On Error Resume Next
Set t = ThisWorkbook.Worksheets(name)
SheetExists = Not t Is Nothing
On Error GoTo 0
End Function
Sub Example_ReorderArray()
Dim order As Variant
order = Array("トップ", "売上", "在庫", "顧客", "設定")
ReorderByArray order
End Sub
VB- ポイント:
- 柔軟: 欲しい並びをそのまま書ける。存在しない名前は安全にスキップ。
- 前から詰める: 左端→以降直後に置くと意図通りに並ぶ。
一覧シート(Control!A列)で指定
Sub ReorderByControlList()
Dim ctrl As Worksheet, last As Long, r As Long, name As String, idx As Long
Set ctrl = ThisWorkbook.Worksheets("Control")
last = ctrl.Cells(ctrl.Rows.Count, "A").End(xlUp).Row
If last < 2 Then Exit Sub
Application.ScreenUpdating = False
'A2から順に並べる
idx = 1
For r = 2 To last
name = CStr(ctrl.Cells(r, "A").Value)
If SheetExists(name) Then
If idx = 1 Then
ThisWorkbook.Worksheets(name).Move Before:=ThisWorkbook.Worksheets(1)
Else
ThisWorkbook.Worksheets(name).Move After:=ThisWorkbook.Worksheets(idx - 1)
End If
idx = idx + 1
End If
Next
Application.ScreenUpdating = True
End Sub
VB- ポイント:
- 運用に強い: 並びを表で管理でき、編集もしやすい。
一部だけ並べ替える(可視限定・除外あり)
Sub SortVisibleWorksheetsByName()
Dim vis() As String, ws As Worksheet, n As Long, i As Long, j As Long, t As String
'可視ワークシート名を配列化
For Each ws In ThisWorkbook.Worksheets
If ws.Visible = xlSheetVisible Then
n = n + 1
ReDim Preserve vis(1 To n)
vis(n) = ws.Name
End If
Next
If n <= 1 Then Exit Sub
'昇順にソート
For i = 1 To n
For j = i + 1 To n
If StrComp(vis(i), vis(j), vbTextCompare) > 0 Then
t = vis(i): vis(i) = vis(j): vis(j) = t
End If
Next j
Next i
'可視シートだけ前詰めで再配置(非表示は触らない)
Application.ScreenUpdating = False
ThisWorkbook.Worksheets(vis(1)).Move Before:=ThisWorkbook.Worksheets(1)
For i = 2 To n
ThisWorkbook.Worksheets(vis(i)).Move After:=ThisWorkbook.Worksheets(i - 1)
Next
Application.ScreenUpdating = True
End Sub
VB- ポイント:
- 非表示を保つ: VeryHidden/Hiddenを動かしたくないときに有効。
- 画面安定: 先頭から順に並べると意図通りになる。
例題で練習
例題1:月次レポートを「トップ→設定→月次→その他」の順に並べる
Sub Example_MonthlyOrder()
Dim order As Variant
order = Array("トップ", "設定", "月次", "その他")
ReorderByArray order
End Sub
VB- ポイント:
- 明確な順序: 重要シートを前に、補助系を後ろへ。
例題2:名前の先頭が「週報_」のシートだけを名前順で前方に集約
Sub Example_CollectWeeklyToFront()
Dim ws As Worksheet, list As New Collection, i As Long
'対象を収集
For Each ws In ThisWorkbook.Worksheets
If Left$(ws.Name, 3) = "週報" Then list.Add ws.Name
Next
If list.Count = 0 Then Exit Sub
'前方へ固める(順序は収集順、必要なら名前ソートを挟む)
Application.ScreenUpdating = False
ThisWorkbook.Worksheets(list(1)).Move Before:=ThisWorkbook.Worksheets(1)
For i = 2 To list.Count
ThisWorkbook.Worksheets(list(i)).Move After:=ThisWorkbook.Worksheets(i - 1)
Next
Application.ScreenUpdating = True
End Sub
VB- ポイント:
- 集約: 週報など系列シートを前方にまとめて見やすく。
例題3:目次(Index)の次に「売上」「在庫」「顧客」を並べ替え
Sub Example_AfterIndexOrder()
Dim anchorPos As Long, order As Variant, i As Long
'Indexの位置を特定
anchorPos = ThisWorkbook.Worksheets("Index").Index
Application.ScreenUpdating = False
order = Array("売上", "在庫", "顧客")
For i = LBound(order) To UBound(order)
If SheetExists(CStr(order(i))) Then
ThisWorkbook.Worksheets(CStr(order(i))).Move After:=ThisWorkbook.Worksheets(anchorPos)
anchorPos = ThisWorkbook.Worksheets(CStr(order(i))).Index
End If
Next
Application.ScreenUpdating = True
End Sub
VB- ポイント:
- アンカーを使う: 指定シートの直後に連続で並べると、束で扱いやすい。
実務の落とし穴と対策
- インデックスのズレ:
- 対策: 左端から順に「先頭→直後」方式で並べる。削除・挿入と同様、逆順ループやアンカーを活用。
- 存在しない名前:
- 対策: 事前に存在チェック。上の SheetExists 関数を必ず使う。
- 非表示/VeryHiddenの扱い:
- 対策: 可視限定で動かすか、動かす対象を明示的にリスト化。
- ThisWorkbookとActiveWorkbookの混同:
- 対策: 対象ブックを統一して記述。別ブックなら Workbooks(“名前”) を使って渡す。
- 大量枚数のパフォーマンス:
- 対策: Application.ScreenUpdating を False にしてからまとめて移動、最後に True に戻す。
