VBでDCOUNTを使用するには?

解決


はづき  URL  2002-12-18 15:28:34  No: 76664  IP: [192.*.*.*]

はじめまして
現在VB6とACCESS2000を用いてデータベースアプリを組んでいます
その中でDCOUNTという関数を使用してクエリーを作ったところ
「式に未定義関数'DCOUNT'があります」
のエラーで蹴られてしまいました

アクセスの中では無事クエリーはできています
まったく同じSQLをVB上で書き、レコードセットを作るとエラーが出ます
もちろん先にアクセス上にクエリを作成して、そのクエリをレコードセットに取り込んでもエラーになります

DCOUNTはVBでは使えないのでしょうか?
ご教授お願いします

編集 削除
とろ  2002-12-18 15:54:46  No: 76665  IP: [192.*.*.*]

VB5+Access97 の環境では、
VB から DCount 関数を使用したクエリを
正しく実行することができました。

どのようなクエリを実行しているのですか?

# まさか、 VB6 や Access2k だから
# ダメっていうことはないでしょう...

編集 削除
はづき  2002-12-18 16:26:42  No: 76666  IP: [192.*.*.*]

とろさんお返事ありがとうです

作成したいクエリはわけあって結構複雑です
(本人がそう思ってるだけかもしれないのは事実かもしれない)
作成したテーブルとクエリの簡易版を以下に記述させていただきます
テーブル:TBL明細
コード・氏名・商品コード・購入価格
001   Aさん  005      500
003   Bさん  003      400
008   Cさん  005      200
001   Aさん  001      200
テーブル:TBL商品
商品コード・商品名
101       商品1
103       商品2
105       商品3
107       商品4
というテーブルを用いてお客様がどの商品をいくら買ってるかを出すクエリを作成します(クロス集計クエリ)
ここがちとわけありな部分で、その時フィールド名に商品コードか商品名をつければいいのですがどうしても連番でなくてはなりません

最終目的のクエリは↓です
コード・氏名・合計 ・ 1 ・ 2 ・ 3 ・ 4 ・ 5
001     Aさん 700   200       500
003     Bさん 400        400     
008     Cさん 200             200         

そのままで連番は無理と判断したので一度以下のクエリを作成しました

SELECT TBL明細.コード, TBL明細.氏名, TBL明細.商品コード, TBL明細.購入価格
DCount("TBL明細","TBL商品","商品コード <= " & 商品コード) AS 商品連番
FROM TBL明細

そうするとサクセスの上で無事目的の中間のクエリが出ました
コード・氏名・商品コード・購入価格・商品連番
001   Aさん  005      500         3
003   Bさん  003      400         2          
008   Cさん  005      200         3
001   Aさん  001      200         1
これでクロス集計を作成するとクエリはできました
安心してVBからレコードセットオブジェクトへ読み込もうとすると
エラーが発生します
普通の選択クエリー(SELECT  FROM  WHEREの構成)は普通に処理してくれます
わかりにくい説明ですけどこんな感じです
こういう使い方はできないのでしょうか?

編集 削除
魔界の仮面弁士  2002-12-18 16:29:20  No: 76667  IP: [192.*.*.*]

DCount関数とは、正確には、Access.Applicationオブジェクトの
DCountメソッドの事を指しています。

つまり「DCOUNT関数」は、Jetの関数ではなく、Accessが提供している
ものであるため、Access以外(VB等)では、それをSQL中に埋め込んで
利用する事はできません。

編集 削除
はづき  2002-12-18 16:35:04  No: 76668  IP: [192.*.*.*]

魔界の仮面弁士さん
ということはこれは無理なのでしょうか?
まだ未熟でよくわからないこと多数ですが
DAOで使用できないということですよね?
なにかうまくこのクエリを作成する方法というのはあるでしょうか?

2日かけて考えたのに使えないんじゃ、ふに落ちないというか・・・
質問ばかり申し訳ありません

