tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板 [ツリー表示へ]   [Home]
一括表示(VB6.0)
タイトル該当レコードが存在しない場合にRecordcount=1と返される
記事No15938
投稿日: 2014/07/10(Thu) 14:09
投稿者山田
SQLを実行後のRecordcountの値についてご指導お願い致します。

VB6.0とACCESS2000にて10数年ぶりに過去の遺産を修正しております。

SELECT MAX(hoge) FROM A_TABLE WHERE 〜

これを実行すると、
該当レコードが存在する場合には正しい結果が返ってきました。
そして、.Fields(0).Value にて正しい結果 MAX(hoge) が得られました。

分からないのは、該当レコードが存在しない場合にもRecordcount=1と返される事です。
該当レコードがなければ=0(とかマイナス値?)になるような気がするのですが…
当然、.Fields(0).Value にはNullが入りますので、値は取得できません。

なぜ1が入るのか、そもそもRecordcountを判断材料にするのは間違っているのか?
ご指導の程よろしくお願い致します。

[ツリー表示へ]
タイトルRe: 該当レコードが存在しない場合にRecordcount=1と返される
記事No15939
投稿日: 2014/07/10(Thu) 20:47
投稿者魔界の仮面弁士
> VB6.0とACCESS2000にて10数年ぶりに過去の遺産を修正しております。
お疲れ様です……!!

> そもそもRecordcountを判断材料にするのは間違っているのか?
基本的には、RecordCount プロパティを使用するべきではありません。

ここで具体的な理由について言及することは避けますが、ざっくり言えば
レコードの存在確認なら EOF プロパティを用いるべきですし、
総件数を求めるなら、COUNT 集計関数を用いる方が望ましいです。


> 該当レコードが存在しない場合にもRecordcount=1と返される事です。
ここで重要なのは「該当レコード」ではなく「結果レコード」です。

今回は、『集計関数』を使っているため、集計対象のデータが 0 件であっても、
集計結果のレコードは生まれることになります。

取得した Recordset において、.EOF と .BOF のプロパティが共に True であるならば、
.RecordCount プロパティが返す値は 0 となります。

しかし .EOF と .BOF のいずれかが False の場合、少なくともその Recordset は
1 行以上のデータを含んでいることになります。(たとえば null 値しか持たない行であっても)

本当に 0 行にしてみたいのであれば、検索するクエリーの最後に
『 HAVING MAX(hoge) IS NOT NULL 』を加えてみて下さい。
今度は .RecordCount が 1 を返さなくなるでしょうし、また、
.Fields(0).Value から値が返されることも無くなるはずです。
(Access のクエリデザイナで、両方の実行結果を比較してみて下さい)


> 該当レコードがなければ=0(とかマイナス値?)になるような気が
ちなみに、総レコード数をカウントしないタイプのカーソルの場合は、
実際のデータ数に関係なく、RecordCount = -1 となりえます。ご注意あれ。

[ツリー表示へ]
タイトルRe^2: 該当レコードが存在しない場合にRecordcount=1と返される
記事No15941
投稿日: 2014/07/10(Thu) 22:41
投稿者山田
魔界の仮面弁士様、ご回答有難うございます。

> > そもそもRecordcountを判断材料にするのは間違っているのか?
> 基本的には、RecordCount プロパティを使用するべきではありません。

了解です。根本的な間違いをしておりました。

> ここで具体的な理由について言及することは避けますが、ざっくり言えば
> レコードの存在確認なら EOF プロパティを用いるべきですし、
> 総件数を求めるなら、COUNT 集計関数を用いる方が望ましいです。

hogeの中での最大値を取得するのが目的でした。
その為に 0<Recordcount であれば.Fields(0).Valueを覗くつもりでした。
結果、IsNull(.Fields(0).Value)で判定してみました。

> 今回は、『集計関数』を使っているため、集計対象のデータが 0 件であっても、
> 集計結果のレコードは生まれることになります。

言われてみれば仰るとおりですね!結果レコードが格納されるレコードですものね!

