ADOのExecuteメソッドで交互にエラーが出る

このQ&Aのポイント
  • ExcelでADO+ODBCを用いてローカルのMySQLにアクセスしています。とあるサイトから参考にさせてもらって作成した以下のソースで、シート上のボタンをクリックしたらODBCに設定したDSNのテーブル一覧をシートに出力するというマクロなのですが、実行してみると正常終了とエラーが交互に繰り返されます。
  • エラーが出るときにデバッグしてみると標準モジュールのSet adoRS = adoCON.Execute("SHOW TABLES;")を実行した時点でエラー(赤丸の×でエラー説明なし)がでて強制終了します。
  • この原因について心当たりがありましたら教えてください。
回答を見る
  • ベストアンサー

ADOのExecuteメソッドで交互にエラーが出る

こんにちは。 ExcelでADO+ODBCを用いてローカルのMySQLにアクセスしています。 とあるサイトから参考にさせてもらって作成した以下のソースで、 シート上のボタンをクリックしたら ODBCに設定したDSNのテーブル一覧をシートに出力 するというマクロなのですが、実行してみると正常終了とエラーが交互に繰り返されます。 エラーが出るときにデバッグしてみると標準モジュールの Set adoRS = adoCON.Execute("SHOW TABLES;") を実行した時点でエラー(赤丸の×でエラー説明なし)がでて強制終了します。 この原因について心当たりがありましたら教えてください。 ****シートモジュール**** Private dsn As String Private uid As String Private pwd As String Private strsql As String Sub para_get() dsn = Range("C6") uid = Range("C7") pwd = Range("C8") strsql = Range("C9") End Sub Sub ボタン1_Click() Dim errflag As Integer errflag = 0 Call para_get errflag = DBconnect(dsn, uid, pwd) If errflag <> 0 Then MsgBox "データベースに接続できませんでした" Else MsgBox "データベースに接続できました" End If errflag = sql_exe End Sub *****標準モジュール****** Dim adoCON As New ADODB.Connection Public Function DBconnect(dsn As String, uid As String, pwd As String) Dim errflag As Integer errflag = -1 On Error GoTo errflag 'Access VBA Tips '4.5 MySQLのデータベースを開く・閉じる 'ADOでデータソースをオープン adoCON.Open "dsn=" & dsn & ";uid=" & uid & ";pwd=" & pwd & ";" errflag = 0 Exit Function errflag: 'データベースのクローズ adoCON.Close Set adoCON = Nothing End Function Function sql_exe() As Integer Dim adoRS As New ADODB.Recordset 'レコードセットの作成(SELECT文の実行) Set adoRS = adoCON.Execute("SHOW TABLES;") Range("B15").CopyFromRecordset adoRS 'データベースのクローズ adoRS.Close Set adoRS = Nothing End Function

noname#198479
noname#198479

質問者が選んだベストアンサー

  • ベストアンサー
  • Siegrune
  • ベストアンサー率35% (316/895)
回答No.2

うまくいってよかったですね。 >ボタン1_Click()ではなくsql_exe() の方ですよね? これは、いまのソースでは、どちらでも問題ないです。 とにかくボタン1_Click()の処理が終わる前にcloseしてください との趣旨でした。 On Error GoTo 0 の説明の前に On Error GoTo errflag とは、エラーがおきたときに errflag: 以下の処理をしなさいという命令です。 で、resume nextでエラーが起きた次の命令へ処理を戻すとか。 exit subやexit functionで、処理を終了させるとかします。 (今回はend functionなので、exit functionと同様かな。) ということで、 On Error GoTo 0 は、エラーが起きたときにどこへも制御を移さずにエラーを表示させる(つまりは普通の)状態に 戻す命令です。 今回の場合、 On Error GoTo errflag の後に adoCON.Open "dsn=" & dsn & ";uid=" & uid & ";pwd=" & pwd & ";" errflag = 0 Exit Function しかないので、ま、いいといえばいいのでしょうが、 例えば、errflagが日付型になっていたりすると(ソースを見る限りありえないですが) errflag = 0 でエラーが起きたのに、errflag:へいってclose処理してfunctionを終わるという動きになり 想定外の動きをしてしまうことになります。⇒バグの元になりやすいというだけです。 追伸: 私が、「お行儀悪い」って書いているのは、直さなくてもプログラムソースの書き方に よってはうまくいくこともあるのだが、バグの元になりやすい書き方に対して言っているだけで、 他意はないです。 (未熟者とか言っているつもりはないのですが誤解されたようでしたらすいません。)