編集 削除
はづき  2002-12-18 16:38:35  No: 76669  IP: [192.*.*.*]

簡易版を記述したときに
商品は4種しかないのにフィールドは5まで書いてしまいました
これは間違いです・・・
商品が4種ならフィールドも4までになります・・・
あと最終目的のクエリの1・2・3・4は
商品テーブルの1番目のレコードから最終レコードまで対応しています

編集 削除
魔界の仮面弁士  2002-12-18 17:53:21  No: 76670  IP: [192.*.*.*]

> ということはこれは無理なのでしょうか?
VBからAccessをオートメーションで呼び出し、そちらに開かせれば可能です。
実行環境にMicrosoft Accessが必要になってしまいますけれどね。

> DAOで使用できないということですよね?
DAOというよりも、呼び出し側(ホスト)の問題だったりします。
ちなみに、たとえAccessであっても、レジストリの設定
(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\SandBoxMode)
を変更されたら、利用できなくなってしまいます。

> なにかうまくこのクエリを作成する方法というのはあるでしょうか?
う〜ん。よいSQLが思い浮かびません。

ADOであれば、Standalone-Recordsetや hierarchical-Recordsetで
対処するという事もできますが…DAOの場合は、一旦、ワークテーブルに
吐き出してしまった方が楽かも知れません。(回答になっていませんね…)

編集 削除
とろ  2002-12-18 17:57:28  No: 76671  IP: [192.*.*.*]

Dim sSQL as String
sSQL = ""
sSQL = sSQL & "select コード, 氏名, 商品コード, 購入価格,"
sSQL = sSQL & "       DCount(""*"", ""TBL商品"", ""商品コード <= '"" & 商品コード & ""'"") as 商品連番"
sSQL = sSQL & "from TBL明細"

このクエリを DAO で実行できませんか?

編集 削除
とろ  2002-12-18 17:58:08  No: 76672  IP: [192.*.*.*]

★ 上の訂正

Dim sSQL as String
sSQL = ""
sSQL = sSQL & " select コード, 氏名, 商品コード, 購入価格,"
sSQL = sSQL & "        DCount(""*"", ""TBL商品"", ""商品コード <= '"" & 商品コード & ""'"") as 商品連番"
sSQL = sSQL & " from TBL明細"

このクエリを DAO で実行できませんか?

編集 削除
魔界の仮面弁士  2002-12-18 18:18:43  No: 76673  IP: [192.*.*.*]

Access VBA や Excel VBA上からDAOを実行している分には、
実行できると思います。が、VBからでは呼び出せない可能性が高いかと。

# インストールされているJetが、セキュリティパッチを適用していない
# バージョンであれば、VBからでも実行できる可能性はありますが。。。

編集 削除
魔界の仮面弁士  2002-12-18 18:45:57  No: 76674  IP: [192.*.*.*]

ちなみに当方で実験したら、こんな感じになりました。
DCountが見つからない…というエラーが表示されています。
(なお、SandBoxモードは 0 に設定してあります。)http://www.ocv.ne.jp/~oratorio/junk/image/DCountOfVB.JPG

VB: VS6 Enterpirse/SP5
OS: WinXP Pro/SP1 with Q327696, Q329048, Q329115, Q329834
JET: Version 4.0 Service Pack 6
DAO: Version 3.60 ビルド3714.5

# ただし、Excel 2000 VBAおよびAcess 2000 VBAからでは、
# 全く同じコードで実行できました。

編集 削除
はづき  2002-12-18 19:14:35  No: 76675  IP: [192.*.*.*]

検討ありがとうございました
もう少し考えてみます

とろさん>>
私もはっきりとは認識していませんが
魔界の仮面弁士さんのおっしゃるとおり
VBからは使用不可能のようです
環境は魔界の仮面弁士さんとOSが2000かXPかの違いくらいなので

