エクセルのシート分割・統合を自動化!手作業ミスをゼロにするVBAの使い方とは

 

大量のデータを手作業でシート分割・シート統合していませんか?

 

VBAを使えば、何十分もかかっていたシートの分割・統合作業をボタン1クリックで処理可能。

この記事では、実務でよく発生する「シート分割」「シート統合」の2パターンを、実際のVBAコードを交えて紹介します。

 

手作業でシートを分割・統合していると、コピペの抜け漏れや転記ミスが発生しやすく、修正作業に余計な時間を取られることになります。

しかし、VBAで自動化してしまえば、毎回同じ処理を正確に実行してくれるので、編集ミスは発生しません。

 

「プログラミングの知識がなくても使えるの?」と思った方も安心してください。

この記事では、プログラミング初心者の方でも理解できるように、コードの動きをひとつひとつ丁寧に解説します。

 

広告

手作業のシート分割・統合が引き起こす3つの問題

エクセルでデータを管理していると、「担当者ごとにシートを分けてほしい」「各部署のシートをひとつにまとめてほしい」といった作業が日常的に発生しますよね。

 

件数が少ないうちは手作業でもすぐに対応できると思います。

しかし、

データが100件、200件と増えてくるとどうでしょう。

コピペミスが発生したり、必要なデータを間違って削除してしまったり、編集ミスが発生してしまいます。

 

私がこれまで受注してきたマクロ開発の中でも、「シート分割・統合の自動化」は特に依頼が多い案件のひとつです。

依頼者の話を聞くと、手作業で処理し続けることで下記のような問題が発生していることがわかりました。

 

問題①:コピペの抜け漏れによる編集ミスが頻発する

手作業でデータをシートに振り分けていると、「このデータをコピーしたっけ?」「あのシートに貼り付け忘れていた」というミスが必ず起きます。

データ件数が多くなるほど、目視での確認には限界がある。

 

特に月末や締め切り直前に急いで処理すると、コピペの抜け漏れが発生しやすく後から修正する作業が余計に発生します。

私が受注したケースでも、「手作業でシートを分けていたら、ひとつのシートだけデータが漏れていた」というトラブルが原因でVBA導入を決めた担当者の方が多くいらっしゃいました。

 

問題②:件数が増えるほど処理時間が長くなる

「10人分のデータを担当者ごとに振り分ける」という作業を毎月手作業でやっていたとすると、どうなるでしょうか。

データが100件なら10分で終わる作業でも、500件になれば30分以上かかることも珍しくありません。

 

データ量に比例して作業時間も増えていくのが手作業の問題点です。

 

VBAで自動化してしまえば、データ件数が1,000件に増えても処理時間はほぼ変わりません。 ボタンを押してから数秒で完了します。

 

問題③:毎月同じ作業を繰り返す非効率さ

シート分割・統合が月次業務になっている場合、毎月同じ手順を繰り返すことになります。

「先月もやったから手順はわかってる」と思っていても、担当者が変わると手順の引き継ぎが必要になりますし、手順書を別途作成するコストが発生してしまう。

 

VBAで一度自動化してしまえば、誰でもボタンひとつで同じ処理が実行でき引き継ぎのコストもかかりません。

 

シート分割VBAの基本|条件に合わせてデータを自動で振り分ける

シート分割VBAとは、一枚の一覧表シートにあるデータを、特定の条件(担当者名・部署名・地域名など)に従って複数のシートに自動で振り分けるVBAのことです。

 

たとえば、「一覧表シートにある全社員のデータを、担当部署ごとに別シートへ分割したい」という場面で活躍します。

手作業でやろうとするとフィルターをかけて、コピーして、シートに貼り付けて、という繰り返し作業が発生しますが、VBAなら一瞬で処理できるんです。

 

サンプル事例:担当者ごとにシートを自動分割する

「Sheet1」に以下のような一覧表があるとします。 A列に「担当者名」、B列に「案件名」、C列に「売上金額」が入力されています。