その他の回答 (2)

  • 30246kiku
  • ベストアンサー率73% (370/504)
回答No.3

ご質問への回答は出ていますので、以下は余談(補足)的なものとしてください。 提示された記述が全コードだとした場合、 ・Function の戻り値が設定されていない  (暗黙の 0 しか戻らないので、特に DBconnect後の、接続失敗は通らない)  DBconnectは戻り値の型を明示(宣言)していないので、Variant  値を設定していないので Empty  Empty を Integer で解釈すると 0( Empty を String で解釈すると "" )  sql_exeでは、戻り値の型を Integer 宣言  戻り値は、初期値 0 に設定されるが sql_exe = XX していないので 0 のまま ・sql_exe を標準モジュールに置くのなら、SQL/Rangeを固定した書き方にしない ・シート側では、直接 ADO 用の変数を参照しない  (必要なら関数経由とする:適宜関数を作る) 2つ目、3つ目については、私はそう思うっていうだけです。 以下たたき台にしてみてください。(環境が無いので、動作未検証) (行儀についてはわかりません) 標準モジュールに以下 Dim adoCON As ADODB.Connection Public Sub DBdisConnect()   On Error Resume Next   If (adoCON Is Nothing) Then Exit Sub   If (adoCON.State = adStateOpen) Then adoCON.Close   Set adoCON = Nothing End Sub Public Function DBconnect(dsn As String, uid As String, pwd As String) As Integer   Dim errflag As Integer   errflag = 0   On Error GoTo ERR_HND   Call DBdisConnect   ' 念のため   Set adoCON = New ADODB.Connection   adoCON.Open "dsn=" & dsn & ";uid=" & uid & ";pwd=" & pwd & ";" ERR_EXIT:   DBconnect = errflag   Exit Function ERR_HND:   errflag = -1   Call DBdisConnect   Resume ERR_EXIT End Function Public Function sql_exe(sSql As String, rng As Range) As Integer   Dim adoRS As ADODB.Recordset   Dim errflag As Integer   errflag = 0   On Error GoTo ERR_HND   Set adoRS = adoCON.Execute(sSql)   rng.CopyFromRecordset adoRS   adoRS.Close ERR_EXIT:   Set adoRS = Nothing   sql_exe = errflag   Exit Function ERR_HND:   errflag = -1   If (Not adoRS Is Nothing) Then adoRS.Close   Resume ERR_EXIT End Function シート側に以下 Private dsn As String Private uid As String Private pwd As String Private strsql As String Private Sub para_get()   dsn = Range("C6")   uid = Range("C7")   pwd = Range("C8") '  strsql = Range("C9")   strsql = "SHOW TABLES;" End Sub Sub ボタン1_Click()   Call para_get   If (DBconnect(dsn, uid, pwd) = 0) Then     If (sql_exe(strsql, Range("B15")) <> 0) Then       MsgBox "データ取得でエラー"     End If     Call DBdisConnect   Else     MsgBox "データベースに接続できませんでした"   End If End Sub とか Sub ボタン1_Click()   Call para_get   If (DBconnect(dsn, uid, pwd) = 0) Then     Call sql_exe(strsql, Range("B15"))     Call DBdisConnect   Else     MsgBox "データベースに接続できませんでした"   End If End Sub

  • Siegrune
  • ベストアンサー率35% (316/895)
回答No.1

