目次
はじめに
Excelでデータを扱うとき、ヘッダー行(1行目の項目名)を除いてデータ部分だけを処理したい場面は非常に多いです。今回は、ヘッダー行を除外した範囲を簡単に取得できる関数を紹介します。
ヘッダー行を除外する処理とは
データ範囲があるとき、通常は1行目に「名前」「年齢」「住所」などの項目名が入っています。このような項目名の行をヘッダー行と呼びます。
データ処理をする際、このヘッダー行は除外して、2行目以降の実際のデータだけを対象にしたいことがよくあります。例えば、A1:D10の範囲があったとき、A2:D10の範囲を取得したいケースです。
VBAではOffsetとResizeを組み合わせることで、この処理を実現できます。Offsetは範囲を移動させるメソッドで、Resizeは範囲のサイズを変更するメソッドです。
GetBodyRange関数の実装
ヘッダー行を除外する処理を関数化すると、コードが読みやすくなります。以下のような関数を作成してみました。
Function GetBodyRange(ByVal rng As Range) As Range
Set rng = rng.Offset(1) ' 1行下にオフセット
Set rng = rng.Resize(rng.Rows.Count - 1) ' 行数を1減らす
Set GetBodyRange = rng
End Function
この関数は、渡された範囲から1行目を除外した範囲を返します。
処理の流れを詳しく見ていきます。まずOffset(1)で範囲を1行下に移動させます。これでA1:D10がA2:D11になります。
次にResizeで行数を1減らします。Rows.Count - 1とすることで、元の範囲の行数から1を引いた行数にリサイズします。これでA2:D11がA2:D10になります。
この2つの処理を組み合わせることで、元の範囲の1行目を除外した範囲が得られます。
実際の使用例
実際に動作を確認できるコードを用意しました。新しいExcelブックを開いて、Alt + F11でVBエディタを開き、標準モジュールに以下のコードを貼り付けて実行してみてください。
Function GetBodyRange(ByVal rng As Range) As Range
Set rng = rng.Offset(1)
Set rng = rng.Resize(rng.Rows.Count - 1)
Set GetBodyRange = rng
End Function
Sub TestGetBodyRange()
Dim ws As Worksheet
Dim headerRange As Range
Dim bodyRange As Range
Dim i As Long
Set ws = ActiveSheet
' サンプルデータを作成
ws.Range("A1").Value = "名前"
ws.Range("B1").Value = "年齢"
ws.Range("A2").Value = "田中"
ws.Range("B2").Value = 25
ws.Range("A3").Value = "佐藤"
ws.Range("B3").Value = 30
ws.Range("A4").Value = "鈴木"
ws.Range("B4").Value = 28
' ヘッダーを含む全体の範囲を取得
Set headerRange = ws.Range("A1:B4")
' ヘッダーを除外したデータ部分を取得
Set bodyRange = GetBodyRange(headerRange)
' データ部分の各セルに色を付けて確認
bodyRange.Interior.Color = RGB(255, 255, 200)
MsgBox "データ部分の範囲: " & bodyRange.Address
End Sub
このコードを実行すると、A1:B1にヘッダーが、A2:B4にデータが作成されます。そしてGetBodyRange関数でヘッダーを除外したA2:B4の範囲に色が付きます。
この関数が便利な理由
この関数を使うメリットは、コードの意図が明確になることです。
関数を使わない場合、以下のように書くことになります。
Set dataRange = dataRange.Offset(1).Resize(dataRange.Rows.Count - 1)
一方、関数を使うと以下のように書けます。
Set dataRange = GetBodyRange(dataRange)
どちらも同じ処理ですが、関数を使った方が「ヘッダーを除外してデータ部分を取得している」という意図が一目で分かります。
また、複数の箇所で同じ処理を書く必要がなくなるため、コードの修正も楽になります。もし処理内容を変更したくなったときは、関数の中身を1箇所修正するだけで済みます。
エラー処理の追加
実際の業務では、データ行が存在しない場合も考慮する必要があります。範囲が1行しかない場合(ヘッダーのみの場合)、そのままではResizeでエラーが発生してしまいます。
そこで、事前に行数をチェックする処理を追加します。
Function GetBodyRange(ByVal rng As Range) As Range
' 範囲が1行しかない場合はNothingを返す
If rng.Rows.Count <= 1 Then
Set GetBodyRange = Nothing
Exit Function
End If
Set rng = rng.Offset(1)
Set rng = rng.Resize(rng.Rows.Count - 1)
Set GetBodyRange = rng
End Function
Rows.Countで範囲の行数を確認し、1行以下の場合はNothingを返して処理を終了します。これでエラーを防げます。
この関数を使う側では、戻り値がNothingかどうかをチェックする必要があります。
Set bodyRange = GetBodyRange(headerRange)
If bodyRange Is Nothing Then
MsgBox "データ行がありません"
Exit Sub
End If
Is Nothingでチェックすることで、データが存在しない場合の処理を分岐できます。このようなチェックを入れておくと、予期しないエラーを防げて安心です。
まとめ
ヘッダー行を除外する処理をGetBodyRange関数として切り出すことで、コードの可読性(読みやすさ)が向上します。データ処理でよく使うパターンなので、標準モジュールに用意しておくと便利です。