サンプル事例一覧表

 

このデータを担当者名(A列)ごとに別シートへ自動分割するVBAを作成します。 担当者が「田中」「鈴木」「佐藤」の3名いる場合、「田中」シート・「鈴木」シート・「佐藤」シートが自動で作成され、それぞれのデータが転記されます。

 

Sub シート分割()

Dim ws_src As Worksheet '元データのシート
Dim ws_new As Worksheet '分割先の新しいシート
Dim lastRow As Long '元データの最終行
Dim i As Long 'ループカウンター
Dim staffName As String '担当者名を格納する変数
Dim sheetExists As Boolean 'シートが存在するか確認するフラグ

'元データのシートを設定
Set ws_src = ThisWorkbook.Worksheets("Sheet1")

'元データの最終行を取得(A列で判定)
lastRow = ws_src.Cells(Rows.Count, 1).End(xlUp).Row

'2行目から最終行まで繰り返し処理
For i = 2 To lastRow

'担当者名を取得
staffName = ws_src.Cells(i, 1).Value

'シートがすでに存在するか確認
sheetExists = False
Dim sh As Worksheet
For Each sh In ThisWorkbook.Worksheets
If sh.Name = staffName Then
sheetExists = True
Exit For
End If
Next sh

'シートが存在しない場合は新規作成
If sheetExists = False Then
Set ws_new = ThisWorkbook.Worksheets.Add(After:=ThisWorkbook.Worksheets(ThisWorkbook.Worksheets.Count))
ws_new.Name = staffName

'新しいシートにヘッダー行をコピー
ws_src.Rows(1).Copy Destination:=ws_new.Rows(1)
End If

'担当者名のシートを取得
Set ws_new = ThisWorkbook.Worksheets(staffName)

'担当者のシートの最終行を取得し、次の行にデータを転記
Dim newLastRow As Long
newLastRow = ws_new.Cells(Rows.Count, 1).End(xlUp).Row + 1
ws_src.Rows(i).Copy Destination:=ws_new.Rows(newLastRow)

Next i

MsgBox "シートの分割が完了しました。", vbInformation

End Sub

 

実行結果がこちら

サンプルs事例の実行結果

担当者の人数分シートが作成され、データを分割することができます。

 

シート分割VBAコードの全体像と解説

コードの流れを順番に解説します。

 

