はじめまして
現在VB6とACCESS2000を用いてデータベースアプリを組んでいます
その中でDCOUNTという関数を使用してクエリーを作ったところ
「式に未定義関数'DCOUNT'があります」
のエラーで蹴られてしまいました
アクセスの中では無事クエリーはできています
まったく同じSQLをVB上で書き、レコードセットを作るとエラーが出ます
もちろん先にアクセス上にクエリを作成して、そのクエリをレコードセットに取り込んでもエラーになります
DCOUNTはVBでは使えないのでしょうか?
ご教授お願いします
VB5+Access97 の環境では、
VB から DCount 関数を使用したクエリを
正しく実行することができました。
どのようなクエリを実行しているのですか?
# まさか、 VB6 や Access2k だから
# ダメっていうことはないでしょう...
とろさんお返事ありがとうです
作成したいクエリはわけあって結構複雑です
(本人がそう思ってるだけかもしれないのは事実かもしれない)
作成したテーブルとクエリの簡易版を以下に記述させていただきます
テーブル: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の構成)は普通に処理してくれます
わかりにくい説明ですけどこんな感じです
こういう使い方はできないのでしょうか?
DCount関数とは、正確には、Access.Applicationオブジェクトの
DCountメソッドの事を指しています。
つまり「DCOUNT関数」は、Jetの関数ではなく、Accessが提供している
ものであるため、Access以外(VB等)では、それをSQL中に埋め込んで
利用する事はできません。
魔界の仮面弁士さん
ということはこれは無理なのでしょうか?
まだ未熟でよくわからないこと多数ですが
DAOで使用できないということですよね?
なにかうまくこのクエリを作成する方法というのはあるでしょうか?
2日かけて考えたのに使えないんじゃ、ふに落ちないというか・・・
質問ばかり申し訳ありません
簡易版を記述したときに
商品は4種しかないのにフィールドは5まで書いてしまいました
これは間違いです・・・
商品が4種ならフィールドも4までになります・・・
あと最終目的のクエリの1・2・3・4は
商品テーブルの1番目のレコードから最終レコードまで対応しています
> ということはこれは無理なのでしょうか?
VBからAccessをオートメーションで呼び出し、そちらに開かせれば可能です。
実行環境にMicrosoft Accessが必要になってしまいますけれどね。
> DAOで使用できないということですよね?
DAOというよりも、呼び出し側(ホスト)の問題だったりします。
ちなみに、たとえAccessであっても、レジストリの設定
(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\SandBoxMode)
を変更されたら、利用できなくなってしまいます。
> なにかうまくこのクエリを作成する方法というのはあるでしょうか?
う〜ん。よいSQLが思い浮かびません。
ADOであれば、Standalone-Recordsetや hierarchical-Recordsetで
対処するという事もできますが…DAOの場合は、一旦、ワークテーブルに
吐き出してしまった方が楽かも知れません。(回答になっていませんね…)
Dim sSQL as String
sSQL = ""
sSQL = sSQL & "select コード, 氏名, 商品コード, 購入価格,"
sSQL = sSQL & " DCount(""*"", ""TBL商品"", ""商品コード <= '"" & 商品コード & ""'"") as 商品連番"
sSQL = sSQL & "from TBL明細"
このクエリを DAO で実行できませんか?
★ 上の訂正
Dim sSQL as String
sSQL = ""
sSQL = sSQL & " select コード, 氏名, 商品コード, 購入価格,"
sSQL = sSQL & " DCount(""*"", ""TBL商品"", ""商品コード <= '"" & 商品コード & ""'"") as 商品連番"
sSQL = sSQL & " from TBL明細"
このクエリを DAO で実行できませんか?
Access VBA や Excel VBA上からDAOを実行している分には、
実行できると思います。が、VBからでは呼び出せない可能性が高いかと。
# インストールされているJetが、セキュリティパッチを適用していない
# バージョンであれば、VBからでも実行できる可能性はありますが。。。
ちなみに当方で実験したら、こんな感じになりました。
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からでは、
# 全く同じコードで実行できました。
検討ありがとうございました
もう少し考えてみます
とろさん>>
私もはっきりとは認識していませんが
魔界の仮面弁士さんのおっしゃるとおり
VBからは使用不可能のようです
環境は魔界の仮面弁士さんとOSが2000かXPかの違いくらいなので
いい結果が出ましたら報告いたしますが
力業になりそうでいやだなぁ(^^;
なぜ、私の環境は実行できてしまうのでしょう...
はづきさんの提示したデータで [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
> 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
> 使われるのは、JET 3.5系DLLですね。
失礼しました (_ _;)
でも、 3.5 も 4.0 も両方 SandBox は 2 でした。
う〜ん ;;; 不思議ですねぇ...
★ 上の方の記述の訂正
SandBox -> SandBoxMode
結局JETだと不可であり
DAO3.5とAC97の時にはできるんでしょうかね
私の方では、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を使用することができませんでした。
自宅のPCで実行したところ、
家でも実行できてしまいました。
WinMe + Access2k + VB5
結論:
VB5 か VB6 かっていうことが
原因でしょうか...???
# そんなまさか?
★ 上の投稿撤回
(なかったことにして下さい。)
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
そういえば、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=『一般的な実行時エラー』
魔界の仮面弁士さんのソースで実行したら、次のようになりました。
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 で使わないようにした方が良い』
という結論でよろしいですね。
# 最初の質問者に代わって、解決にチェックを付けました。
# ご了承下さい。 (_ _) ペコリ
★ チェックし忘れてしまったので、
改めて、チェック!!