スポンサーサイト 


上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

--/--/--

Category: スポンサー広告

TB: --  /  CM: --

top △

Nz の罠 


Nz 関数で、Null だったら置換える値(2番目の引数)を省略した場合、対象が、
・数値型の場合は「0」に・・・・
・テキスト型なら空文字("")に・・・・
変換されるんだそうです。

Null 自体に、数値/テキスト型ってあるんでしょうか??

Nz 関数に Null を与えて、2番目の引数が省略されていたら、Empty が返るだけだと思っていました。
この Empty は都合の良いもので、演算過程とか代入・比較先の解釈により、
数値として扱う時には「0」、文字としてなら空文字("") に置き換えられるものと思ってました。

VarType(Null) → 1 ( vbNull )
VarType(Nz(Null)) → 0 ( vbEmpty )

"123=" & Empty → "123="
1 + Empty → 1

っていう簡単なものはイミディエイトウィンドウでも確認できますね。
 
以下の内容でテーブル「T1」を作っておきます。
ani1s1
1123 
2 234
30234
※ i1:長整数、s1:テキスト(空欄部分は Null)

で、以下を記述して確認してみます。
Public Sub test()
  Dim rs As New ADODB.Recordset

  rs.Open "T1", CurrentProject.Connection, adOpenForwardOnly, adLockReadOnly
  While (Not rs.EOF)
    Debug.Print VarType(rs("i1")), rs("i1"),
    Debug.Print VarType(rs("s1")), rs("s1")
    Debug.Print VarType(Nz(rs("i1"))), Nz(rs("i1")),
    Debug.Print VarType(Nz(rs("s1"))), Nz(rs("s1"))
    Debug.Print VarType(Nz(rs("i1")) + Nz(rs("s1"))), Nz(rs("i1")) + Nz(rs("s1")),
    Debug.Print VarType(Nz(rs("s1")) + Nz(rs("i1"))), Nz(rs("s1")) + Nz(rs("i1"))
    Debug.Print VarType(Nz(rs("i1")) & Nz(rs("s1"))), Nz(rs("i1")) & Nz(rs("s1")),
    Debug.Print VarType(Nz(rs("s1")) & Nz(rs("i1"))), Nz(rs("s1")) & Nz(rs("i1"))
    rs.MoveNext
  Wend
  rs.Close
End Sub

1行目は、純な値
2行目は、Nzの戻り値(2番目の引数省略)
3行目は、演算子 + を使って・・・・記述順を変えてみる
4行目は、演算子 & を使って・・・・記述順を変えてみる

結果は以下の様になりました。
1レコード目vbLong123vbNullNull
vbLong123vbEmpty 
vbLong123vbLong123
vbString123vbString123
2レコード目vbNullNullvbString234
vbEmpty vbString234
vbString234vbString234
vbString234vbString234
3レコード目vbLong0vbString234
vbLong0vbString234
vbDouble234vbDouble234
vbString0234vbString2340

※ 本来 VarType 部分は数値ですが、わかりやすいように定数名に置き換えました。

では、次に Nz の2番目の引数を省略せずにやってみます。
Public Sub test1()
  Dim rs As New ADODB.Recordset

  rs.Open "T1", CurrentProject.Connection, adOpenForwardOnly, adLockReadOnly
  While (Not rs.EOF)
    Debug.Print VarType(rs("i1")), rs("i1"),
    Debug.Print VarType(rs("s1")), rs("s1")
    Debug.Print VarType(Nz(rs("i1"), 0)), Nz(rs("i1"), 0),
    Debug.Print VarType(Nz(rs("s1"), "")), Nz(rs("s1"), "")
'    Debug.Print VarType(Nz(rs("i1"), 0) + Nz(rs("s1"), "")), Nz(rs("i1"), 0) + Nz(rs("s1"), ""),
'    Debug.Print VarType(Nz(rs("s1"), "") + Nz(rs("i1"), 0)), Nz(rs("s1"), "") + Nz(rs("i1"), 0)
    Debug.Print VarType(Nz(rs("i1"), 0) & Nz(rs("s1"), "")), Nz(rs("i1"), 0) & Nz(rs("s1"), ""),
    Debug.Print VarType(Nz(rs("s1"), "") & Nz(rs("i1"), 0)), Nz(rs("s1"), "") & Nz(rs("i1"), 0)
    rs.MoveNext
  Wend
  rs.Close
End Sub
※ 上記、演算子 + のところはコメントに・・・・
そのまま実行すると、型が一致しない 13 のエラーになるので・・・なので、
1行目は、純な値
2行目は、Nzの戻り値(2番目の引数を指定)
3行目は、演算子 & を使って・・・・記述順を変えてみる

結果は以下の様に
1レコード目vbLong123vbNullNull
vbLong123vbString 
vbString123vbString123
2レコード目vbNullNullvbString234
vbInteger0vbString234
vbString0234vbString2340
3レコード目vbLong0vbString234
vbLong0vbString234
vbString0234vbString2340

これらの結果をみると、2番目の引数のあり/なしで、同じにならないものがある。

異なる事を知っていて・・・2番目の引数を省略する分には良いのかも?
でも、
  省略せずに記述するクセをつけた方が良いのかも・・・・

例えば、
DLookup("氏名","テーブル名","ID = " & Nz(Me.ID))

数値型 ID の氏名を得たい・・・・ Nz(Me.ID) では Null なら 0 ・・・・
じゃ・・・ないですよね。
確認した結果からすると、検索条件部分は "ID = " のままで、エラーになっていく・・・
Nz(Me.ID,0) であれば、Null なら "ID = 0" になって、該当するものがなければ Null が返ってくる。

DLookup は、コントロールソースや入力規則に記述する時もありますが、
Nz を噛ましただけでは十分じゃないのかな・・・・Null を意識してみよう。
関連記事

2013/05/22

Category: 注意しよ

TB: --  /  CM: 0

top △

この記事に対するコメント

top △

コメントの投稿

Secret

top △


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。