• ベストアンサー

VB6+SQL サーバー 2000 で 実行時エラー '3704' がでます:

VB6 + SQL サーバー 2000 でDB接続を行っていますが リストのように SELECT 文の後にInsert 文を実行しようとし Re.Closeを実行すると ------------------------------------------------------------- 実行時エラー '3704': オブジェクトが閉じている場合は、操作は許可されません -------------------------------------------------------------  とエラーになり、連続するSQL文を実行する場合のopen ,Close は どのように書けばよろしいのでしょうか。  ネット上で見つけた資料によるとメソッド RE.CancelUpdate を使うと ありましたがこれもエラーとなります。 どなたか 教えていただけないでしょうか。 --- sample ---------------------------------------- Dim Cn As New ADODB.Connection Dim Re As New ADODB.Recordset Connect = "" Connect = "Provider = SQLOLEDB;" _ & "Data Source = サーバー;" _ & "User ID = sa;" _ & "Password = パスワード;" _ & "initial Catalog = database;" ' Cn.Open Connect ' strSQL = "SELECT * from DBTBL WHERE CODE = '000001'" Re.Open strSQL, Cn, adOpenKeyset 'SQL文を実行 Re.Close ' strSQL = "Insert Into MAS1PF (CODE,NAME,TEL,FAX) Values('11111','名前','TEL,'FAX)" Re.Open strSQL, Cn, adOpenKeyset 'SQL文を実行 ' Re.Close Cn.Close

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

  • ベストアンサー
回答No.1

1:strSQL = "SELECT * from DBTBL WHERE CODE = '000001'" 2:Re.Open strSQL, Cn, adOpenKeyset 'SQL文を実行 3:Re.Close 4:strSQL = "Insert Into MAS1PF (CODE,NAME,TEL,FAX) Values('11111','名前','TEL,'FAX)" 5:Re.Open strSQL, Cn, adOpenKeyset 'SQL文を実行 の 3: で Re.Close したまま、5: で Re.Open しているからだと思います。 5: の前に Set Re = New ADODB.Recordset を入れると正常に動作するようになると思います。 ちなみに、なぜ 2: ではエラーが発生しないかというと、 Dim Re As ADODB.Recordset ではなく、 Dim Re As New ADODB.Recordset として宣言しているからです。

ShiroNeko
質問者

お礼

insert,update,delete の場合は Execute を使いなさいと文書を 見つけました。 Executeだと re.close は不要との記述もありました。 試したところイメージ通りの処理ができていますので、これでやってみようと 思います。 本当にありがとうございました。

ShiroNeko
質問者

補足

tukasa-12r さんありがとうございます。早速 試してみたのですが同じエラーが発生します。 Dim Cn1 As New ADODB.Connection Dim Re As ADODB.Recordset vProv = "Provider = SQLOLEDB;" _ & "Data Source = サーバー;" _ & "User ID = sa;" _ & "Password = パスワード;" _ & "initial Catalog = database;" Cn1.Open vProv 'Db OPEN strSQL = "SELECT * from DBTBL WHERE CODE = '000001'" Re.Open strSQL, Cn, adOpenKeyset 'SQL文を実行 Re.Close strSQL = "Insert Into MAS1PF (CODE,NAME,TEL,FAX) Values('11111','名前','TEL,'FAX)" Set Re = New ADODB.Recordset Re.Open strSQL, Cn, adOpenKeyset 'SQL文を実行 Re.Close ← ここでエラー 3704 がでます もう少し教えていただけないでしょうか。

その他の回答 (1)

noname#140971
noname#140971
回答No.2