>実行してみると正常終了とエラーが交互に繰り返されます。 一回目は正常終了ですか?それともエラーですか? ★1回目 Sub ボタン1_Click() Dim errflag As Integer errflag = 0 Call para_get errflag = DBconnect(dsn, uid, pwd) '★★★ここで、adoCON.Openが行われる。 If errflag <> 0 Then MsgBox "データベースに接続できませんでした" Else MsgBox "データベースに接続できました" End If errflag = sql_exe '★★★ここでは、adoCONはcloseしていない。 End Sub ★2回目 Sub ボタン1_Click() Dim errflag As Integer errflag = 0 Call para_get errflag = DBconnect(dsn, uid, pwd) '★★★ここで、adoCON.OpenをしようとしてすでにOPEN状態なのでエラー。 '★★★エラー処理でadoCON.closeされる。 If errflag <> 0 Then MsgBox "データベースに接続できませんでした" Else MsgBox "データベースに接続できました" End If '★★★"データベースに接続できませんでした"とでていると思いますが! errflag = sql_exe '★★★ここで、adoCONがclose状態なのでエラー!!! End Sub と動いていそうですが。 ●Openしたままなのはお行儀悪いです。 Sub ボタン1_Click() の最後で、 adoCON.Close Set adoCON = Nothing をしましょう。 ●On Error Gotoの使い方もお行儀悪いです。 思わぬ処理が走る原因になりかねません。 On Error GoTo errflag 'Access VBA Tips '4.5 MySQLのデータベースを開く・閉じる 'ADOでデータソースをオープン adoCON.Open "dsn=" & dsn & ";uid=" & uid & ";pwd=" & pwd & ";" On Error GoTo 0 '正常に処理が終わったら元に戻す。 errflag = 0 Exit Function errflag: On Error GoTo 0 'エラー処理が呼び出されても元に戻す。 'データベースのクローズ adoCON.Close Set adoCON = Nothing End Function ●接続失敗して後続処理を実行するのはよろしくありません。 If errflag <> 0 Then MsgBox "データベースに接続できませんでした" exit sub '★処理を終了する!!! Else

noname#198479
質問者

補足

回答ありがとうございます。 未熟者で行儀の悪いソースですいません。 >●Openしたままなのはお行儀悪いです。 Sub ボタン1_Click() の最後で、 adoCON.Close Set adoCON = Nothing をしましょう。 ボタン1_Click()ではなくsql_exe() の方ですよね? adoCONをcloseしてたと思ったらエラーのときしかcloseされてないですね。。。 closeしたらうまくいきました。 (ちなみにエラーは2回目の時です。) >●On Error Gotoの使い方もお行儀悪いです。 思わぬ処理が走る原因になりかねません。 On Error GoTo 0 は初めて見ましたがこの処理はどういうときに 必要なのでしょうか?実際、使用していなくても うまく動作しており、引用元にもこのような 記載はなかったので教えていただけると嬉しいです。

