• 締切済み

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 ---------------------------------

みんなの回答

  • end-u
  • ベストアンサー率79% (496/625)
回答No.3

戻り値がないんだったら Function でなくSubプロシージャで良いような気もしますけど いや、そこはあまり関係ないところなんでしょうね。 #1回答の前に簡単なmdb読み込みのテストコードで試してみてはいましたが、やはり現象が確認できないんですよね。 DBの種類と、再現する最低限のテストコードがあれば、試せる環境の方がいらっしゃるかもしれませんが... どうもお力になれないようです。すみません。 あと、KenKen_SPさんではないんですが、 Newキーワードに関してはひょっとしたらADOとの読み違いではないかと思うんです。 DAOでは New Recordset で新規Recordsetはつくれないのですよね。 もしかすると、DAOではなくADOを使ったほうが良いのではというアドバイスかもしれません?

  • KenKen_SP
  • ベストアンサー率62% (785/1258)
回答No.2

ぱっと見なのですが、main プロシージャで Dim dbRes(2) As New Recordset とか For i=0 to 2   Set dbRes(i) = new Recordset Next とか...してますか?

Miyabi__
質問者

補足

回答ありがとうございます。 「New」を使っているか?ということで良いでしょうか? 使っていません。 使う方が正しいのでしょうか?使わない方が正しいのでしょうか?

  • end-u
  • ベストアンサー率79% (496/625)
回答No.1

>初めて発生するまでは問題なく動いており、 >そこに関するソースの変更をしたわけではないのに発生しました。 >また、ソースを変更せず、Excelのシートの追加や削除を行った後、コンパイルを行うと発生したりもします。 > >その他、そのコンパイルエラーが発生した後に、ファイルを保存し、再度開くと、 >再び同じエラーが出る場合と、出ない場合があり、再現性が難しい状態にあります。 再現性が難しいというのは厄介そうですね。 中間コード?とかが関係してたりするんですかね? http://www.h3.dion.ne.jp/~sakatsu/Excel_Tips13.htm 取り敢えず新規Bookにコードを移植して作り直しておいたほうが良いような気もします。 >関数の引数としては受け渡さず、直接グローバル変数で値を受け渡す回避方法を取っております。 という事で解決されているようなので、それはそれでいいんじゃないでしょうか。 ちょっと試してみてもいいかなと思えるのは、 Call test(dbWS, dbWB, dbRes()) ...としてみたり、Function側をVariantで受けてみたり。(全然自信なし)

Miyabi__
質問者

補足

早速のご回答ありがとうございました。 確認に時間を取りました。 > 新規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) --------------------------------- とすれば問題ないのかもしれません。 再現性が難しいので、本当にエラーにならない方法であるのかの証明ができませんが…。