Private Sub Command1_Click()   Dim strSQL(1) As String      strSQL(0) = "INSERT INTO Table1 (ID, 顧客名) VALUES (3, 'AAA')"   strSQL(1) = "INSERT INTO Table1 (ID, 顧客名) VALUES (4, 'BBB')"   CnnExecute strSQL(0)   CnnExecute strSQL(1) End Sub No1さんの回答で不具合自体は解消されています。 が、幾つか改善すべき点もあるようです。 CnnExecute関数は、conCNNSTRING を SQL Server 2000 のそれに変更しての動作確認も済んでいます。 改善点1、ADODB のエラー管理を行う。 改善点2、トランザクションのロールバックも行う。 なお、Set cnn = New ADODB.Connection を複数回実行するのであれば関数にすればよい。 そうすれば、 Command1_Click() のように非手続き的に安直の書くことも可能。 Const conCNNSTRING = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\temp\db1.mdb" Public Function CnnExecute(ByVal strSQL As String) As Boolean On Error GoTo Err_CnnExecute    Dim isOK As Boolean    Dim cnn As ADODB.Connection       isOK = True    Set cnn = New ADODB.Connection    With cnn      .Errors.Clear      .ConnectionString = conCNNSTRING      .Open      .BeginTrans      .Execute strSQL      .CommitTrans    End With Exit_CnnExecute: On Error Resume Next    CnnExecute = isOK    Exit Function Err_CnnExecute:    isOK = False    If cnn.Errors.Count > 0 Then      ErrMessage cnn.Errors(0), strSQL      cnn.RollbackTrans    Else      MsgBox "プログラムエラーが発生しました。システム管理者に報告して下さい。(CnnExecute)", _         vbExclamation, " 関数エラーメッセージ"    End If    Resume Exit_CnnExecute End Function Public Sub ErrMessage(ByVal CnnErrors As ADODB.Error, ByVal strSQL As String)    MsgBox "ADOエラーが発生しましたので処理をキャンセルします。" & Chr$(13) & Chr$(13) & _       "・Err.Description=" & CnnErrors.Description & Chr$(13) & _       "・Err.Number=" & CnnErrors.Number & Chr$(13) & _       "・SQL State=" & CnnErrors.SQLState & Chr$(13) & _       "・SQL Text=" & strSQL, _       vbExclamation, " ADO関数エラーメッセージ" End Sub

ShiroNeko
質問者

お礼

良きアドバイス ありがとうございます。 たいへん 勉強になります。 早速ためしてみます。