いい結果が出ましたら報告いたしますが
力業になりそうでいやだなぁ(^^;

編集 削除
とろ  2002-12-19 10:22:24  No: 76676  IP: [192.*.*.*]

なぜ、私の環境は実行できてしまうのでしょう...

はづきさんの提示したデータで [TBL明細] と [TBL商品] を作成。
※ [TBL明細].[商品コード] に関しては、恐らく記述間違いだったと思うので、
   001, 003, 005 -> 101, 103, 105 と修正して作成しました。
環境
OS      : WinNT4.0(SP6)
VB      : VB5(SP3)
Access  : Access97(SR2)
JET     : 4.00.6019.00
DAO     : 3.51.1608.0
SandBox : 2

'* コード(参照設定は Microsoft DAO 3.51 Object Library のみ追加)
Option Explicit
Private Sub Command1_Click()
  Dim daoDbe  As DAO.DBEngine
  Dim daoWs   As DAO.Workspace
  Dim daoDb   As DAO.Database
  Dim daoRs   As DAO.Recordset
  Dim sSQL    As String
  Dim i       As Integer
  sSQL = ""
  sSQL = sSQL & " select コード, 氏名, 商品コード, 購入価格,"
  sSQL = sSQL & "        DCount(""*"", ""TBL商品"", ""商品コード <= '"" & 商品コード & ""'"") as 商品連番"
  sSQL = sSQL & " from TBL明細"
  Set daoDbe = New DAO.DBEngine
  Set daoWs = daoDbe.Workspaces(0)
  Set daoDb = daoWs.OpenDatabase(App.Path & "\db1.mdb")
  Set daoRs = daoDb.OpenRecordset(sSQL)
  Do While daoRs.EOF = False
    For i = 0 To daoRs.Fields.Count - 1
      Debug.Print daoRs.Fields(i).Value,
    Next i
    Debug.Print
    daoRs.MoveNext
  Loop
  daoRs.Close
  daoDb.Close
  daoWs.Close
  Set daoRs = Nothing
  Set daoDb = Nothing
  Set daoWs = Nothing
  Set daoDbe = Nothing
End Sub

'* 実行後のイミディエイトウィンドウ
001  Aさん  105  500  3
001  Aさん  101  200  1
003  Bさん  103  400  2
008  Cさん  105  200  3

編集 削除
魔界の仮面弁士  2002-12-19 11:32:32  No: 76677  IP: [192.*.*.*]

> JET     : 4.00.6019.00
> DAO     : 3.51.1608.0
DAO 3.5xは、JET 4.0のDLLを利用しません。
使われるのは、JET 3.5系DLLですね。

> SandBox : 2
それ自体は、デフォルトの値ですね。
それは、JET 3.5のSandBoxですか? それとも、4.0?
http://support.microsoft.com/default.aspx?scid=kb;ja;239104
http://support.microsoft.com/default.aspx?scid=kb;ja;239482

編集 削除
とろ  2002-12-19 12:15:57  No: 76678  IP: [192.*.*.*]

> 使われるのは、JET 3.5系DLLですね。

失礼しました (_ _;)
でも、 3.5 も 4.0 も両方 SandBox は 2 でした。

う〜ん ;;; 不思議ですねぇ...

編集 削除
とろ  2002-12-19 12:17:10  No: 76679  IP: [192.*.*.*]

★ 上の方の記述の訂正

SandBox -> SandBoxMode

編集 削除
はづき  2002-12-19 13:05:34  No: 76680  IP: [192.*.*.*]

結局JETだと不可であり
DAO3.5とAC97の時にはできるんでしょうかね

編集 削除
魔界の仮面弁士  2002-12-19 22:32:13  No: 76681  IP: [192.*.*.*]

私の方では、Access 97/2000製 MDBのそれぞれに対し、
  DAO 3.51
  DAO 3.60
  Microsoft OLE DB Provider for Microsoft JET 3.51
  Microsoft OLE DB Provider for Microsoft JET 4.0
のそれぞれにて試してみましたが、いずれもVBからでは
DCOUNTを使用することができませんでした。

編集 削除
とろ  2002-12-20 08:59:21  No: 76682  IP: [192.*.*.*]

自宅のPCで実行したところ、
家でも実行できてしまいました。

WinMe + Access2k + VB5

結論:
VB5 か VB6 かっていうことが
原因でしょうか...???
# そんなまさか?

編集 削除
とろ  2002-12-20 09:02:58  No: 76683  IP: [192.*.*.*]

★ 上の投稿撤回
(なかったことにして下さい。)

編集 削除
とろ  2002-12-20 09:51:40  No: 76684  IP: [192.*.*.*]

RDO や ADO を使って mdb に接続した所、
RDO の OpenResultset の所でエラーが発生しました。

実行時エラー '40002'
07001:[Microsoft][ODBC Microsoft Access Driver]
パラメータが少なすぎます。4を指定して下さい。

# 関係あるのかな?

Private Sub Test_RDO()
  Set rdoCn = New RDO.rdoConnection
  With rdoCn
    .Connect = "DBQ=C:\db1.mdb;Driver={Microsoft Access Driver (*.mdb)};"
    .EstablishConnection
  End With
  Set rdoRs = rdoCn.OpenResultset(sSQL)
  '* 以下略
End Sub

Private Sub Test_ADO()
  Set adoCn = New ADODB.Connection
  adoCn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\db1.mdb;"
  Set adoRs = New ADODB.Recordset
  adoRs.Open sSQL, adoCn, adOpenStatic, adLockOptimistic
  '* 以下略
End Sub

編集 削除
魔界の仮面弁士  2002-12-20 11:34:37  No: 76685  IP: [192.*.*.*]

そういえば、RDOは試していませんでしたね。

> パラメータが少なすぎます。4を指定して下さい。
ODBCエラー"07001:Wrong number of parameters."が発生すると
いう事は、SQL中に、ODBCドライバが認識不可能なキーワードが
含まれていたため、それをパラメータクエリとして認識してしまった
可能性があります。上記の場合、少なくとも4つのパラメータが
存在していたと思われているのかと。


ちなみに当方ではこんな感じ。やはりDCOUNTが認識できないようです。

ソースはこちら。(RDOを利用するので、Enterprise Editionが必要です)
http://www.ocv.ne.jp/~oratorio/junk/draft/DCountOfRDO.txt

VB_Num=『 40002 』
VB_Src=『MSRDO20.DLL』
VB_Msg=『37000: [Microsoft][ODBC Microsoft Access Driver] 式に未定義関数  'DCOUNT' があります。』
==========
rdoNum=『-3102 』
rdoSrc=『ODBC』
rdoSta=『37000』
rdoRCD=『一般的な実行時エラー』

編集 削除
とろ  2002-12-20 12:21:14  No: 76686  IP: [192.*.*.*]

魔界の仮面弁士さんのソースで実行したら、次のようになりました。

VB_Num=『 40002 』
VB_Src=『MSRDO20.DLL』
VB_Msg=『07001: [Microsoft][ODBC Microsoft Access Driver] パラメータが少なすぎます。4 を指定してください。』
==========
rdoNum=『-3010 』
rdoSrc=『ODBC』
rdoSta=『07001』
rdoRCD=『一般的な実行時エラー』

私だけ DAO や ADO で実行できてしまうのは腑に落ちませんが、
『実行できない可能性が極めて高いということで、
  DCount 関数は VB で使わないようにした方が良い』
という結論でよろしいですね。

# 最初の質問者に代わって、解決にチェックを付けました。
# ご了承下さい。 (_ _) ペコリ

編集 削除
とろ  2002-12-20 12:25:37  No: 76687  IP: [192.*.*.*]

★ チェックし忘れてしまったので、
改めて、チェック!!

編集 削除