VBAでは変数やフィールドに値が無い状態を表すキーワードが、Null・Empty
Nothing・""(ZeroLengthString/長さ0の文字列)と、いくつも存在します。
今回はそれぞれのキーワードの意味と相違点、使用上の注意について説明し
ていきます。
● 詳細 ●
【Null】
その変数やフィールドに有効なデータが格納されていないことを示します。
別の言い方をすると、明示的にNullを代入された変数や、フィールド・コント
ロールが完全に未定義の状態を示します。ですから数値の0やスペースはNullで
はありません。なぜなら0やスペースという「値」が定義されているからです。
なお、変数の場合Null値を格納できるのはVariant型だけです。
変数やフィールド・コントロールにNull値が取得されるのは、変数に明示的
にNullを代入した時や、Null値を含む計算を行った時、未入力のフィールド・
コントロールです。特に、データとバインドしていない(非連結)コントロール
のフィールドがNullであることを覚えておくと、役に立ちます。
また、Nullは0と同じように計算相手をNullにしてしまうのですが、Nullが未
定義状態を示すことを理解していれば、話は簡単。未定義の要素を含む式(計算)
の結果が未定義状態(=Null)になるのは当然ですね。
なお、C言語のNullとVBのNullは若干違う部分があり、Win32APIの呼び出しの
際などにCの長さ0の文字列タイプのNullを使う時には「vbNullChar」を使用し
ます。
変数やフィールド・コントロールがNull値を含んでいるかをチェックするに
は、IsNull関数を使用します。
----------------------------------------
Dim Var As Variant
Var = Null
Debug.Print IsNull(Var)
----------------------------------------
この例ではVariant型の変数VarにNullを明示的に代入した後、IsNull関数で
調査していますので、イミディエイトウィンドウには「True」が表示されます。
注意しなくてはいけない点は、決して「If Var = Null」や「If Var <> Null」
という形で比較してはいけないということです。なぜなら、他の状況ではTrue
と評価される式でも、Nullを含む式では式全体がFalseになってしまい、Falseと
評価されてしまうからです。
【Empty】
Variant型の変数に格納される特殊な値の1つであり、変数が初期化されてい
ないことを表すキーワードです。
しかし、数値型の変数ではEmptyは「0」と評価され、文字列型の変数では
Empty値は「""(長さ0の文字列)」と評価されるため、明示的にVariant型を宣言
した変数以外ではなかなかお目にかかる機会も無いでしょう。
ただ、数値型 (日付/時刻型もシリアル値という数値で管理されていますので、
大きな意味での数値型です) や文字列型は、デフォルトで「0」や「""」が与え
られているのではなく、VBAのコンパイラが型宣言を判断して自動的に値を代入
しているのだ、ということを覚えておいたほうが良いでしょう。
変数がEmptyであるかどうかをチェックするためには、IsEmpty関数を使用し
ます。
----------------------------------------
Dim Var As Variant
Debug.Print IsEmpty(Var)
----------------------------------------
この例ではVariant型の変数Varが初期化されないままIsEmpty関数によって調
査されていますので、イミディエイトウィンドウには「True」が表示されます。
【Nothing】
Object型の変数に格納される特殊な値であり、Object型の変数が特定のオブ
ジェクトと関係付けられていないことを表します。通常はSetステートメントと
同時に使われ、Object型の変数と特定のオブジェクトとの関係を無効にするた
めに使われます。
----------------------------------------
Set MyObject = Nothing
----------------------------------------
Object方の変数にNothingを代入したときに、ほかの変数がそのオブジェクト
を参照していなければ、それまでに参照していたオブジェクトに割り当てられ
ているすべてのシステムリソースとメモリが解放されます。この処理は、必ず
モジュールの適用範囲(スコープ)内で行う習慣を付けておきましょう。
複数のオブジェクト変数が同じオブジェクトを参照している場合、Setステー
トメントを使ってすべての変数に明示的にキーワードNothingを設定するか、ま
たはNothingに設定した最後のオブジェクト変数が、暗黙のうちに適用範囲 (ス
コープ) 外になった後でなければ、各変数が参照するオブジェクトに関連付け
られたメモリとシステムリソースは解放されません。
変数がNothingであるかどうかを確認するためには、オブジェクト変数を比較
するための演算子、Isを使って以下のように判別します
----------------------------------------
If obj Is Nothing Then
Set Obj = Fomrs![フォーム1]
End If
----------------------------------------
この例では、Object型変数Objが特定のオブジェクトと関連付けられていない
場合は、Objにフォーム1を割り当てています。
【""(長さ0の文字列)】
文字を1つも含まない文字列 ("") です。文字列型変数の場合、前述のように
初期値がこの長さ0の文字列になります。レコードセットの場合は対象がテキス
ト型のフィールドであっても、明示的に長さ0の文字列を代入しない限りNullと
評価されます。
------------------------------------------------------------
Dim Rst As DAO.Recordset
Set Rst = CurrentDb.OpenRecordset("Select * From テーブル1")
Rst.MoveFirst
Debug.Print Rst![フィールド1]
Rst![フィールド1].Edit
Rst![フィールド1] = ""
Rst![フィールド1].Update
Debug.Print Rst![フィールド1]
------------------------------------------------------------
上のフィールド1が未入力の場合、イミディエイトウィンドウには最初「Null」
が表示されます。しかし、明示的に「""(長さ0の文字列)」を代入したあとは空
白が表示されるようになります。ただ、フィールドのAllowZeroLength/空文字
列の許可プロパティをTrueにしておかないと、このサンプルはエラーが出ます。
【最後に】
このように、変数やフィールド・コントロールが空であることを示すキーワー
ドが何種類も存在します。特に「Null」と「""(長さ0の文字列)」の区別は重要
です。同じテキスト型のフィールドの場合でも、レコードセットの場合とレコー
ドとバインド(連結)したコントロールの場合、フィールドの値を代入した変数
の場合で得られる結果が違うことなど、慣れと注意が必要です。
|