関連するQ&A

  • 実行時エラー-2147217904

    rs.CursorLocation = adUseClient rs.Open strSQL, cn, adOpenKeyset, adLockOptimistic の部分で、 実行時エラー-2147217904 「1つ以上の必要なパラメータの値が設定されていません」 となるのですが、どういうことでしょうか? やはりSql文に問題があるのでしょうか?

  • 実行時エラー 3265「要求された名前、または序数

    ADOで rs.Open strSQL, cn, adOpenKeyset, adLockOptimistic を過ぎようとすると 実行時エラー 3265「要求された名前、または序数に対応する項目がコレクションに見つかりません」 になるのですが、 strSQLの文字列をクエリのSQLビューに張り付けると、問題なくクエリが表示されます。 だから、 存在しないフィールド名を指定した訳ではないのですが なぜこの部分でエラーになるのでしょうか? オブジェクトが閉じてないのかと思い、 rs.Close: Set rs = Nothing をイミディエイトでやってみたら オブジェクトが閉じている場合は、操作は許可されません。 になります。

  • 【Access2003】VBAで削除のSQL実行ができない

    初歩的な質問かもしれませんが・・・ ACCESS2003VBAでADOを用いて削除を実行しようとしているのですがエラー(エラーは「オーバーフローしました」です。)が出て実行できません。 ソースは以下の通りです。 Dim strSQL As String Dim rs As New ADODB.Recordset Set cn = CurrentProject.Connection strSQL = " DELETE FROM D_TB" rs.Open strSQL, cn, , adOpenStatic, adLockOptimistic       '←ここでエラー Do Until rs.EOF rs.Delete rs.MoveNext Loop rs.Close cn.Close どこがおかしいのでしょうか? 大変困っています。教えてください。よろしくお願いいたします。

  • 実行時エラー-2147217900(80040e1

    アクセスVBAです。 Set cn = CurrentProject.Connection rs.Open "T_test", cn, adOpenKeyset, adLockOptimistic としたときに、T_testと言うテーブル名は存在するのに、 「実行時エラー-2147217900(80040e14) SQLステートメントが正しくありません Delete、Insert、Procedure、SelectまたはUpdateを使用して下さい。」 と言うエラーが発生します。 どうしてテーブルが存在するのにこのエラーが発生するのでしょうか?

  • SQL Serverへの接続について

    すみませんが、どなたか教えてください。 Access2000のプロジェクトからADOを使って、OLE-DB経由でSQL Serverに接続しようとしています。 SQLステートメントを指定して、レコードセットを作成したいのですが、 以下のSQL分のテーブル名のSYARMに対して、オブジェクト名SYARMは無効ですというメッセージが出てきます。どこが問題になっているのでしょうか? Dim cn As New ADODB.Connection Dim rs As New ADODB.Recordset cn.Open "Provider=SQLOLEDB;" & "datasource=(local);" & "Integrated Security=SSPI;" rs.Open "SELECT * FROM SYARM WHERE KANNO=12345;", cn, adOpenKeyset, adLockOptimistic rs.Close cn.Close Set rs = Nothing Set cn = Nothing

  • Insert時に一意制約エラーがでる。

    よろしくお願いします。 VB6.0 DB:ORACLE8.1.6 クライアントWIN2000 サーバーWIN2000SERVER VBでデータをINSERTするプログラムを作ったのですが、どうしても一意制約エラーが出てしまいます。 これはデータの都合上仕方が無いのか? (データの主キーに「.」が入っているのでエラーになるのでしょうか?) プログラムが悪いのか? よろしくお願いします。 エラーは2回目の実行部分です。 データ(すべて文字型) 000   001   002 ベルリン12345 ベルリン 12345 ベルリン123.45 ベルリン 123.45 ベルリン123 45 ベルリン 123 45 プログラム strSql = "Insert Into KUNIBETU(k000,k001,k002) Values ('ベルリン12345','ベルリン,'12345')" '処理のチェック If Execute_sql(strSql) = False Then Err.Raise -1, , "失敗しました!" cn.RollbackTrans rs.Close Set rs = Nothing cn.Close Set cn = Nothing Exit Sub End If strSql = "Insert Into KUNIBETU(k000,k001,k002) Values ('ベルリン1234.5','ベルリン','123.45')" '処理のチェック If Execute_sql(strSql) = False Then Public Function Execute_sql(strSql As String) As Boolean Dim cmd As New ADODB.Command Execute_sql = False ' Commandオブジェクトを作成 Set cmd = New ADODB.Command cmd.ActiveConnection = cn cmd.CommandText = strSql ' アクション クエリーを実行 cmd.Execute      ←←←←←←エラー部分 Set cmd = Nothing Execute_sql = True Exit Function

  • SQLの構文エラー??

    お世話になっています。 OS:Win2000 DB:Access2000 です。 Insert文、Update文共に「構文エラー」になってしまいます。 ですが、実行したSQL文をAccessのクエリに貼り付けて実行しても エラーにならず、正常に実行されます。 エラーになったSQL文は以下のとおりです。 INSERT INTO D_Schedule (ShisetuNo,YYYYMMDD,ScheTime,Seq,Title,Memo,AddDate,UpdDate) VALUES (1,20041213,'0900',6,'BBB','BBB',#2004/12/16 14:31:49#,#2004/12/16 14:31:49#) UPDATE D_Schedule Set YYYYMMDD =20041213, ScheTime ='0900', Title ='AAA', Memo ='BBB', UpdDate =#2004/12/16 14:30:06# WHERE ShisetuNo=1 AND YYYYMMDD=20041213 AND ScheTime='0900' AND Seq=2 Insert文の場合、Valueの左側を指定しないで Insert Into D_Schedule Values()だとエラーにならないです。 何かお心当たりのある方、ご指摘お願いいたします。 DB更新はADOで行っています。 ADOの接続方法は Set gobjCon = Server.CreateObject("ADODB.Connection") gobjCon.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=" & GCOM_DBNAME & ";" です。 SQL文の実行方法は gobjCon.Execute(strSQL) です。よろしくお願いいたします。

  • 【Excel】【VBA】実行時エラー メモリ不足

    【Excel】【VBA】実行時エラー -'-2147467259「メモリ不足です」 win8.1 エクセル2010 メモリ8Gのスペックで VBAコードを実行しているのですが たまに 実行時エラー -'-2147467259「メモリ不足です」 となり、マクロが中断されてしまいます。 今回、実行時エラー -'-2147467259「メモリ不足です」と出たコードは rs.Open strSQL, cn, adOpenKeyset, adLockOptimistic です。 前後のコードは省略していますが 普段は問題なく通ります。 strSQLも、中身をクエリのSQLビューに張り付けて、クエリで見てみたけど 問題なく表示されます。 なぜメモリ不足ですとなるのでしょうか? スペックが低いのですか?

  • VB6からSQLServer7に加工したデータを、正常に追加できません。なぜ?

    VB6から、SQLServerに対して 加工したデータを追加するプログラムをしています。 (環境:Windows2000 Pro + VB6[SP5] + SQLServer[7.0]) 一度、「sampletable」のデータを全件削除した上で、 必ず2回以上実行するループ処理の中で、Insert文を発行しています。 がしかし、プログラム実行後にSQLServerのデータベースを検索してみると、 何故か、最後に実行したInsert文しか、正常に実行終了していないようなのです。 (最後のループ処理でInsertされたデータしか、追加されてないのです。) 何か、プログラム上で、おかしいところとか 抜けているところとかございましたら、教えて下さい。 <サンプルプログラム> ' SQL Server へ接続 Set cn = New ADODB.Connection cn.Open "Provider=SQLOLEDB;" & _ "Data Source=(localhost);" & _ "Initial Catalog=database", "login", "passwd" ' 一度、テーブルデータを削除する strSQL = "delete from sampletable" Set rs = cn.Execute(strSQL) Do 'このループ処理は、2回以上、必ず動作します。 ・・・ (データ加工処理) ・・・ ' データを追加する strSQL = "INSERT INTO sampletable(xxx, xxx, xxx) " & _ "VALUES('" + HENSUU-A + "','" + HENSUU-B + "','" + HENSUU-C + "')" Set rs = cn.Execute(strSQL) Loop ' SQL Server 接続を閉じる cn.Close

  • VB6でのSQL実行について

    VB6でのSQL実行について VB6でのSQL実行について困っています。 SQL文を作成し、ダイナセットで実行している最中にも 再度別のSQL文をダイナセットで実行することは可能なのでしょうか? 言語はVB6.0、DBはOracle9iを使用しています。 イメージ的にはこんな使い方をしたいです。 dim lngRecordRow1 as long 'レコード数1 dim lngRecordRow2 as long 'レコード数2 dim OraDynaset1 As OraDynaset dim OraDynaset2 As OraDynaset dim strSQL as string 'SQL文 dim lngCnt1 as long 'ループカウンタ1 dim lngCnt2 as long 'ループカウンタ2 strSQL= ---SQL文作成1回目--- Set OraDynaset1 = OraDatabase.CreateDynaset(strSQL, ORADYN_READONLY) 'SQL文実行1回目 lngRecordRow1 = OraDynaset1.RecordCount for lngCnt1 = 1 to lngRecordRow1 '--- 処理 --- strSQL= ---SQL文作成2回目--- Set OraDynaset2 = OraDatabase.CreateDynaset(strSQL, ORADYN_READONLY) 'SQL文実行2回目 lngRecordRow2 = OraDynaset2.RecordCount for lngCnt2 = 1 to lngRecordRow2 '--- 処理 --- next lngCnt2 next lngCnt1 1回目で取得したSQL実行結果を行単位でループをまわしつつ、1回目で取得したレコードの結果を条件に使用して別のSQL文を作成し、ループをまわしている最中に実行したいです。 その際、2回目のSQLの結果が2レコード以上の場合、さらにループをまわして条件判別をしたいです。 かなり困っています。回答待ってます。

専門家に質問してみよう