Nameオブジェクトとは
Excelには「名前付き範囲(名前の定義)」という機能があります。Range("A1:A10")のようなセル番地の代わりに、「売上リスト」のような分かりやすい名前でセル範囲を参照できる機能です。数式を作るときはもちろん、VBAから扱う場合にも、コードの可読性やメンテナンス性を高めるのに役立ちます。
この名前付き範囲をVBAから操作するのがNamesコレクションとNameオブジェクトです。この記事では、名前付き範囲の作成・参照・削除・一覧取得までを、実際に動作するサンプルコードとともに解説します。
名前付き範囲を作成する
Names.Addメソッドを使うと、VBAから名前付き範囲を新規作成できます。
Sub AddNamedRange()
ThisWorkbook.Names.Add Name:="売上リスト", RefersTo:="=Sheet1!$A$2:$A$100"
MsgBox "名前付き範囲を作成しました"
End Sub
RefersToにはシート名を含めた絶対参照($付き)でセル範囲を文字列指定します。相対参照にしてしまうと、選択しているセルによって参照先がずれてしまうため、基本的には絶対参照で指定します。
RangeオブジェクトのAddressプロパティを使うと、より安全に絶対参照の文字列を組み立てられます。
Sub AddNamedRangeFromRange()
Dim targetRange As Range
Set targetRange = Sheet1.Range("A2:A100")
ThisWorkbook.Names.Add Name:="売上リスト", RefersTo:="=" & Sheet1.Name & "!" & targetRange.Address
End Sub
名前付き範囲を参照する
作成した名前付き範囲は、Range関数にそのまま名前を渡すことで参照できます。
Sub UseNamedRange()
Dim total As Double
total = Application.WorksheetFunction.Sum(Range("売上リスト"))
MsgBox "売上リストの合計: " & total
End Sub
セル番地を直接書くよりも、「売上リストの合計を計算している」という意図がコードから読み取りやすくなります。表の行数が増減してセル範囲が変わっても、名前の参照先だけを更新すれば、名前を使っているすべてのコードや数式に反映される点も便利です。
名前付き範囲の一覧を取得する
ブック内に定義されている名前付き範囲を一覧で確認したい場合は、Namesコレクションをループします。
Sub ListAllNames()
Dim nm As Name
For Each nm In ThisWorkbook.Names
Debug.Print nm.Name & " → " & nm.RefersTo
Next nm
End Sub
このコードを実行すると、イミディエイトウィンドウにすべての名前とその参照先が一覧表示されます。他の人が作ったブックを引き継いだときなど、どんな名前が定義されているかを調べたい場合に便利です。
名前付き範囲が存在するかチェックする
存在しない名前をRange関数に渡すと実行時エラーになるため、事前にチェックしてから使うと安全です。
Function NameExists(nameToCheck As String) As Boolean
Dim nm As Name
On Error Resume Next
Set nm = ThisWorkbook.Names(nameToCheck)
On Error GoTo 0
NameExists = Not nm Is Nothing
End Function
Sub CheckAndUseName()
If NameExists("売上リスト") Then
MsgBox Range("売上リスト").Address & "が見つかりました"
Else
MsgBox "「売上リスト」という名前は定義されていません"
End If
End Sub
On Error Resume Nextでエラーを一旦無視し、Nameオブジェクトが取得できたかどうかで存在判定を行っています。
名前付き範囲を削除する
不要になった名前付き範囲はDeleteメソッドで削除できます。
Sub DeleteNamedRange()
On Error Resume Next
ThisWorkbook.Names("売上リスト").Delete
On Error GoTo 0
End Sub
存在しない名前を削除しようとするとエラーになるため、On Error Resume Nextで回避しておくと安全です。すべての名前付き範囲を一括削除したい場合は、Namesコレクションを末尾から逆順にループします。
Sub DeleteAllNames()
Dim i As Long
For i = ThisWorkbook.Names.Count To 1 Step -1
ThisWorkbook.Names(i).Delete
Next i
End Sub
コレクションを先頭からループしながら削除すると、要素が減った分だけインデックスがずれて一部の項目を処理し損ねることがあります。逆順にループするのが安全な定石です。
印刷範囲との連携(組み込みの名前)
ExcelにはPrint_Area(印刷範囲)のように、あらかじめ用途が決まっている「組み込みの名前」も存在します。これもVBAから操作できます。
Sub SetPrintAreaByName()
ThisWorkbook.Names.Add Name:="Print_Area", RefersTo:="=Sheet1!$A$1:$F$30"
End Sub
これはWorksheet.PageSetup.PrintAreaプロパティで印刷範囲を設定するのと同じ結果になりますが、Namesコレクション経由で統一的に扱えることを知っておくと、名前に関する処理をまとめて実装しやすくなります。
注意点
- RefersToの書き忘れに注意:
RefersToにシート名を含めないと、意図しないシートが参照されたり、エラーになったりすることがあります。 - 同名の名前は上書きされる:既に存在する名前に対して
Names.Addを実行すると、エラーにはならず参照先が上書きされます。新規作成のつもりが誤って上書きしていないか注意しましょう。 - スコープに注意:名前付き範囲には「ブック全体」と「特定シート内のみ」のスコープがあります。
ThisWorkbook.Namesはブックスコープ、Worksheet.Namesはシートスコープの名前を扱う点に注意してください。
まとめ
NameオブジェクトとNamesコレクションを使うと、名前付き範囲の作成・参照・削除・一覧取得をVBAから自由に操作できます。
- 作成は
Names.Add、削除はNames("名前").Delete - 一覧取得は
For Each nm In ThisWorkbook.Namesでループ - 存在確認は
On Error Resume Nextと組み合わせて安全に行う - 一括削除は末尾から逆順にループするのが定石
セル範囲に名前を付けて管理することで、数式もVBAコードも「何を参照しているか」が一目で分かるようになります。表の構造が変わりやすいブックほど、名前付き範囲を活用するメリットは大きくなります。


コメント