関連するQ&A

  • Excel VBA ByRef引数の型?

    Excel2010でセルに関数式を埋め込むマクロを書いています。 そこで、「ByRef引数の型が一致しません」というエラーが出て困っています。 プログラムの中からエラーの出る所だけを取り出してtest1,test2として試したところ、 test1はエラーが出て、test2はプログラムが動いて目的とするセルに関数式が挿入されました。 Sub test1() dim i, myR as integer myR = 30 For i = 7 To 31 Cells(4, i) = "=IF(" & ConvertToLetter(i) & i - 4 & "="""","""",SUM(" & ConvertToLetter(i) & "5:" & ConvertToLetter(i) & myR & ")/(" & myR & "-COUNTIF(" & ConvertToLetter(i) & "5:" & ConvertToLetter(i) & myR & ","""")))" next i End Sub test1でConvertToLetter(i)のiが青色で選択され「ByRef引数の型不一致」エラーとなってしまいます。 そこで、試しに一度変数iの値をkに渡して同じプログラムをtest2として実行してみました。 Sub test2() dim i, k, myR as integer myR = 30 For i = 7 To 31 k=i Cells(4, i) = "=IF(" & ConvertToLetter(k) & i - 4 & "="""","""",SUM(" & ConvertToLetter(k) & "5:" & ConvertToLetter(k) & myR & ")/(" & myR & "-COUNTIF(" & ConvertToLetter(k) & "5:" & ConvertToLetter(k) & myR & ","""")))" next i End Sub このtest2は、きちんと実行され、目的とするG4(~AE4)のセルに =IF(G3="","",SUM(G5:G30)/(30-COUNTIF(G5:G30,""))) という式が挿入されました。 質問1:なぜ、test1がダメで、test2ならうまくいくのかという理由がわかりません。 質問2:うまくいったtest2と同じ式を、もっと長いプログラムの中に入れるとやはり「ByRef引数の型が一致しません」エラーが出てプログラムが止まってしまいます。test2単独のプログラムならうまく動くのに、他のプログラムの一部に埋め込むとエラーが出る理由もわかりません。 VBAプログラムを試行錯誤しながら勉強している初心者です。どなたかご教示お願いします。 ちなみに、ConvertToLetterは、 Function ConvertToLetter(iCol As Integer) As String Dim iAlpha As Integer Dim iRemainder As Integer iAlpha = Int((iCol - 1) / 26) iRemainder = iCol - (iAlpha * 26) If iAlpha > 0 Then ConvertToLetter = Chr(iAlpha + 64) End If If iRemainder > 0 Then ConvertToLetter = ConvertToLetter & Chr(iRemainder + 64) End If End Function という、関数で定義しています。

  • 「ByRef引数の型が一致しません」助けてください。

    お世話になります。 現在VBAでHTMLの書き出し用プログラムを書いています。 書き出したHTMLをUTF-8に変換するため、 ■UTF-8ファイル作成 for VBA http://www.vector.co.jp/soft/dl/winnt/prog/se320375.html のクラスモジュールを利用させていただいております。 Sub testAで定義した内容を書き出すために、 Sub createTestでtestA fNum(i)とした場合、 「ByRef引数の型が一致しません」と怒られてしまいます…。 単数の生成であれば、testA f1で生成可能なのですが、 生成ファイルが複数あり、配列に格納して処理したいのです。 どなたかお力をお貸しください。 プログラムの知識はほぼ素人レベルですorz 宜しくお願いします。 ▼コード Option Explicit Public Sub createTest() Dim fNum As Variant Dim f1 As New TextFile, f2 As New TextFile, f3 As New TextFile, f4 As New TextFile, f5 As New TextFile, f6 As New TextFile Dim f7 As New TextFile, f8 As New TextFile, f9 As New TextFile, f10 As New TextFile, f11 As New TextFile, f12 As New TextFile Dim f13 As New TextFile, f14 As New TextFile, f15 As New TextFile, f16 As New TextFile, f17 As New TextFile Dim Header As String, BodyS_T As String, BodyS_L As String, GlNavi As String, Promo As String, Contents As String, PrNavi As String, SeNavi As String, Footer As String, BodyE As String Dim ContentsM As String, ContentsS As String Dim WBK As Workbook Dim SH2 As Worksheet Dim TplBox As Variant Dim createCurPath As String Dim i As Integer Set WBK = ThisWorkbook Set SH2 = WBK.Sheets(2) createCurPath = ThisWorkbook.path & "\" & UserForm1.TextBox1.Value fNum = Array(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17) '<HEADER> Header = "Header" '<BODY-START> BodyS_T = "BodyS_T>" BodyS_L = "BodyS_L" '<GLOBAL NAVI> GlNavi = "GlNavi" '<PROMO> Promo = "Promo" '<CONTENTS> Contents = "Contents" ContentsM = "ContentsM" ContentsS = "ContentsS" '<PRIMRY NAVi> PrNavi = "PrNavi" '<SECONDARY NAVI> SeNavi = "SeNavi" '<FOOTER> Footer = "Footer" '<BODY-END> BodyE = "BodyE" For i = 0 To 16 If i = 0 Then fNum(i).FileCreate createCurPath & "\index.html", "UTF-8" ElseIf UserForm1("TextBox" & i + 1).Value <> "" Then fNum(i).FileCreate createCurPath & "\" & UserForm1("TextBox" & i + 1).Value & "\index.html", "UTF-8" End If fNum(i).TextWriteLine Header If i = 0 Then fNum(i).TextWriteLine BodyS_T ElseIf UserForm1("TextBox" & i + 1).Value <> "" Then fNum(i).TextWriteLine BodyS_L End If TplBox = SH2.Range("C" & i + 3).Value If TplBox <> "" Or TplBox <> "選択" Then If InStr(TplBox, "-TA-") > 0 Then testA fNum(i) fNum(i).TextWriteLine Promo fNum(i).TextWriteLine PrNavi ElseIf InStr(TplBox, "-TB-") > 0 Then testA fNum(i) fNum(i).TextWriteLine "<hr />" ElseIf InStr(TplBox, "-TC-") > 0 Then fNum(i).TextWriteLine ContentsS End If End If fNum(i).FileClose Next i End Sub Public Sub testA(f As TextFile) f.TextWriteLine "テスト1" End Sub

  • String だと「 ByRef引数の型が一致しません 」というエラーが出ます。なぜ?

    ここで「Kaplan-Meyer 生存分析に便利なソフトを教えて」と質問した shuu_01 です。ここで VisualBasic のソースのありかを教えて頂き、自分に使いやすいようソースを書き換えようと奮闘中です(それまで VisualBasic の経験がなく 無謀!と実感中です)。 元々のソースはグラフが1本だけだったので、肺癌だと「腺癌」「扁平上皮癌」「小細胞癌」、、といろんな癌の種類別にグラフを数本 書くのが目標です。そこで、 Sub km_test() Dim nc As Integer, gr() As String nc = 2 ReDim gr(nc) gr(0) = "腺癌" gr(1) = "扁平上皮癌" gr(2) = "小細胞癌" km_group_test nc, gr End Sub Sub km_group_test(nc As Integer, gr As String) End Sub というソースを書くと: String の変数 gr の色が変わり、「 ByRef引数の型が一致しません 」というエラーが出ます。 Integer の変数 nc ではエラーが出ません。 きちんと型を一致させているつもりなのに、なぜ???

  • VBで、型が一致しません、というエラーがでます

    下記のcodingが、コンパイルエラー 「型が一致しません:配列またはユーザー定数型を  指定してください。」 とエラーがでます myFileDump3()という関数を作り test、から、それを呼び出しています myFileDump3(ary1)のary1がエラーとして指摘されます WindowXPでACCESSのVBです Function test() Dim ary1(3, 3) As Long ary1(1, 1) = 11: ary1(1, 2) = 12: ary1(1, 3) = 13 ary1(2, 1) = 21: ary1(2, 2) = 22: ary1(2, 3) = 23 ary1(3, 1) = 31: ary1(3, 2) = 32: ary1(3, 3) = 33 myFileDump3 (ary1) End Function '--------------------------------------------- Function myFileDump3(ary1() As Long)    ・    ・    ・    ・

  • 配列の参照渡しで型が一致しません。

    エクセル2003です。 いつもお世話になります。 以下のコードを実行すると「配列の型が一致しません。」というエラーが出ます。 typeNameで確認しても配列の型はvariant()で正しいと思うのですが。。。 皆様のお知恵を拝借させていただけないでしょうか。 -------------------------------------- Sub main() Dim e As Variant e = fuN() Call pRo(e)  '←ここでエラーになる。 End Sub Function fuN() As Variant Dim a(0) As Variant a(0) = "zero" fuN = a End Function Sub pRo(ByRef c() As Variant) '処理っす End Sub --------------------------------------

  • [Excel2000_VBA] 型が一致しませんメッセージが表示

    各サイトを調べたのですが、自分のレベルに合った解答内容がなくよく理解できなかったので、質問させて頂きます(初歩的な質問で申し訳ありません) ユーザー定義を使用し、以下のコードを作ってみました。 配列を引数にして、まとめて返したいと考えていますが、構造体を使用すると「型が一致しません」と表示されてしまいます。 何が原因しているのでしょうか? さっぱり分かりませんので、ご教示お願いいたします。 Type test aaaa As Integer End Type Sub sbTest() Dim myAns() As test myAns = Sample1(myAns) End Sub Function Sample1(ByRef Ans() As test) Dim i As Integer Dim ret(0 To 9) As test For i = 0 To 9 ret(i).aaaa = i Next Ans = ret '配列名で配列を戻り値 End Function

  • ACCESSの宣言

    Private Sub コード_AfterUpdate() Dim Mdb As Database Dim Mtb As Recordset Dim sqlstr As String って、始めに宣言しますが、いざプログラムを走らせてみると、Dim Mdb As Database で "コンパイルエラー ユーザー定義型は定義されていません" になってしまいます。ここでひっかかるともうどうにもできないです。 なぜ、この宣言はいけないのでしょうか?

  • 関数の引数と型

    関数の引数と型 TextBoxに数字しか入力できないようにする関数として Private Function fTextBoxNumberCheck(Byval MyTextBox as TextBoX)As Boolean という宣言文を目にしました。 Q1. Byval MyTextBox これは関数の呼び出し側では実引数としてText1,Text2のようなオブジェクト自体を 渡すことができるということでしょうか? 私の読んでいる入門書では実引数は変数ばかりなので・・・。 Q2. as TextBox これは入門書によれば実引数のデータ型となっていますが 調べてもTextBoxという型はありませんでした。 宣言文は関数のサンプルとして、その前後は記載されていませんでしたが、 どこかにTextBoxの宣言をしてあるはず(?)なのでしょうか? Yesとすればどのように書くのでしょうか?

  • VB6で配列を引数にするときの2通りの方法について

    VB6で引数に配列を渡す方法が2通りあるよう?ですが以下のような配列があり、渡し方によって引数の定義の仕方が異なると思うのですが、(2)番目の関数の書き方が知りたいです。 dim ary_dat(10) as integer (1)test_A( ary_dat ) は、sub test_A( byref ary() as integer)という関数を作れば動作することはわかりましたが、 (2)test_B( ary_dat(0) ) は、関すでどのような引数を定義すればできるのでしょうか?

  • Excel VBA配列をFunctionに渡す

    こんばんは、引数について教えてください。 Excel VBAの関数を作っていましたが、 1.Function ColumnArrayの部分でコンパイルエラーが発生し、  「配列がありません」と表示されます。  引数を配列のみで渡した場合、問題なく渡せるようですが、  他の引数と、CriteriaArrsの配列と一緒に渡せないのでしょうか。  すべて配列として1つにまとめて渡さなければならないのでしょうか。 2.CriteriaArrs = Array("田中", "鈴木")の部分は、文字列の増減が発生しますので  配列はParamArray  CriteriaArrs()とした方がよいのでしょうか 説明が不足している点があるかもしれませんが宜しくお願いいたします。 Function ColumnArray(SheetName As Worksheet, _ StartCell As Range, _ FieldColumn As Long, _ CountColumn As Long, _ CriteriaArrs As Variant _ ) As Long ・・・ End Function ------------------------------------- sub test() Dim CriteriaArrs() As Variant Dim SheetA As WorkSheet DIm RangeA range CriteriaArrs = Array("田中", "鈴木") set SheetA =Worksheet(1) set RangeA=Range("B3") FilterCount = ColumnArray(SheetA, RangeA, 3, 2, CriteriaArrs) end sub

専門家に質問してみよう