Excel VBAで業務効率化:1行内の複数列のデータを複数行に入れ替えてコピーする方法

はじめに

Excel VBAを使用して業務効率化を図る方法を紹介します。具体的には、1行内の複数列のデータを複数行に入れ替えてコピーする方法について解説します。この方法を活用することで、データ処理の手間を大幅に削減できます。特に、大量のデータを扱う業務においては、手動での作業を自動化することで効率が飛躍的に向上します。

VBAの基本設定

まずは、VBAの基本設定方法について説明します。Excelの開発者タブを有効にし、VBAエディタを開く手順を確認します。

  1. Excelを開き、[ファイル] > [オプション] > [リボンのユーザー設定]を選択します。
  2. [開発]タブにチェックを入れて、[OK]をクリックします。
  3. [開発]タブが表示されたら、[Visual Basic]をクリックしてVBAエディタを開きます。

vba-efficiency-multiple-columns-to-rows03

VBAエディタでは、新しい標準モジュールを挿入するか、既存シートのエリアにコードを記述します。これにより、Excelの操作を自動化するためのスクリプトを作成できます。

vba-efficiency-multiple-columns-to-rows04

処理概要

1件の相談に対して複数列にわたり相談種別が入力されている表があるとします。この表では、1件のデータに対してどんな相談があったかを確認することができますが、各列にどの種別が入力されるかが不明なため、全体を把握する際に特定の相談種別がいつ、どれだけあったのかを把握するのは困難です。

そこで本記事では、Excel VBAを使用して、1行に入力されている相談種別の数だけ複数行に展開する方法を考えます。これにより、相談種別を一つの列に集約できるため、フィルターなどを用いたデータの把握や集計が容易になります。

この処理は、特定の業務プロセスを自動化し、手動で行っていた複雑なデータ操作を効率化することを目的としています。

vba-efficiency-multiple-columns-to-rows01a
展開前イメージ
vba-efficiency-multiple-columns-to-rows02a
展開後イメージ

コードの全体像

次に、本記事で使用するVBAコードの全体像を示します。このコードは、1行内の複数列に入力されたデータを複数行に展開してコピーするためのものです。

Sub CopyTableRows()
    Dim wsSource As Worksheet
    Dim wsDestination As Worksheet
    Dim tblSource As ListObject
    Dim tblDestination As ListObject
    Dim rng As Range
    Dim rngToCopy As Range
    Dim rngPS As Range
    Dim newRow As ListRow
    Dim i As Integer

    ' スクリーン更新と自動計算をオフにする
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual

    ' ソースシートと宛先シートを設定
    Set wsSource = ThisWorkbook.Sheets("マスタデータ")
    Set wsDestination = ThisWorkbook.Sheets("サポート種別展開")

    ' ソースシートと宛先シートのテーブルを設定
    Set tblSource = wsSource.ListObjects("業務日報")
    Set tblDestination = wsDestination.ListObjects("サポート種別")

    ' コピー先のテーブルのデータをすべて消去
    If tblDestination.ListRows.Count > 0 Then
        tblDestination.DataBodyRange.Delete
    End If

    ' テーブルの全行をループ
    For Each rng In tblSource.DataBodyRange.Rows
        'L列からO列を除外し、P列からQ列までを含む
        Set rngToCopy = Union(rng.Resize(, 11), rng.Offset(, 15).Resize(, 2))
        ' 宛先シートのテーブルの最後の行にコピー
        rngToCopy.Copy Destination:=tblDestination.ListRows.Add(AlwaysInsert:=True).Range.Resize(, rngToCopy.Columns.Count)

        'L列からO列までデータが入力されている場合は、次の行に同じデータを挿入し、K列にそのデータを入れる
        Set rngPS = rng.Offset(, 11).Resize(, 4)
        i = 0
        Do While i < Application.WorksheetFunction.CountA(rngPS)
            Set newRow = tblDestination.ListRows.Add(AlwaysInsert:=True)
            rngToCopy.Copy Destination:=newRow.Range.Resize(, rngToCopy.Columns.Count)
            newRow.Range.Cells(1, 11).Value = rng.Cells(, 12 + i)
            i = i + 1
        Loop
    Next rng
    
    ' スクリーン更新と自動計算をオンに戻す
    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
    
End Sub

