Home » Excel VBA Rangeオブジェクト » RangeでValueを省略するとよくない事例

RangeでValueを省略するとよくない事例

対象:Excel2003, Excel2007, Excel2010, Excel2013

RangeオブジェクトでValueプロパティを省略するとよくない事例

VBA(Visual Basic for Applications)でExcelマクロを作るときに、もっともよく利用するのはRangeオブジェクトでしょう。

RangeプロパティやCellsプロパティを使ってRangeオブジェクトを取得して、セルのデータを変更したりするのは、Excelマクロの基本中の基本です。

このRangeオブジェクトの値を操作するときに、Valueプロパティを明示的に指定する派の人と、指定しない派の人がいます。

例えば、アクティブブックのアクティブシートのA1セルに「合格」という文字列を入力するには
 Range("A1").Value = "合格"
 Cells(1, 1).Value = "合格"
 Range("A1") = "合格"
 Cells(1, 1) = "合格"
といった書き方があります。

前半2つはValueプロパティを明確に指定してデータを代入していて、後半2つはVBAにどのプロパティなのかの判断を任せてValueプロパティにデータを代入してもらっています。

私がどちらなのか、というとValueプロパティを指定する派です。

Valueプロパティを指定するほうが、可読性が上がりますし、変な不具合に悩まされる可能性も減るためです。

[スポンサードリンク]

RangeオブジェクトのデフォルトプロパティはValueではない

Valueプロパティを省略した場合にValueプロパティとして扱われる現象を、「ValueプロパティがRangeオブジェクトの既定プロパティだから」といった説明をしている書籍やWebがありますが、これは間違いです。

オブジェクトブラウザで確認すればすぐわかることです。

オブジェクトブラウザで、RangeオブジェクトのValueプロパティを確認すると、下図のように既定プロパティのアイコンとはなっておらず、詳細ペインにもそのような記述はありません。

RangeオブジェクトでValueプロパティを省略するとよくない事例

Rangeオブジェクトでは、_Defaultプロパティに既定プロパティのアイコンが表示され、詳細ペインにもそのとおり記述されています。(_Defaultプロパティが表示されていない場合は、オブジェクトブラウザ内で右クリックして表示されるショートカットメニューで[非表示のメンバーを表示]をOnにしてください)

RangeオブジェクトでValueプロパティを省略するとよくない事例

Rangeオブジェクトの既定のプロパティは、あくまでも_Defaultプロパティなのです。

RangeオブジェクトでValueプロパティを指定しないときにValueプロパティとして扱われるのは、オブジェクトブラウザから明確な仕様として読み取ることはできません。経験則としてValueプロパティとして扱われることがもちろん多いですが。

Valueプロパティを省略したときの不具合

Valueプロパティを省略したときには、不具合が出る可能性もあるということを認識しておく必要があります。

Valueプロパティを指定しないことで発生する不具合の、具体的な例をあげておきます。

セルに入力されているデータに一括して文字列を追加したいといったことは、実務ではあります。そんなときに使えるマクロもご紹介しています。

例えば、選択されていたセルの文字列の前に「id」という文字列を追加したいときに、マクロを作らずイミディエイトウィンドウから実行する場合、Valueプロパティを指定しない派の人なら
 for each rng in selection: rng = "id" & rng: next
と書くはずです。

残念ながらこのコードでは、このコードでは選択されていたセルの文字列の前に「id」という文字を追加することはできません。特にエラーメッセージも表示されません。

Valueプロパティまで指定した
 for each rng in selection: rng.value = "id" & rng.value: next
というコードを実行すると、選択されていたセルの文字列の前に「id」という文字を追加することがちゃんとできます。

これは、イミディエイトウィンドウから実行したから発生する現象ではありません。

ちゃんとしたSubプロシージャの形にした
 Sub 文字列追加()
  Dim rng
  For Each rng in Selection
   rng = "id" & rng
  Next
 End Sub
でも、やはりダメで、Valueプロパティを指定した
 Sub 文字列追加()
  Dim rng
  For Each rng in Selection
   rng.Value = "id" & rng.Value
  Next
 End Sub
ならちゃんと動きます。

このことは、Microsoftの技術情報文書「Can't Set Value Property in For Each with Variant Type」にも書かれています。この現象を回避するためには上記のようにValueプロパティを明確に指定するか、変数の型宣言をしてやることが必要です。

RangeオブジェクトでValueプロパティを省略する場合、本当は書くのが正しいのだということを知った上で省略しているということをしっかり認識し、このような不具合が発生する可能性もあることを覚悟しておく必要があります。(というか、コードも読みやすくなるんだから、書きましょうよ.Valueくらい)

[スポンサードリンク]

Home » Excel VBA Rangeオブジェクト » RangeでValueを省略するとよくない事例

「Excel VBA Rangeオブジェクト」の記事一覧

検索


Copyright © インストラクターのネタ帳 All Rights Reserved.

.