ブックに属する名前とシートに属する名前(2)
昨日に続き、Nameプロパティについて。教わったことや試してみたことを、いくつか備忘録として残しておく。
実験
セルに名前を付けて、その値を複数の方法・条件で参照してみる。
名前を指定してセル選択
A1に「氏名」と名付けた状態で、名前ボックスにセル番地を入力すると、A1に移動する。
名前ボックスはドロップダウンボックスなので、名前を選択することも可能。
マクロで名前を指定して値取得
上記「氏名」に「山田太郎」と入力されている場合。
「氏名」というセルの名前で「山田太郎」の値を取得する方法は、以下の二通り。
Sub NameTest() MsgBox Range("氏名").Value MsgBox ThisWorkbook.Names("氏名").RefersToRange.Value End Sub
複数の同じ名前を参照する場合の優先順位
A1の名前が「氏名」の状態で、シートをコピー。すると、コピー先のA1も「氏名」という名前になる。
- コピー元の「氏名」・・・ブックに属する名前
- コピー先の「氏名」・・・シートに属する名前
コピー先「氏名」の値を、「村岡花子」に変えてみよう。この状態で、元のシートを選択し、先ほどのマクロを実行してみる。
結果は、共に「山田太郎」が表示される。これは、何となく予想通り。
次いで、コピーしたシートがアクティブな状態で、つまり「村岡花子」が表示されている状態で、同マクロを実行する。結果は、以下の通り。
Sub NameTest() ' ↓ 「村岡花子」が表示される。 MsgBox Range("氏名").Value ' ↓ 「山田太郎」が表示される。 MsgBox ThisWorkbook.Names("氏名").RefersToRange.Value End Sub
もう一つ。
シート先に属する名前「氏名」だけを削除して、再度、同マクロを実行する。このとき、アクティブシートのA1には「村岡花子」が表示されたままである。結果は、以下の通り。
Sub NameTest() ' ↓ 「山田太郎」が表示される。 MsgBox Range("氏名").Value ' ↓ 「山田太郎」が表示される。 MsgBox ThisWorkbook.Names("氏名").RefersToRange.Value End Sub
この実験から、以下のことが分かる。
① Range("セル名称") が参照する、同じ名前の優先順位
- アクティブシートに属する名前
- ブックに属する名前
② ThisWorkbook.Names("セル名称").RefersToRange が参照する、
同じ名前の優先順位
- ブックに属する名前のみ
※↓↓---------------------公開後追記---------------------↓↓
Imiitoさんから、ご指摘いただいた(いつも有難うございます)。
ThisWorkBook.Namesの優先順位は、
- 最も左のワークシートに属する名前
- ブックに属する名前
試しにシートの並びを入れ替えたところ、↓ 以下の結果になった。
Sub NameTest() ' ↓ 「山田太郎」が表示される。 MsgBox Range("氏名").Value ' ↓ 「村岡花子」が表示される。 MsgBox ThisWorkbook.Names("氏名").RefersToRange.Value End Sub
シートの並びによって、得られる結果が正反対になってしまった。
※↑↑---------------------公開後追記---------------------↑↑
前者は、状況によって結果が自動的に変わってしまう。上手く使えば便利なのかもしれないが、意図しない結果が返ってくることもある。
使いどころとしては、例えば同じ書式のシートが複数ある場合。1シートにつき1名の社員情報を管理していて、これが複数ある場合など。
後者は、同じ名前が複数あってもブックに属する名前を参照する。意図しない名前の複製が生じていたとしても、問題なくオリジナルを参照可能となる。
※↓↓---------------------公開後追記---------------------↓↓
Imihitoさんからのご指摘により、こちらも訂正。上記(後者)は、オリジナルのシートが最も左にいる場合のみに成立する条件となる。従って、状況によって結果が自動的に変わってしまうのは、こちらも同じだった。
※↑↑---------------------公開後追記---------------------↑↑
なお、別のシートにある「シートに属する名前」を指定するには、シートも指定すれば良いようだ。
Sub NameTest() ' Sheet1の山田太郎ではなく、村岡花子が表示される MsgBox Sheets("Sheet1 (2)").Range("氏名").Value End Sub
結論
それぞれの方法に、メリットとデメリットあり。
その特性を正しく理解し、正しく活用しよう。
なんて書いておきながら、忘れたころに、自分もうっかり失敗しそうです。
参考まで。