エクセルのマクロ(VBA)でデータを分割する方法を説明します。
何らかのExcelの表形式のデータがあったとして、それをグループ分けして別ファイルで保存します。
1.概要
今回のデータを分割するマクロの作業概要は以下の通りです。
①任意の列を基準にグループ分けしてデータを分割。
②そのグループ名でそれぞれを別ブックで保存。
例としては以下のようなイメージです。
映画タイトルやジャンル、評価などの一覧データがあったとします。
任意の列を3列目(C列)としてマクロを実行すると、グループ分けしアクションだけのデータやサスペンスだけのデータに分割してその名前で保存します。
2.コード全体
以下が今回のマクロのコード全体です。
これをなるべく簡潔に説明していきます。
※マクロは上から下に向かって順番に実行されていきます。
※ページの最後にコピペできるようにコード全体を載せておきます。
____________________________________________
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
なるべく短く記述することに努めましたが、初学者の方はこれでも見ていてしんどいかもしれません。
よって一度コードを取り払います!
3.コードを日本語に変換してみる
上で示したコードを日本語で表現しなおすとこのようになります。
____________________________________________
【イメージ】
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
①本マクロがあるフォルダを作業場所として設定。
②どの列を基準にグループ分けして分割するかを設定(上記例でいうと3列目の「ジャンル」)。
③データ開始行を設定(上記例でいうと2行目)。
④最終行を判定(データの存在する最終行を自動で判定します)。
⑤データを一行ずつ順番に見ながら⑥以降の作業を繰り返す。
⑥もしまだ分割データが作成されていないグループなら⑦~⑩までを実行(例:サスペンスのデータが未作成なら、グループ分け対象としてサスペンスを認識する)。
⑦データを別の新規ブックとしてコピー。
⑧データを一行ずつ順番に見ながら⑨の作業を繰り返す。
⑨上記⑥で認識したグループ以外の行なら削除(例:グループ分け対象としてサスペンスを認識している時なら、アクションやホラーなどの行は削除)。
⑩不要な行を削除し終わった状態で保存。
(⑩まで作業完了したら⑤に戻り次の行を見る)
4.コードの解説
ここからは上記の日本語にしたものを一部ずつコードに戻しながら説明していきます。
上述した全体の動作イメージを常に持ちながら読むようにしてください。
説明するコードは太字で示します。
4-1.作業場所の設定と変数
一部日本語をコードに戻します。
____________________________________________
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
①ChDir ThisWorkbook.Path
マクロファイルと同じフォルダを作業場所として認識。
※マクロは常にこのフォルダを作業場所として認識する。
②開始行 = 2
「開始行」という変数は2になる。
③最終行 = ActiveSheet.UsedRange.Cells( ・・・
「最終行」という変数はデータの存在する最終行の数字になる。
補足:変数とは?
任意の文字や数字など、何にでもなれる存在。
変数ではなく文字として扱いたい場合、””で囲む。
例:開始行 → 変数
”開始行” → 文字
4-2.繰り返し処理
さらに一部、日本語をコードに戻します。
ここでは太字の「For ~ Next i」の箇所に注目してください。
____________________________________________
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
For文
何らかの作業を繰り返し行う時に使用する。
変数が プラス or マイナス されながら指定の数字に到達するまで繰り返す。
以下の例の場合、iが変数。
どれくらい プラス or マイナス されるかを表しているのが「step 〇」の箇所。
上の例1でいうと、プログラムが上から指示を行っていきこのFor文に突入します。
このときiは1からスタートします。
For以下に書いてある指示を行ったら、iは+1されてForの先頭に戻ります。
そしてまた指示を行い、iはさらに+1され先頭に…
といった感じに指示を繰り返し、iが100になるまで繰り返し続けます。
4-2.セルの参照とIf文など
For以降の指示内容の部分をコードに戻します。
____________________________________________
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
Cells(〇, ☆).Value
〇行目・☆列目のセルの値(文字や数字)。
・・・ & “.xlsx”
「&」は文字・数字・変数などを結合する役割。
「”.xlsx”」は””で囲んでいるので変数ではなく文字。
If文
指示を If と End If で挟む。
Ifから始まる条件に当てはまる場合は指示を行う。
当てはまらない場合は指示を行わない。
End IF に到達したらIf文は終了。
Dir(~)
~というファイルが存在しない場合、空白を返してくる。
“”
空白を表す。
4-3.シートのコピーと保存など
If文以降の指示内容の部分をコードに戻します。
____________________________________________
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
ActiveSheet.Copy
選択されているシートをコピーする。
するとコピーされ新規ブックとなったシートが画面の前面に表示されるので、指定がない限りマクロはその後このシートを対象に作業をしていくことになる。
ターゲット = Cells(i, 基準列).Value
「ターゲット」という変数は、「i」行目の「基準列」列目の値(例:「サスペンス」「ドラマ」「アクション」 etc…)になる。
上述の通り「i」と「基準列」もそれぞれ変数であり、何らかの数字になっているのです(「基準列」は固定で3、「i」はFor文の中で1から順番に変化していきます)。
ActiveWorkbook.SaveAs 〇〇
選択されているブックを〇〇という名前で保存。
不要な行を削除して一つのグループのみ(例えばサスペンスのみ)にしたブックを保存する。
ActiveWorkbook.Close
選択されているブックを閉じる。
選択されているブックとは、そのとき最前面のブックです。つまり「ActiveSheet.Copy」でコピーされた新規ブックのことです。
4-4.不要な行の削除
If文以降の指示内容の部分をコードに戻します。
____________________________________________
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
Rows(☆).Delete
Rows(☆)・・・☆行目。
Delete・・・削除する。
この2つを合わせて読むと、「☆行目を削除」となります。
<>
If文の中で使い、「ではない」という意味。
つまりIf文の先頭から読むと「もし「d」行目・「基準列」列目のセルが「ターゲット」の値”ではない”のであれば、「d」行目を削除する」となります。
※「d」「基準列」「ターゲット」はすべて変数です。
5.コードコピペ用
ここまでの説明にでてきたコードは画像だったので、コピペできるようにテキストで載せておきます。
※掲載すると左寄せになってしまうようです。コピペ後はご自身で位置を調整してください(左寄せのままでも動きます)。
Sub データ分割()
Application.ScreenUpdating = False
ChDir ThisWorkbook.Path
基準列 = 3
開始行 = 2
最終行 = ActiveSheet.UsedRange.Cells(ActiveSheet.UsedRange.Count).Row
For i = 最終行 To 開始行 Step -1
ファイル名 = Cells(i, 基準列).Value & “.xlsx”
If Dir(ファイル名) = “” Then
ActiveSheet.Copy
ターゲット = Cells(i, 基準列).Value
For d = 最終行 To 開始行 Step -1
If Cells(d, 基準列).Value <> ターゲット Then Rows(d).Delete
Next d
ActiveWorkbook.SaveAs ファイル名
ActiveWorkbook.Close
End If
Next i
Application.ScreenUpdating = True
End Sub