このコードは、マスタデータシート(以下、ソースシート)からデータを取得し、サポート種別展開シート(以下、宛先シート)にコピーするプロセスを自動化します。特に、特定の列を除外してコピーする部分や、複数行にデータを展開する部分がポイントです。

ソースシートと宛先シートの設定

ソースシートと宛先シートの設定方法について詳しく解説します。まず、ソースシートと宛先シートを変数に設定します。

Set wsSource = ThisWorkbook.Sheets("マスタデータ")
Set wsDestination = ThisWorkbook.Sheets("サポート種別展開")

次に、ソースシートと宛先シートのテーブルを設定します。

Set tblSource = wsSource.ListObjects("業務日報")
Set tblDestination = wsDestination.ListObjects("サポート種別")

これにより、ソースシートと宛先シートのテーブルを操作する準備が整います。テーブルはExcelのリストオブジェクトとして扱われ、データの操作が容易になります。

テーブルの設定とデータの消去

宛先シートの既存データを消去する方法を説明します。以下のコードを使用して、宛先シートのテーブル内のデータをすべて削除します。

If tblDestination.ListRows.Count > 0 Then
    tblDestination.DataBodyRange.Delete
End If

このコードは、宛先シートのテーブルに既存のデータがある場合、それをすべて削除します。これにより、新しいデータをクリーンな状態で挿入することができます。

データのコピーと入れ替え

各行のデータをコピーし、必要に応じて複数行に入れ替える方法について詳しく解説します。具体的なコードの説明とともに、Union関数やOffset関数の使い方を紹介します。

For Each rng In tblSource.DataBodyRange.Rows
    Set rngToCopy = Union(rng.Resize(, 11), rng.Offset(, 15).Resize(, 2))
    rngToCopy.Copy Destination:=tblDestination.ListRows.Add(AlwaysInsert:=True).Range.Resize(, rngToCopy.Columns.Count)

この部分のコードでは、各行のデータをコピーし、必要に応じて複数行に入れ替えます。Union関数を使用して、特定の列を選択し、Offset関数を使用して列をシフトさせます。これにより、特定の列を除外してコピーすることができます。

L列からO列のデータ処理

L列からO列のデータをチェックし、必要に応じて新しい行にデータを挿入する方法を説明します。CountA関数の使い方や、ループ処理の詳細についても触れます。

Set rngPS = rng.Offset(, 11).Resize(, 4)
i = 0
Do While i < Application.WorksheetFunction.CountA(rngPS)
    Set newRow = tblDestination.ListRows.Add(AlwaysInsert:=True)
    rngToCopy.Copy Destination:=newRow.Range.Resize(, rngToCopy.Columns.Count)
    newRow.Range.Cells(1, 15).Value = rng.Cells(, 16 + i)
    i = i + 1
Loop

この部分のコードでは、L列からO列のデータをチェックし、データが入力されている場合は新しい行にデータを挿入します。CountA関数を使用して、データが入力されているセルの数をカウントし、ループ処理で新しい行にデータをコピーします。これにより、特定の条件に基づいてデータを動的に処理することができます。

スクリーン更新と自動計算の制御

スクリーン更新と自動計算をオフにする理由と、その方法について説明します。最後に、これらをオンに戻す方法も紹介します。

Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual

' 処理後にオンに戻す
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic

スクリーン更新と自動計算をオフにすることで、コードの実行速度を向上させることができます。特に、大量のデータを処理する場合には、これらの設定をオフにすることでパフォーマンスが大幅に向上します。処理が完了したら、これらをオンに戻すことを忘れないようにしましょう。

まとめ

本記事の内容を総括し、VBAを使用した業務効率化のメリットについて再確認します。また、読者に対しての次のステップや追加のリソースも提供します。VBAを活用することで、日々の業務がどれだけ効率化できるかを実感していただければ幸いです。

VBAを使うことで、手動で行っていた複雑なデータ処理を自動化し、時間と労力を大幅に削減することができます。特に、今回紹介したようなデータのコピーと入れ替えのプロセスは、手作業では非常に手間がかかるものですが、VBAを使えば簡単に実現できます。

さらに、VBAのスクリプトは一度作成すれば何度でも再利用可能です。これにより、同じ作業を繰り返す必要がなくなり、業務の効率化が図れます。また、VBAの知識を深めることで、他の業務プロセスの自動化にも応用できるようになります。

Excelの基本から便利な関数やグラフ


ピボットテーブルの基本から応用


マクロ/VBAの基本&業務効率化