はじめに
VBAのFunction
は、通常、数値や文字列といった「値」を返します。しかし、より高度な使い方として、セル範囲(Range
)やワークシート(Worksheet
)といった「オブジェクト」そのものを戻り値として返すことができます。
オブジェクトを返す関数を作成できると、「特定の条件に合致するセル範囲を探して、その範囲を返す」といった、非常に再利用性の高い部品(ツール)を作れるようになります。
この記事では、Range
オブジェクトを戻り値として返すオリジナル関数を例に、その作り方と使い方、そして重要な Set
キーワードの役割を解説します。
オブジェクトを返すFunction
のサンプルコード
この例では、指定されたワークシートの中から、データが入力されている最後のセルを探し出し、そのセル(Range
オブジェクト)を返す FindLastCell
という関数を作成します。
完成コード
' === 指定されたシートの最終セル(Rangeオブジェクト)を返すFunction ===
Function FindLastCell(targetSheet As Worksheet) As Range
Dim lastRow As Long
Dim lastCol As Long
' データが存在する最終行と最終列をそれぞれ取得
lastRow = targetSheet.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
lastCol = targetSheet.Cells.Find("*", SearchOrder:=xlByColumns, SearchDirection:=xlPrevious).Column
' Setキーワードを使って、戻り値にRangeオブジェクトを代入
Set FindLastCell = targetSheet.Cells(lastRow, lastCol)
End Function
' === 作成したFunctionを呼び出すSubプロシージャ ===
Sub Test_FindLastCell()
Dim reportSheet As Worksheet
Dim lastCell As Range
Set reportSheet = ThisWorkbook.Worksheets("Sheet1")
' --- Functionを呼び出し、戻り値のRangeオブジェクトを変数に格納 ---
' オブジェクトを受け取る際にもSetキーワードが必要
Set lastCell = FindLastCell(reportSheet)
' --- 取得したオブジェクトのプロパティを利用 ---
' lastCellはRangeオブジェクトなので、.Address や .Value などのプロパティが使える
MsgBox "最後のセルは " & lastCell.Address & " です。" & vbCrLf & _
"そのセルの値は「" & lastCell.Value & "」です。", vbInformation
' 取得したセルに色を付ける
lastCell.Interior.Color = vbYellow
End Sub
コードの解説
Function FindLastCell(...) As Range
Function
の最後に As Range
と指定することで、この関数が返す戻り値のデータ型が Range
オブジェクトであることを定義しています。As Worksheet
とすれば、ワークシートオブジェクトを返す関数になります。
Set FindLastCell = targetSheet.Cells(lastRow, lastCol)
この一行が、オブジェクトを返す Function
の最も重要なポイントです。
- 数値や文字列といった「値」を戻り値にするときは
FunctionName = 値
と書きます。 - 一方、
Range
やWorksheet
などの「オブジェクト」を戻り値にするときは、必ずSet
キーワードを付けてSet FunctionName = オブジェクト
と書く必要があります。
Set
を付け忘れると、オブジェクトそのものではなく、オブジェクトの既定のプロパティ(Range
なら.Value
)を返そうとしてしまい、型が一致せずにエラーとなります。
Set lastCell = FindLastCell(reportSheet)
Function
を呼び出して、返されたオブジェクトを受け取る側でも注意が必要です。
lastCell
はRange
型のオブジェクト変数なので、Function
から返されたRange
オブジェクトを代入する際にも、Set
キーワードが必須となります。
まとめ
今回は、VBAで Range
などのオブジェクトを返す、より高度な Function
の作り方を解説しました。
Function ... As Range
のように、戻り値の型にオブジェクト型を指定する。- 戻り値を設定する際は、
Set Function名 = オブジェクト
のように、必ずSet
キーワードを付ける。 - 呼び出し元で戻り値のオブジェクトを受け取る際も、
Set オブジェクト変数 = Function名(...)
のようにSet
が必要。
この Set
のルールさえマスターすれば、VBAでできることの幅が大きく広がります。特定の条件でセルやシートを探すような定型処理を関数化しておけば、様々なマクロから呼び出して使える、非常に強力な武器になります。