関連するQ&A

  • EXCELからORACLEのテーブルをselectしたいのですが、うま

    EXCELからORACLEのテーブルをselectしたいのですが、うまくいきません。 ご指導のほどお願いいたします。 下記サンプルをネット('Access VBA Tips)で探し実行しました。 Access版だからいけないのでしょうか? adoCON.Open "DSN=company_viewer; UID=jxxx; PWD=yjxxx;" のオープン・クローズは正常終了します。 Set adoCON = Application.CurrentProject.Connection が実行できません。 実行時エラー 438 オブジェクトはこのプロパティまたはメソッドをサポートしていません。 が出てしまいます。 Excelではだめなのでしょうか? 教えてください。 よろしくお願いいたします。 ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー--------------- Sub prcAdoOracleODBC() 'Access VBA Tips '4.3 ORACLEのDBを開く・閉じる/ODBCを使う Dim adoCON As New ADODB.Connection Dim adoRS As ADODB.Recordset '?ADOを使いADRSODBCというデータソースをオープンします adoCON.Open "DSN=company_viewer; UID=jxxx; PWD=yjxxx;" 'データベースのオープン(データベースオブジェクトの作成) Set adoCON = Application.CurrentProject.Connection 'レコードセットの作成(SELECT文の実行) Set adoRS = adoCON.Execute("select * from casUR") 'レコードセットのクローズ adoRS.Close 'データベースのクローズ adoCON.Close 'オブジェクト変数のクリア Set adoRS = Nothing Set adoCON = Nothing End Sub

  • PostgresのViewをExcelのVBAでレコード取得できない

    はじめまして。mady1234と申します。 Postgresを利用した社内ツールを作成しています。 Postgresのテーブルからレコード取得は出来ますが、Viewからの取得が出来ません。エラーが発生します。 実行時エラー'-2147467259(8004005)': 環境はサーバーはVine4.2 Postgres8.3 クライアントのOSはXP Excelは2003です。 色々と検索しましたが、テーブルのレコード取得の方法はあってもビューは見つけれませんでした。 ご教授の程、宜しくお願いいたします。 --------------------------以下、VBAの記述です-------------------  Dim row1,col1, as integer row1=1 col1=1 Dim adoCON As New ADODB.Connection Dim adoRS As ADODB.Recordset Set adoCON = New ADODB.Connection adoCON.CommandTimeout = 0 adoCON.ConnectionString = "DSN=PostgreSQL30;" & _ "uid=postgres;" & _ "pwd=;" adoCON.Open Set adoRS = New ADODB.Recordset adoRS.Source = " SELECT * from View1;" adoRS.ActiveConnection = adoCON adoRS.CursorType = adOpenKeyset adoRS.LockType = adLockOptimistic adoRS.Open Do Until adoRS.EOF Worksheets("sheet1").Cells(row1, col1).Value = adoRS!usuryou adoRS.MoveNext row1 = row1 + 1 Loop adoRS.Close adoCON.Close Set adoRS = Nothing Set adoCON = Nothing

  • SQLの条件に変数を

    はじめまして。よろしくお願いします select文のwhere条件にidを指定したいのですがうまくいきません。 べつに変数を使用しなくてもよいのですが良い方法がありましたらご教授下さい Private Sub コマンド8_Click() Dim adoCON As ADODB.Connection Dim adoRS As ADODB.Recordset Dim no As interger no=me.id Set adoCON = Application.CurrentProject.Connection Set adoRS=adoCON.Execute("select varcodeno from varcode_tbl where id=no")strName = adoRS!varcodeno adoRS.Close adoCON.Close Set adoRS = Nothing Set adoCON = Nothing Me.jancode.Value = strName End Sub

  • Access2003(VBA)でADO接続時にルーターのセッション増加

    早速質問させていただきます。 WindowsXP上のAccess2003でDBServer(SQLSERVER2005Express)にADO接続でデータ要求を行うアプリを開発しました。 このアプリをDBServerがあるネットワークセグメント以外から実行するとルータのセッション数が見る見るうちに増加してルーターがハングアップしてしまいます。 調査してみたらADOのRecoredsetをMovenextする度にセッション数が増えるようです。そもそもADO接続では毎レコード毎?にセッションを張るような仕組みなのでしょうか? またこの現象を解消するにはどのような手法があるのでしょうか? ご教授のほどよろしくお願い致します。 -------------------------------------------------------------- Dim adoCON As New ADODB.Connection Dim adoRS As ADODB.Recordset '(1)ADOを使いSQL ServerのDBを開きます adoCON.Open "Driver={SQL Server};" & _ "server=SERVERNAME\SQLEXPRESS;          database=db_name; uid=sa; pwd=sa;" 'レコードセットの作成(SELECT文の実行) Set adoRS = adoCON.Execute("select * from 商品マスタ where 削除日=0") '//CSVデータ取り込み用配列の初期化 Erase arr() LineCount = 0 TblColCnt = 0 '最終レコードまで順読み込みを行う Do Until adoRS.EOF = True ReDim Preserve arr(ShouhinMSTMaxCol, LineCount) For cols = 1 To adoRS.Fields.Count - 1 TblColCnt = TblColCnt + 1 arr(TblColCnt, LineCount) = Trim$(adoRS(cols - 1)) Next LineCount = LineCount + 1 TblColCnt = 0 'レコードの順読み adoRS.MoveNext Loop 'レコードセットのクローズ adoRS.Close 'データベースのクローズ adoCON.Close 'オブジェクト変数のクリア Set adoRS = Nothing Set adoCON = Nothing --------------------------------------------------------------

  • ADO接続によるストアド

    あまりDB接続などに詳しくないので、 うまく説明できないと思いますがご了承下さい。 環境は Win2000+VB6+SQLSERVER2000+ADO2.5 やりたいことは、 SQLSERVERに設定してあるストアドがあります。 そのストアドをVB上から呼び出し結果を得たいわけです。 ストアドは、1つのパラメータを与えることで、 そのパラメータの最大値を取得してきます。 そして、データベース内では最大値が+1されているというものです。 現在 Dim adoCon As ADODB.Connection Dim adoCmn As ADODB.Command Dim adoRs As ADODB.Recordset ''DBに接続 Call DB接続関数(adoCon) Set adoCmn = New ADODB.Command Set adoRs = New ADODB.Recordset adoCmn.ActiveConnection = adoCon adoCmn.CommandText = "EXEC ストアド名 'パラメータ'" adoRs.Open adoCmn という状態で、ストアド自体は動作することができました。 しかし、最大値を取得することができません。 adoRsにはきちんとレコードセットが返ってきてない感じです。 どうすれば、最大値を取得できるでしょうか?

  • エクセルでのアクセスからのデータ抽出

    Web情報を参考にエクセルにて下記VBAコードを作りました。 Sub DB_Read() Dim adoCON As New ADODB.Connection Dim adoRS As New ADODB.Recordset Dim strSQL As String Dim odbdDB As Variant Dim wSheetName As Variant Dim i, j As Integer Dim GetName odbdDB = ActiveWorkbook.Path & "\test.accdb" adoCON.ConnectionString = "provider=Microsoft.ACE.OLEDB.12.0;" _ & "Data Source=" & odbdDB & "" adoCON.Open j = 4 Do Until j = 18 GetName = Range("B4").Value & "_" & Cells(16, j).Value strSQL = "SELECT 規格値,Max,Min,結果1,結果2,結果3 FROM T_測定結果 WHERE [測定項目]='" & GetName & "'" adoRS.Open strSQL, adoCON, adOpenDynamic wSheetName = ActiveSheet.Name i = 20 adoRS.MoveLast Do Until adoRS.EOF Or i = 25 With Worksheets(wSheetName) .Cells(17, j).Value = adoRS!規格値 .Cells(18, j).Value = adoRS!Max .Cells(19, j).Value = adoRS!Min .Cells(i, j).Value = adoRS!結果1 .Cells(i + 10, j).Value = adoRS!結果2 .Cells(i + 20, j).Value = adoRS!結果3 End With i = i + 1 adoRS.MovePrevious Loop j = j + 1 Loop adoRS.Close Set adoRS = Nothing adoCON.Close Set adoCON = Nothing End Sub VBAを走らせると1巡は走るのですが、「Do Until j = 18」の2巡目に入ると、「wSheetName = ActiveSheet.Name」のところで「実行時エラー3705 アプリケーション定義またはオブジェクトの定義エラー」と出てしまいます。 エラーの原因が分からないので、アドバイスを頂きたいです。

  • ADO1とADO2は意味は同じですか?

    Private Sub ADO1() Dim cn As New ADODB.Connection cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source= " & CurrentProject.FullName cn.Close: Set cn = Nothing End Sub Private Sub ADO2() Dim cn As ADODB.Connection Set cn = New ADODB.Connection cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source= " & CurrentProject.FullName cn.Close: Set cn = Nothing End Sub は、 Dim cn As ADODB.Connection Set cn = New ADODB.Connection を簡素化したものが Dim cn As New ADODB.Connection になるのでしょうか?

  • ADOでレコードを閉じるタイミング。。Access2000/VB6/Win2K

    レコードセットを返すFuncitonプロシージャーを作ってみたのですが。。。 下のGet_Recordsの方のレコードセットをCloseすると上の方のDisp_Dataでオブ ジェクトが閉じているといって怒られます。しかし、閉じないと下の方では開きっ ぱなしになると思うのですが。。。どのように処理すればいいのでしょうか? Public P_CN As ADODB.Connection Private Sub Disp_Date()   Dim RS As ADODB.Recordset   Dim SQL AS String    Set RS = Get_Records(SQL)     With RS      If .RecordCount > 0 Then       .MoveLast: .MoveFirst       .Debug.Print !顧客_ID        End If      End With      RS.Close     Set RS = Nothing End Sub Public Function Get_Records(pSQL As String) As ADODB.Recordset   Dim RS As ADODB.Recordset     Set RS = New ADODB.Recordset      RS.Open pSQL, P_CN, adOpenKeyset, adLockOptimistic     Set Get_Records = RS '''    RS.Close '''   Set RS = Nothing End Function

  • VBS ADO接続について

    VBSCRIPTを使用するのが始めてでなかなかうまくいきません アドバイス頂けますでしょうか。 環境 Windows2000Server 下記のようにしてみたのですが、エラーメッセージとしては 「オブジェクト名'test2'は無効です。」と出てしまいます。 このテーブル'test2'はクエリアナライザでSQLを使って 作成しました。 色々調べてはいますが、できましたらアドバイスの方お願いできますでしょうか。 Private Function DbDataUpdate(id2) Dim sql Dim conObj_ 'DBオブジェクトの生成 Set conObj_ = WScript.CreateObject("ADODB.Connection") conObj_.open "DSN=×××;UID=×××;PWD=×××;" conObj_.BeginTrans sql = "INSERT INTO test (id1, id2) " & _ "SELECT id1, id2 FROM test2 " & _ "WHERE " & _ "del = 0 AND " & _ "id2 = '" & id2 & "'" conObj_.execute(sql) sql = "UPDATE test2 " & _ "SET del = 1," &_ "WHERE " & _ "del = 0 AND " & _ "id2 = '" & id2 & "'" conObj_.execute(sql) conObj_.CommitTrans conObj_.close End Function

  • Access2007からADO接続にてEXCEL

    Access2007からADO接続してEXCELのシートにSELECT文を発行すると、 『[Microsoft][ODBC Excel Driver]選択された CollatingSequence は OS でサポートされていません。』のエラーが出ます。 SELECT文に条件を付けると上記エラーが発生します、条件なしの場合はエラーが発生しません。 エラーが発生してもデバッグで F8 で実行すると正常に条件付きでSELECTされます、 エラーは一回目のSELECTだけで、以降はエラーが発生しません。 対処の方法をお教え下さい。 よろしくお願いします。 (("Microsoft.Jet.OLEDB.4.0"を使用してもエラーが発生しました。)) (例) 'テンポラリファイルを取り込む Dim querydef As DAO.querydef Dim adoCON As New ADODB.Connection Dim adoRS As New ADODB.Recordset Dim strV As String Dim strQ As String 'ADOを使い読み込み専用モードでExcelファイルを扱う準備(オープン)をします adoCON.Open "Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)}; " & _ "DBQ=" & "C:\test2014.xlsx" & ";" & _ "ReadOnly=True" 'SQLを実行(全件検索)   OK Set adoRS = adoCON.Execute("SELECT * FROM [Shite1$]") 'SQLを実行(条件付き検索) NGエラーが発生します。 Set adoRS = adoCON.Execute("SELECT * FROM [Shite1$] WHERE A = 7 ")

専門家に質問してみよう