こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

ExcelVBAで『ByRef 引数の型が一致しません』が発生する場合と発生しない場合がある

こんばんは。
何故このような現象が発生するか判らず、
質問致します。

環境は
・WindowsXP Professional
・Excel2003
・ExcelVBA
・参照設定:Microsoft DAO 3.6 Object Library
です。

下記は抜粋した内容ですが、
レコードセットを配列で宣言し、
関数に配列として受け渡しています。

プログラムを作成途中、テストとして実行した所、
「Call test(dbWS, dbWB, dbRes)」
のdbResの所が黄色になり
「ByRef 引数の型が一致しません」
と表示されました。

初めて発生するまでは問題なく動いており、
そこに関するソースの変更をしたわけではないのに発生しました。
また、ソースを変更せず、Excelのシートの追加や削除を行った後、コンパイルを行うと発生したりもします。

その他、そのコンパイルエラーが発生した後に、ファイルを保存し、再度開くと、
再び同じエラーが出る場合と、出ない場合があり、再現性が難しい状態にあります。

色々試したところ、レコードセットを配列で関数に渡さなければ問題がなさそうで、
現在はdbWS、dbWB、dbRes(2)をグローバル変数で宣言し、
関数の引数としては受け渡さず、直接グローバル変数で値を受け渡す回避方法を取っております。

何かこの現象についてご存知の方がいれば教えて頂きたいと思います。
不足している情報がありましたら指摘下さい。

---------------------------------
Sub main()
  Dim dbWS As Workspace
  Dim dbWB As Database
  Dim dbRes(2) As Recordset

  '処理

  Call test(dbWS, dbWB, dbRes)

End Sub
---------------------------------
Private Function test(ByRef dbWS As Workspace, ByRef dbWB As Database, ByRef dbRes() As Recordset)

  '処理

End Function
---------------------------------

投稿日時 - 2009-12-06 23:51:17

QNo.5503710

暇なときに回答ください

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.3

戻り値がないんだったら Function でなくSubプロシージャで良いような気もしますけど
いや、そこはあまり関係ないところなんでしょうね。

#1回答の前に簡単なmdb読み込みのテストコードで試してみてはいましたが、やはり現象が確認できないんですよね。
DBの種類と、再現する最低限のテストコードがあれば、試せる環境の方がいらっしゃるかもしれませんが...
どうもお力になれないようです。すみません。

あと、KenKen_SPさんではないんですが、
Newキーワードに関してはひょっとしたらADOとの読み違いではないかと思うんです。
DAOでは New Recordset で新規Recordsetはつくれないのですよね。
もしかすると、DAOではなくADOを使ったほうが良いのではというアドバイスかもしれません?

投稿日時 - 2009-12-19 00:39:42

ANo.2

ぱっと見なのですが、main プロシージャで

Dim dbRes(2) As New Recordset

とか

For i=0 to 2
  Set dbRes(i) = new Recordset
Next

とか...してますか?

投稿日時 - 2009-12-09 15:14:33

補足

回答ありがとうございます。

「New」を使っているか?ということで良いでしょうか?

使っていません。

使う方が正しいのでしょうか?使わない方が正しいのでしょうか?

投稿日時 - 2009-12-12 02:08:35

ANo.1

>初めて発生するまでは問題なく動いており、
>そこに関するソースの変更をしたわけではないのに発生しました。
>また、ソースを変更せず、Excelのシートの追加や削除を行った後、コンパイルを行うと発生したりもします。
>
>その他、そのコンパイルエラーが発生した後に、ファイルを保存し、再度開くと、
>再び同じエラーが出る場合と、出ない場合があり、再現性が難しい状態にあります。
再現性が難しいというのは厄介そうですね。
中間コード?とかが関係してたりするんですかね?
http://www.h3.dion.ne.jp/~sakatsu/Excel_Tips13.htm

取り敢えず新規Bookにコードを移植して作り直しておいたほうが良いような気もします。

>関数の引数としては受け渡さず、直接グローバル変数で値を受け渡す回避方法を取っております。
という事で解決されているようなので、それはそれでいいんじゃないでしょうか。
ちょっと試してみてもいいかなと思えるのは、
Call test(dbWS, dbWB, dbRes())
...としてみたり、Function側をVariantで受けてみたり。(全然自信なし)

投稿日時 - 2009-12-07 22:30:23

補足

早速のご回答ありがとうございました。
確認に時間を取りました。

> 新規Bookにコードを移植して作り直しておいたほうが良いような気もします。

ソースはそのままで移植しましたが、同じエラーが発生しました。


> Call test(dbWS, dbWB, dbRes())

同じエラーが発生しました。


> Function側をVariantで受けてみたり。

「型が一致しません。配列またはユーザー定義型を指定してください。」
と表示されました。


> という事で解決されているようなので、それはそれでいいんじゃないでしょうか。

現在、運用上のソースは先述のままで使用しております。
特に問題なく動いてるので現実問題としてはこのままで良いと思います。
コーディング規約上グローバル変数を多用しないことが推奨されている、
及び今後のために質問を致しました。

dbresを配列の要素(dbres(0)またはdbres(1)、dbres(2))として渡す部分はエラーが発生していませんでした。
なので、

呼び出す側------------------------
Call test(dbWS, dbWB, dbRes(0), dbRes(1), dbRes(2))
----------------------------------

関数定義側------------------------
Private Function test(ByRef dbWS As Workspace, ByRef dbWB As Database, ByRef dbRes0 As Recordset, ByRef dbRes1 As Recordset, ByRef dbRes2 As Recordset)
---------------------------------

とすれば問題ないのかもしれません。
再現性が難しいので、本当にエラーにならない方法であるのかの証明ができませんが…。

投稿日時 - 2009-12-18 23:21:01

あなたにオススメの質問