> 『 HAVING MAX(hoge) IS NOT NULL 』を加えてみて下さい。
> 今度は .RecordCount が 1 を返さなくなるでしょうし、また、
> .Fields(0).Value から値が返されることも無くなるはずです。

確かに、HAVING〜を加えると、.Recordcount=0となり、
.Fields(0).Valueには格納されなくなりました!

求めるべきはhoge中の最大値。昔の私はMAXすら使わずに恥ずかしいコードを書いております…

「プログラムは思った通りに動かない。書いた通りに動く。」という言葉が思い出されました。
ありがとうございます。

[ツリー表示へ]
タイトルRe: 該当レコードが存在しない場合にRecordcount=1と返される
記事No15940
投稿日: 2014/07/10(Thu) 21:38
投稿者茶々丸
主に RecordCount プロパティの事について、質問しているようですが SQLの方が気になったので、ちょっと、口出しさせてもらいます。

以下のSQLですが、該当レコードの有無に関わらず、必ず1件返します。
> SELECT MAX(hoge) FROM A_TABLE WHERE 〜

もしかしたら、以下のSQLだと思ったような動作になるのではないでしょうか?
SELECT NZ(MAX(hoge),0) FROM A_TABLE WHERE 〜

見当違いでしたら、御免なさい。

[ツリー表示へ]
タイトルRe^2: 該当レコードが存在しない場合にRecordcount=1と返される
記事No15942
投稿日: 2014/07/10(Thu) 22:55
投稿者山田
茶々丸様、ご回答有難うございます!

ご指導頂きましたSQL文を実行したところ、「式に未定義関数 'NZ' があります」と出ました。
どうやらNZ関数はAccess2010とAccess2007が対象の様です。申し訳ありませんでした。

[ツリー表示へ]
タイトルRe^3: 該当レコードが存在しない場合にRecordcount=1と返される
記事No15943
投稿日: 2014/07/11(Fri) 10:02
投稿者魔界の仮面弁士
> ご指導頂きましたSQL文を実行したところ、「式に未定義関数 'NZ' があります」と出ました。
> どうやらNZ関数はAccess2010とAccess2007が対象の様です。申し訳ありませんでした。
Nz 関数そのものは、Access 2000 や Access 97 などにもありますが、いずれにせよ、
Microsoft Access 上でのみ使える関数で、VB6 からは利用できません。

茶々丸さんの紹介された SQL に相当する問い合わせを行うのであれば、
 SELECT IIF(ISNULL(MAX(hoge)), 0, MAX(hoge)) FROM A_TABLE WHERE 〜
のようにすれば OK です。
VB6 の IIf 関数とは異なり、Jet SQL の IIF 関数は短絡評価であることに注意して下さい。



ちなみに、Access 上からの利用であった場合には、
>> SELECT MAX(hoge) FROM A_TABLE WHERE 〜
というSQL を発行する代わりに、
 value = Application.DMax("hoge", "A_TABLE", 抽出条件)
という VBA コードで最大値を取得できたりします。蛇足までに。

[ツリー表示へ]
タイトルRe^4: 該当レコードが存在しない場合にRecordcount=1と返される
記事No15945
投稿日: 2014/07/11(Fri) 16:35
投稿者山田
魔界の仮面弁士様、ご指導ありがとうございます。

ACCESS上で「NZ」関数の動作を確認する事が出来ました。ありがとうございます。

>  value = Application.DMax("hoge", "A_TABLE", 抽出条件)
> という VBA コードで最大値を取得できたりします。蛇足までに。

これをVBA上でを実行したところ、これまた簡単に希望の結果を得ることが出来ました。

昔、VBは使っていましたが、VBAは初めて使いました。
非常に勉強になります!ありがとうございます。

[ツリー表示へ]
タイトルRe^2: 該当レコードが存在しない場合にRecordcount=1と返される
記事No15944
投稿日: 2014/07/11(Fri) 16:29
投稿者山田
茶々丸様、ご指導ありがとうございます。

魔界の仮面弁士にご指導頂き、茶々丸様にご指摘頂きました「NZ」関数の動作を確認する事が出来ました。
Access上で実行したところ、希望の数値が得られました!ありがとうございます。

[ツリー表示へ]