VBAでデータを都道府県ごとに振り分けるプログラムの紹介

プログラミング

はじめに

Excel VBAで都道府県ごとにデータを自動振り分けるVBAコードを作成したので、筆者自身の備忘録として記す。


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

1. このVBAコードが解決する課題

手作業で都道府県ごとにデータを分けるのは非効率だ。
大量のデータを一括で適切なシートに仕分けることで、以下の問題を解決できる。

✅ シート作成の自動化:都道府県ごとに手動でシートを作る手間を排除
✅ データ転記の高速化:バルク処理を用いて、1セルずつコピーする非効率さを回避
✅ ミスの削減:最終行を自動検出することで、手動入力ミスを防ぐ

では、どのようにコードを最適化していくのか、詳細を見ていこう。


2. コードの核心ポイント

以下のVBAコードでは、都道府県名をキーにしてデータを振り分け、必要に応じて新規シートを作成する。

Sub データ振り分け()
    Dim 元シート As Worksheet
    Dim 先シート As Worksheet
    Dim 最終行 As Long
    Dim i As Long
    Dim 都道府県名 As String
    Dim 対象行 As Long

    Set 元シート = ThisWorkbook.Worksheets("一覧表")
    最終行 = 元シート.Cells(元シート.Rows.Count, "B").End(xlUp).Row

    Application.ScreenUpdating = False

    For i = 3 To 最終行
        都道府県名 = 元シート.Cells(i, 2).Value

        ' シート存在確認と作成処理
        On Error Resume Next
        Set 先シート = ThisWorkbook.Worksheets(都道府県名)
        On Error GoTo 0

        If 先シート Is Nothing Then
            Set 先シート = ThisWorkbook.Worksheets.Add(After:=ThisWorkbook.Worksheets(ThisWorkbook.Worksheets.Count))
            先シート.Name = 都道府県名
        End If

        ' 対象行の算出
        対象行 = 先シート.Cells(先シート.Rows.Count, "B").End(xlUp).Row + 1

        ' データ転記
        With 元シート
            先シート.Cells(対象行, 2).Resize(1, 4).Value = _
                Array(.Cells(i, 3).Value, .Cells(i, 4).Value, .Cells(i, 5).Value, .Cells(i, 6).Value)
        End With

        Set 先シート = Nothing
    Next i

    Application.ScreenUpdating = True
    MsgBox "データの振り分けが完了しました", vbInformation
End Sub

3. コードの改善点と最適化

このコードはシンプルで分かりやすいが、改善の余地もある。
特に、以下の点を見直せば、さらにスマートなコードになる。

(1) シート名の不正文字対策

Excelのシート名には / \ * ? [ ] などの特殊文字が使えない。
これらを置換する処理を追加すれば、エラーを未然に防げる。

都道府県名 = Replace(都道府県名, "/", "・")
都道府県名 = Replace(都道府県名, "\", "・")
都道府県名 = Replace(都道府県名, "*", "")
都道府県名 = Replace(都道府県名, "?", "")
都道府県名 = Replace(都道府県名, "[", "")
都道府県名 = Replace(都道府県名, "]", "")

(2) シート作成処理の改善

On Error Resume Next を使用するとエラーを無視してしまい、意図しない動作を見逃す可能性がある。
シートの存在チェックを関数化すると、より安全な処理ができる。

Function シート取得または作成(シート名 As String) As Worksheet
    Dim ws As Worksheet
    On Error Resume Next
    Set ws = ThisWorkbook.Worksheets(シート名)
    On Error GoTo 0

    If ws Is Nothing Then
        Set ws = ThisWorkbook.Worksheets.Add(After:=ThisWorkbook.Worksheets(ThisWorkbook.Worksheets.Count))
        ws.Name = シート名
    End If

    Set シート取得または作成 = ws
End Function

こうすれば、メイン処理をスッキリと書ける。

Set 先シート = シート取得または作成(都道府県名)

(3) データ転記の最適化

現在のコードは Array() を使って複数のセルにデータをコピーしているが、
Resize ではなく Range を直接指定すると、可読性が向上する。

With 元シート
    先シート.Range("B" & 対象行 & ":E" & 対象行).Value = _
        Array(.Cells(i, 3).Value, .Cells(i, 4).Value, .Cells(i, 5).Value, .Cells(i, 6).Value)
End With

4. 改善後のコード

すべての改善点を反映すると、以下のようになる。

Sub データ振り分け()
    Dim 元シート As Worksheet, 先シート As Worksheet
    Dim 最終行 As Long, i As Long, 都道府県名 As String, 対象行 As Long

    Set 元シート = ThisWorkbook.Worksheets("一覧表")
    最終行 = 元シート.Cells(元シート.Rows.Count, "B").End(xlUp).Row

    Application.ScreenUpdating = False

    For i = 3 To 最終行
        都道府県名 = 元シート.Cells(i, 2).Value

        ' 不正文字の除去
        都道府県名 = Replace(都道府県名, "/", "・")
        都道府県名 = Replace(都道府県名, "\", "・")
        都道府県名 = Replace(都道府県名, "*", "")
        都道府県名 = Replace(都道府県名, "?", "")
        都道府県名 = Replace(都道府県名, "[", "")
        都道府県名 = Replace(都道府県名, "]", "")

        ' シート取得または作成
        Set 先シート = シート取得または作成(都道府県名)

        ' 対象行の算出
        対象行 = 先シート.Cells(先シート.Rows.Count, "B").End(xlUp).Row + 1

        ' データ転記
        With 元シート
            先シート.Range("B" & 対象行 & ":E" & 対象行).Value = _
                Array(.Cells(i, 3).Value, .Cells(i, 4).Value, .Cells(i, 5).Value, .Cells(i, 6).Value)
        End With
    Next i

    Application.ScreenUpdating = True
    MsgBox "データの振り分けが完了しました", vbInformation
End Sub

まとめ

業務で大量のデータ処理をするとき、ちょっとした最適化が作業時間の短縮につながる。
今後のVBA実装時に、ぜひ参考にしてほしい。

コメント