VBAでシートを指定行数ごとに分割して複数ファイルへ保存する

マクロブックのアクティブシート(元シート)にあるデータを以下の条件で新しいファイルを作成

  • 「元シート」の一行目をヘッダー行として新しいファイルにコピーする
  • 新しいファイル名は、「NewFile_」(定数で指定)の後に、連番を追加
  • 新しいファイルの保存先は、マクロブックと同じフォルダ
  • 一つのファイルの最大行は1000行(定数で指定)
  • B列に入っている値が一つ上の行と同じの場合は二つのファイルに分かれないようにする (コピーする列を繰り上げるなど)

以下がマクロです。

Private Sub CopyDataToNewFiles()
    Const maxRows As Long = 1000
    Const newFileName As String = "NewFile_"
    Dim newWb As Workbook
    Dim ws As Worksheet, newWs As Worksheet
    Dim newRow As Long, newFileNum As Long
    Dim lastRow As Long, currentRow As Long
    Dim newFileMake As Boolean: newFileMake = True
    Dim currentStartRow As Long
    
    ' アクティブシートを指定
    Set ws = ThisWorkbook.ActiveSheet
    
    ' 最終行を取得
    lastRow = ws.Cells(ws.Rows.Count, 2).End(xlUp).Row
    
    ' 新しいファイルにコピーするための変数を初期化
    'newFileNum = 0
    
    ' データをコピー
    For currentRow = 2 To lastRow
        ' ファイルを新作
        If newFileMake Then         ' 新しいファイルの作成フラグ
            If Not newWb Is Nothing Then
                ' 保存して閉じる
                newWb.Close SaveChanges:=True
            End If
            
            newFileMake = False
            ' 新しいブックを作成
            Set newWb = Workbooks.Add
            Set newWs = ActiveSheet
            ' ヘッダー行をコピー
            ws.Rows(1).Copy Destination:=newWs.Rows(1)

            ' 新しいファイルを保存
            newFileNum = newFileNum + 1
            newWb.SaveAs ThisWorkbook.Path & "\" & newFileName & Format(newFileNum, "0") & ".xlsx"
            
            newRow = 2                      ' 新ファイルの行数
            currentStartRow = currentRow    ' コピー元先頭行
        End If
        
        ' 一つのファイルの最大行が1000行+b列に入っている値が一つ上の行と違う場合は新しいファイルを作成
        ' 最後の行の時も実行
        If (newRow >= maxRows And ws.Cells(currentRow, 2).Value <> ws.Cells(currentRow + 1, 2).Value) _
                        Or currentRow = lastRow Then
            newFileMake = True      ' 新しいファイルの作成フラグ
            ' 複数行をコピー
            ws.Rows(currentStartRow & ":" & currentRow).Copy Destination:=newWs.Rows("2:" & newRow)
        End If
        newRow = newRow + 1     ' 新ファイルの行数
        
    Next currentRow
    
    ' 保存して閉じる
    newWb.Close SaveChanges:=True
    ' 完了メッセージ
    MsgBox newFileNum & "個のファイルを作成しました。"
End Sub

元データの例

例えば次のようなデータがあるとします。

商品コード得意先商品名
1A社商品1
2A社商品2
3A社商品3
4B社商品4
5B社商品5
6C社商品6
7C社商品7
8C社商品8
9D社商品9
10D社商品10

ここでは説明用に最大行数を5行とします。


単純に5行で分割した場合

NewFile_1.xlsx

商品コード得意先商品名
1A社商品1
2A社商品2
3A社商品3
4B社商品4
5B社商品5

NewFile_2.xlsx

商品コード得意先商品名
6C社商品6
7C社商品7
8C社商品8
9D社商品9
10D社商品10

この場合は問題ありません。


B列の値が途中で分割されそうな場合

例えば次のようなデータです。

商品コード得意先商品名
1A社商品1
2A社商品2
3A社商品3
4A社商品4
5A社商品5
6A社商品6
7B社商品7
8B社商品8
9C社商品9

最大行数を5行に設定すると、本来は5行目で分割されます。

しかしA社のデータが続いているため、

NewFile_1.xlsx

商品コード得意先
1A社
2A社
3A社
4A社
5A社
6A社

NewFile_2.xlsx

商品コード得意先
7B社
8B社
9C社

となります。

つまり、

B列の値が変わるタイミングまで分割を延期

しています。


マクロの処理の流れ

① アクティブシートを取得

Set ws = ThisWorkbook.ActiveSheet
マクロブックで現在表示されているシートを処理対象とします。

② B列の最終行を取得

lastRow = ws.Cells(ws.Rows.Count, 2).End(xlUp).Row

B列の最終データ行を取得します。


③ 新しいブックを作成

Set newWb = Workbooks.Add
Set newWs = ActiveSheet

分割先となる新規ブックを作成します。


④ ヘッダー行をコピー

ws.Rows(1).Copy Destination:=newWs.Rows(1)

元シートの1行目を新しいブックへコピーします。

これにより全ての分割ファイルに見出し行が付きます。


⑤ ファイル名を付けて保存

newWb.SaveAs _
    ThisWorkbook.Path & "\" & _
    newFileName & _
    Format(newFileNum, "0") & _
    ".xlsx"

作成されるファイル名は、

NewFile_1.xlsx
NewFile_2.xlsx
NewFile_3.xlsx

のようになります。


⑥ 分割タイミングを判定

If (newRow >= maxRows And _
    ws.Cells(currentRow, 2).Value <> _
    ws.Cells(currentRow + 1, 2).Value) _
    Or currentRow = lastRow Then

ここがこのマクロの重要な部分です。

以下の条件を両方満たした時に分割します。

  • 指定行数に達した
  • 次行のB列の値が異なる

そのため、

A社
A社
A社
A社
A社
A社

の途中では分割されません。


⑦ ファイルを保存して閉じる

newWb.Close SaveChanges:=True

分割ファイルを保存し、自動的に閉じます。


実行結果

例えば5000行のデータを処理すると、

NewFile_1.xlsx
NewFile_2.xlsx
NewFile_3.xlsx
NewFile_4.xlsx
NewFile_5.xlsx

のような複数ファイルが自動生成されます。

各ファイルにはヘッダー行が付き、B列の同じ値のデータは別ファイルに分割されません。


まとめ

このマクロの特徴は次のとおりです。

  • 指定行数ごとにExcelファイルを分割
  • ヘッダー行を自動コピー
  • 連番付きファイル名で保存
  • B列の同一データを分断しない
  • 大量データの分割やシステム連携に便利

CSV出力やシステム取込用のデータ作成で特に役立つマクロです。

Follow me!