まず Set ws_src = ThisWorkbook.Worksheets(“Sheet1") で、元データが入っているシートを変数に格納します。

シート名が「Sheet1」以外の場合は、この部分を実際のシート名に書き換えてください。

 

次に lastRow = ws_src.Cells(Rows.Count, 1).End(xlUp).Row で、A列の最終行を自動取得します。

データが100件でも1,000件でも、この1行のコードで正確な最終行を取得できます。

範囲を固定値で指定すると、データが増えたときに対応できなくなるため、必ずこの書き方にしましょう。

 

その後、Forループで2行目から最終行まで1行ずつ処理します。 ループ内で、A列の担当者名を staffName という変数に取得します。

 

次の部分が重要なポイントです。

担当者名と同じ名前のシートがすでに存在するかどうかを For Each sh In ThisWorkbook.Worksheets で確認します。

シートが存在しない場合のみ新しいシートを追加し、ヘッダー行(1行目)をコピーします。

これにより、同じ担当者のデータが複数行あっても、シートが二重に作成される問題を防ぐことができます。

 

最後に、分割先のシートの最終行を取得してデータを転記します。

newLastRow = ws_new.Cells(Rows.Count, 1).End(xlUp).Row + 1 で「現在の最終行の次の行」を取得しているため、データが上書きされることなく順番に貼り付けられます。

 

シート分割VBAを実行する際の注意点

シート分割VBAを実装する際に、いくつか注意すべきポイントがあります。

 

まず、元データのA列(担当者名)に空白セルがあると、「空白」という名前のシートが作成されてしまいます。

実行前に元データの空白セルを確認・修正しておくことが大切です。

 

また、すでに同じ名前のシートが存在する状態でVBAを実行した場合、そのシートにデータが追記されます。

「毎月新鮮なデータに洗い替えたい」という場合は、実行前に既存の分割シートを削除する処理を追加するとよいでしょう。

 

関連記事「別シートにテキストを自動転記」では、シートを指定するVBA、転記VBAが設定されたエクセルファイルをダウンロードすることができます。

 

シート統合VBAの基本|複数シートのデータをまとめて一覧化する

シート統合VBAとは、複数のシートに分散しているデータを、ひとつのシートにまとめて一覧化するVBAのことです。

たとえば「1月シート」「2月シート」「3月シート」に入力されている月次データを、「集計シート」にまとめて年間一覧表を作りたい場面や、各部署がそれぞれ入力したシートを管理者がひとつにまとめたい場面で活躍します。 シート数が多いほど手作業での統合は大変で、ひとつでも貼り付けを忘れると集計結果がずれてしまうリスクがあります。

 

サンプル事例:複数の月次報告シートを1枚に統合する

「1月」「2月」「3月」という3つのシートに、それぞれ月次売上データが入力されているとします。

各シートはA列「担当者名」、B列「案件名」、C列「売上金額」という共通フォーマットです。

 

こんな感じ

サンプル事例のフォーマット

 

このデータを「集計」シートにまとめて出力するVBAを作成します。

ヘッダー行は「1月」シートの1行目を1回だけコピーし、各シートの2行目以降のデータを順番に貼り付けるという仕様です。

Sub シート統合()

Dim ws_out As Worksheet '統合先のシート(集計シート)
Dim ws_src As Worksheet '各月のデータシート
Dim lastRowSrc As Long '各シートの最終行
Dim lastRowOut As Long '統合シートの現在の最終行
Dim isFirst As Boolean '最初のシートかどうかを判定するフラグ

'統合先のシートを設定
Set ws_out = ThisWorkbook.Worksheets("集計")

'統合先シートをリセット(前回のデータをクリア)
ws_out.Rows("1:" & ws_out.Rows.Count).ClearContents

isFirst = True '最初のシートフラグを初期化

'全シートをループ処理
Dim sh As Worksheet
For Each sh In ThisWorkbook.Worksheets

'統合先の「集計」シートはスキップ
If sh.Name = "集計" Then GoTo Continue

'データの最終行を取得
lastRowSrc = sh.Cells(Rows.Count, 1).End(xlUp).Row

'最初のシートのみヘッダー行(1行目)をコピー
If isFirst = True Then
sh.Rows(1).Copy Destination:=ws_out.Rows(1)
isFirst = False
End If

'2行目以降のデータを統合シートに貼り付け
lastRowOut = ws_out.Cells(Rows.Count, 1).End(xlUp).Row + 1
sh.Range("A2:C" & lastRowSrc).Copy Destination:=ws_out.Cells(lastRowOut, 1)

Continue:
Next sh

MsgBox "シートの統合が完了しました。", vbInformation

End Sub

 

実行結果がこちら

マクロの実行結果

 

シート数がどれだけ増えても問題なし!

全てのシートを対象にデータが集計シートに統合されます。

 

シート統合VBAコードの全体像と解説

コードの流れを順番に解説します。

まず Set ws_out = ThisWorkbook.Worksheets(“集計") で、データをまとめる先の「集計」シートを変数に格納します。

次に ws_out.Rows(“1:" & ws_out.Rows.Count).ClearContents で集計シートの全データをクリアします。

前回実行したときのデータが残ったまま新しいデータを追記してしまうという問題を防ぐために、必ずクリア処理を入れておきましょう。

 

For Each sh In ThisWorkbook.Worksheets で、ブック内のすべてのシートを順番に処理します。

If sh.Name = “集計" Then GoTo Continue で、統合先の「集計」シート自身はスキップします。

これがないと「集計シートのデータも統合対象になる」という無限ループの原因になるので注意してください。

 

isFirst というフラグを使って、最初のシートのときだけヘッダー行(1行目)をコピーする仕組みにしています。

すべてのシートでヘッダーをコピーすると、集計シートに「担当者名・案件名・売上金額」という見出し行が何行も挿入されてしまうので注意してください。

 

最後に、各シートの2行目以降のデータを集計シートに貼り付けます。

 

lastRowOut = ws_out.Cells(Rows.Count, 1).End(xlUp).Row + 1 で常に「現在の最終行の次の行」を取得するため、データが重なって上書きされることはありません。

 

シート統合VBAを実行する際の注意点

シート統合VBAを使う際にも、いくつか注意点があります。

まず、各シートのフォーマット(列の構成)が統一されていることが前提条件です。

 

「1月シートはA列が担当者名、B列が案件名」なのに、「2月シートはA列が案件番号、B列が担当者名」というフォーマットの違いがあると、集計シートのデータが混乱します。

VBA導入前に、各シートのフォーマットを統一しておきましょう。

 

また、統合対象外にしたいシートがある場合は、If sh.Name = “集計" Then GoTo Continue の部分に条件を追加することで除外できます。

たとえば「設定」シートや「マスタ」シートが存在する場合も同様に除外条件を追記してください。

 

関連記事「シート分割・統合作業、毎日何十分も時間をかけてない?一瞬で処理するVBA自動化テクニック」では、シート分割・統合VBAが設定されたエクセルファイルをダウンロードすることができます。

 

実際にマクロを動かして便利さを体感してみてください。

 

VBAをボタンに登録してワンクリックで実行する方法

ここまで紹介したシート分割VBAとシート統合VBAは、エクセルシート上にボタンを配置することで1クリックで実行することができます。

 

設定方法はとても簡単で、「開発」タブ → 「挿入」 → 「ボタン(フォームコントロール)」を選択して、シート上にドラッグするだけ。

ドラッグすると「マクロの登録」ダイアログが開くので、登録したいマクロ名(例:シート分割 または シート統合)を選んで「OK」をクリックすれば設定完了です。

ボタン作成方法

 

ボタン上で右クリックして「テキストの編集」を選べば、「▶ シート分割を実行」「▶ シート統合を実行」などの説明文をボタンに表示することもできます。

 

注意点として、

「開発」タブがエクセルのメニューに表示されていない場合は、「ファイル」→「オプション」→「リボンのユーザー設定」から「開発」にチェックを入れると表示される

ようになります。

 

一度ボタンを設置してしまえば、次回からは常に表示されるので操作手順を覚える必要はありません。

ボタンは、開発したマクロを誰もが簡単に使えるようにするための方法なので必ず配置しましょう。

 

まとめ ~ シート分割・統合はVBAで自動化が正解 ~

エクセルのシート分割・シート統合を手作業でやり続けることには、「編集ミスの発生」「処理時間の増大」「毎月同じ作業の繰り返し」という3つの問題があります。

 

VBAを使えば、担当者ごとのシート分割も、複数シートの統合も、ボタン1クリックで自動処理可能。

しかも、データ件数が増えても処理時間はほぼ変わらず、編集ミスも発生しません。

一度VBAを設定してしまえば、毎月の面倒な作業から完全に解放されます。

 

今回紹介したVBAコードをベースに、自分の業務に合わせてカスタマイズしてみてください。

シート名の条件や転記する列の範囲を変えるだけで、さまざまな分割・統合パターンに対応できます。

 

もし「自分の業務に合わせた複雑なチェック処理を実装したい」「既存のマクロを改良したい」といったご要望がありましたら、マメBlogのエクセルマクロ開発依頼にご相談ください。

 

業務内容に合わせたオーダーメイドマクロを設定させていただきます。

最後まで読んでいただきありがとうございました。

エクセルVBAを使って面倒なルーティーン作業を自動化しちゃいましょう。