S-JIS[2002-04-21/2008-08-17] 変更履歴

FormulaとValueの関係


セルに値を入れる動作をマクロ化してみると

Sub Macro1()
'
' Macro1 Macro
' マクロ記録日 : 2002 4 21  ユーザー名 : ひしだま
'

'
    Range("B2").Select
    ActiveCell.FormulaR1C1 = "a"
End Sub

となります。 このFormulaR1C1とは何か?
マクロ化したときの動作からして、セルに値を設定する指定だということは明白ですが、 妙な名称ですよね。

実は似た機能として、他にFormula,Valueというものがあります。

    Range("A1").FormulaR1C1 = "a"
    Range("B1").Formula = "a"
    Range("C1").Value = "a"
    Range("D1").FormulaR1C1Local = "a"
    Range("E1").FormulaLocal = "a"

実行してシートを見てみれば分かる通り、結果の違いはありません(爆)

まぁ違いが無いのは固定値を入れているからなんですけど(笑)
次のような違いがあります。

プロパティ値の取得値の設定Local付き更新日
FormulaR1C1数式をR1C1方式で返す数式をR1C1方式で設定 使用環境(の言語)独自の関数名などで数式を使用
日本語環境だけで使うなら関係無し
 
Formula数式をA1方式を返す 数式を設定
Value数式の計算結果を返す数式を設定-  
Textセルの書式に従った文字列を返す- -2006-06-16

Excelでは、セルを指定する方法に、A1方式とR1C1方式という2種類あります。
A1方式はおなじみで、Range("A1")というように使い、A1セルを直接指定します。
これに対しR1C1方式は、自分のセルからの相対位置を「ROW方向にいくつCOL方向にいくつで表す」 という指定の仕方をします。

    Range("A2").FormulaR1C1 = "=R[-1]C[0]"
    Range("B2").Formula = "=B1"
    Range("C2").Value = "=C1"

いずれも、自分自身のセルの1つ上のセルの値を参照する式です。

値の設定時では、FormulaR1C1方式にはR1C1方式でなければならない以外は、 いずれの方式を使っても自動的に判別してくれるようです。

Sub Macro2()
    Range("A4").Value = "a"
    Range("B4").Value = "b"
    Range("C4").Value = "c"
    Range("A5").FormulaR1C1 = "=R[-1]C"
    Range("B5").Formula = "=R[-1]C"
    Range("C5").Value = "=R[-1]C"
    Range("A6").FormulaR1C1 = "=A5"
    Range("B6").Formula = "=B5"
    Range("C6").Value = "=C5"
End Sub

上記のマクロを実行すると、A6セルだけエラーになっているのが見られます。

また、その後に、A5〜C6セルのいずれかをアクティブにして

Sub アクティブセルの内容表示()
    With ActiveCell
	MsgBox .Formula & Chr(13) & _
	    .FormulaR1C1 & Chr(13) & _
	    .Value
    End With
End Sub

というマクロを実行すれば、同一内容のセルなのに、Formula・FormulaR1C1・Valueが それぞれ違うものを返すことが分かります。


Formulaに値が入っているかどうかはHasFormulaを使えば分かります。[2008-08-17]

	Debug.Print Range("A1").HasFormula

FormulaLocalは、 使用環境独自(すなわち日本においては日本固有)の関数を使う場合に意味が分かります。[2006-06-16]
例えばJIS()という半角文字を全角文字に変換する関数は日本固有でしょう。これを試してみると、FormulaLocalでは使えますがFormulaではエラーになります。

	With Sheets(1)
		.Cells(1, 1).Value = "ABC"
		.Cells(2, 1).FormulaLocal = "=JIS(""ABC"")"
		.Cells(3, 1).Formula = "=JIS(""ABC"")" 	'←JIS()が見つからなくてエラーになる
	End With
  A B
1 ABC  
2 ABC  
3 #NAME?  
4    

この場合でもA3セルに関数自体は登録されているので、A3セルでF2を押してそのままEnterを押して再計算させると、ちゃんとした文字が表示されます。


最後に
値として使用する場所でFormula等を省略した場合は、Valueが指定されたものと解釈されます。

    Range("A2") = "=A1"
    MsgBox Range("A2")

    ↓

    Range("A2").Value = "=A1"
    MsgBox Range("A2").Value

自分は、プログラマーが誤解しない為に Valueは書いておいた方がいいと思う。
本来、Range(〜)の結果はRange型のオブジェクトであり、 値を使用する場所(MsgBoxや代入文)で使ったので そのRangeオブジェクトのValueが使われているに過ぎない。
例えば「Union(Range("A1"),Range("B2"))」の場合、値を使用しているわけではない。 「Union(Range("A1").Value,Range("B2").Value)」などという意味ではなく、もし そう書いたら実行時エラーになる。
こういった違いを明確にする為に、値として使用している場合はValueを付けるべきと考える。


マクロの記録の加工へ戻る / Excelへ戻る / 技術メモへ戻る
メールの送信先:ひしだま