質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

Access

Accessはマイクロソフトによるリレーショナルデータベース管理システムです。オブジェクト指向のアプリケーション作成に対応しており、テーブルや編集をはじめ、クエリ生成、入力フォーム作成、レポート作成など一通りの機能を備えています。

Q&A

解決済

1回答

18299閲覧

実行時エラー(オブジェクトが開いている場合は操作は許可されません)になる

gigatail

総合スコア9

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

Access

Accessはマイクロソフトによるリレーショナルデータベース管理システムです。オブジェクト指向のアプリケーション作成に対応しており、テーブルや編集をはじめ、クエリ生成、入力フォーム作成、レポート作成など一通りの機能を備えています。

1グッド

1クリップ

投稿2018/04/19 06:30

編集2018/04/19 07:51

前提・実現したいこと

Access VBA からSQL Serverの[M_取引先マスタ]にテーブルロックを掛けて、フォームに入力があった内容を新規追加したく思っています。

発生している問題・エラーメッセージ

下記ロジックを実行すると、2つ目のSQL文実行時(M_取引先マスタのロックSQL)に
【実行時エラー '3705' オブジェクトが開いている場合は、操作は許可されません。】
とエラーになります。

SELECT COUNTのSQL文をコメントアウトすると、INSERT文の行で同エラーになります。

別ロジックで[DELETE]-->[INSERT]している部分では問題無く動作しているため、コピペするかたちで作ったのですが、SQL文実行の都度クローズしなくてはいけないのでしょうか?

該当のソースコード

Access

1 2Public CN_SQL As New ADODB.Connection 3Public RS_SQL As New ADODB.Recordset 4' ----------------------------------------------------------------------------- 5' Connectionオブジェクトを生成 6' ----------------------------------------------------------------------------- 7Public Sub DB_Connect() 8 9Dim ConnectionString As String 10 11Dim sDBSever As String 12Dim sDBName As String 13Dim sLoginID As String 14Dim sPassWD As String 15 16sDBSever = DLookup("[データ]", "M_システム", "[ID] = 'SvName'") ' SQL Serverが稼働しているサーバー名 17sDBName = DLookup("[データ]", "M_システム", "[ID] = 'DbName'") ' SQL ServerのDB名 18sLoginID = DLookup("[データ]", "M_システム", "[ID] = 'Login'") ' sa 19sPassWD = DLookup("[データ]", "M_システム", "[ID] = 'Pass'")' saのパスワード 20 21' 接続文字列 22ConnectionString = "Provider=SQLOLEDB;Data Source=" & sDBSever & _ 23 ";Initial Catalog=" & sDBName & _ 24 ";Connect Timeout=15" & _ 25 ";user id=" & sLoginID & _ 26 ";password=" & sPassWD 27 28' 接続 29CN_SQL.Open ConnectionString 30 31End Sub 32 33' ----------------------------------------------------------------------------- 34' データベースへの接続を解除する 35' ----------------------------------------------------------------------------- 36Public Sub DB_DISCONNECT() 37 38CN_SQL.Close 39Set CN_SQL = Nothing 40 41End Sub 42 43' ----------------------------------------------------------------------------- 44' 引数のSQL文を実行し、ADODB.Recordsetを返す 45' ----------------------------------------------------------------------------- 46Public Function DB_EXECUTE(s_SQL As String, CursorType, LockType, b_FLG As Boolean) As ADODB.Recordset 47 48b_FLG = True 49 50' タイムアウト設定 (15分) 51CN_SQL.CommandTimeout = 60 * 15 52 53' 処理された行数を示すメッセージが結果セットの一部として返されないようにする 54CN_SQL.execute ("SET NOCOUNT ON") 55 56' 警告メッセージが結果セットの一部として返されないようにする 57CN_SQL.execute ("SET ANSI_WARNINGS OFF") 58 59' オーバーフローおよび0除算時にはNULLを返す 60CN_SQL.execute ("SET ARITHABORT OFF") 61 62 63RS_SQL.CursorType = CursorType 64RS_SQL.LockType = LockType 65 66RS_SQL.Open s_SQL, CN_SQL 67'RS_SQL.Open s_SQL, CN_SQL, CursorType, LockType 68 69Do 70' レコードの操作ができるオブジェクト若しくは次のRecordSetがとれず、コネクションが空になった場合終了 71If RS_SQL.State = adStateOpen Or RS_SQL.ActiveConnection Is Nothing Then 72Exit Do 73End If 74Set RS_SQL = RS_SQL.NextRecordset() 75Loop 76 77Set DB_EXECUTE = RS_SQL 78 79 80' 設定OFF 81CN_SQL.execute ("SET NOCOUNT OFF") 82CN_SQL.execute ("SET ANSI_WARNINGS ON") 83CN_SQL.execute ("SET ARITHABORT ON") 84 85End Function 86 87' ----------------------------------------------------------------------------- 88' トランザクションを開始する 89' ----------------------------------------------------------------------------- 90Public Sub BeginTransaction() 91 92CN_SQL.BeginTrans 93 94End Sub 95 96' ----------------------------------------------------------------------------- 97' トランザクションをコミットする 98' ----------------------------------------------------------------------------- 99Public Sub CommitTransaction() 100 101CN_SQL.CommitTrans 102 103End Sub 104 105' ----------------------------------------------------------------------------- 106' トランザクションをロールバックする 107' ----------------------------------------------------------------------------- 108Public Sub RollbackTransaction() 109 110CN_SQL.RollbackTrans 111 112End Sub 113 114' ----------------------------------------------------------------------------- 115' F_取引先登録のコード 116' ----------------------------------------------------------------------------- 117'DB接続 118Call DB_CONNECT 119 120'SQL文生成 121s_SQL = "" 122s_SQL = "SELECT COUNT(*) AS REC_CNT " 123s_SQL = s_SQL & "FROM M_取引先マスタ " 124s_SQL = s_SQL & "WHERE 取引先CD LIKE '201804%';" 125 126i_Seq = REC_CNT + 1 127 128'SQL文実行 129RS_SQL.Open s_SQL, CN_SQL, adOpenStatic, adLockReadOnly 130 131'トランザクション開始 132Call BEGINTRANSACTION 133 134'SQL文生成 135s_SQL = "" 136s_SQL = "SELECT * FROM M_取引先マスタ WITH (TABLOCK, HOLDLOCK);" 137 138'SQL文実行 139'RS_SQL.Open s_SQL, CN_SQL, adOpenKeyset, adLockPessimistic 140 141s_SQL = "" 142s_SQL = "INSERT INTO M_取引先マスタ (取引先CD, 取引先名, 取引先住所, 更新日時) " 143s_SQL = s_SQL & "VALUES ( " 144s_SQL = s_SQL & "'" & s_SysDate & String(3 - Len(CStr(i_Seq)), "0") & CStr(i_Seq) & "', " 145s_SQL = s_SQL & "N'" & Forms!F_取引先登録.txt_取引先名.Value & "', " 146s_SQL = s_SQL & "N'" & Forms!F_取引先登録.txt_取引先住所.Value & "', " 147s_SQL = s_SQL & "'" & Format(Now(), "yyyy/mm/dd hh:mm:ss") & "' " 148s_SQL = s_SQL & ");" 149 150'SQL文実行 151RS_SQL.Open s_SQL, CN_SQL, adOpenKeyset, adLockPessimistic 152 153'SQL文コミット 154Call COMMITTRANSACTION 155 156'接続を閉じる 157Call DB_DISCONNECT 158 159 160 161' ----------------------------------------------------------------------------- 162' 以下は[DELETE]-->[INSERT]しているロジックです 163' ----------------------------------------------------------------------------- 164 165'----- DB接続 ----- 166Call DB_Connect 167 168'----- トランザクション開始 ----- 169Call BeginTransaction 170 171'該当データをDELETE --> INSERT 172s_SQL = "DELETE FROM T_案件テーブル WHERE ID = '" & KEY & "';" 173 174'SQL文実行 175RS_SQL.Open s_SQL, CN_SQL, adOpenKeyset, adLockPessimistic 176 177s_SQL = "INSERT INTO T_案件テーブル (ID, FLD1, FLD2, FLD3) " 178s_SQL = s_SQL & "VALUES ( , , , );" 179 180'SQL文実行 181RS_SQL.Open s_SQL, CN_SQL, adOpenKeyset, adLockPessimistic 182 183'----- DBコミット ----- 184Call CommitTransaction 185 186'----- 接続を閉じる ----- 187Call DB_DISCONNECT 188

試したこと

補足情報(FW/ツールのバージョンなど)

Access2010
SQL Server2014

ItSANgo👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2018/04/19 06:37

プログラムコード(およびエラーメッセージ)は```で囲ってください。(わからなければ質問編集画面でコード部分を選択し<code>ボタンを押してください)正しく反映されているかどうかは質問編集画面のプレビューを見ながら編集していってください。
sazi

2018/04/19 07:25

RS_SQLの定義や作成部分も追記して下さい。
guest

回答1

0

ベストアンサー

RS_SQL.Openで毎回セッションを開いているんじゃないですか?
別セッションなら当然排他されますので。

追記

SELECT COUNTのSQL文をコメントアウトすると、INSERT文の行で同エラーになります。

insert って openじゃなくて、executeじゃなかった?
まあ、本題とは関係ないですけど。

追加されたコードを見るにセッションは引き継いでいるように見えますね。

VBA

1Call BEGINTRANSACTION

の前でCOMMITするとどうなります?

やっぱり、openでの排他モードが関係しているような気がします。
selectでテーブル単位の排他を行っていますけど、openは基本カーソルなのでレコード単位までしかありません。
executeに変えてみてはどうでしょうか。

投稿2018/04/19 07:30

編集2018/04/19 08:09
sazi

総合スコア25300

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gigatail

2018/04/19 08:00 編集

コメントいただきありがとうございます。 全SQLとも[RS_SQL.Open]としています。 プロシージャ内で[RS1_SQL][RS2_SQL]と変えていった方がいいのでしょうか?
gigatail

2018/04/19 08:08

ご教授ありがとうございます。 デバッグしてみると「アクティブなトランザクションがありません」となります。
sazi

2018/04/19 08:11

あ、beginもセットじゃないと駄目です。 でもそこではない気がするので、回答に追記したので確認ください。
sazi

2018/04/19 08:15

実際に試せてはいないので、トライ&エラーになってしまいます。 ですので、識者の回答をまちましょうか。
sazi

2018/04/19 08:19

感覚的にはwith()はsqlserverでの排他で、openはadoでの排他になるのでレベルがそろってないのでは無いかという気がしますが。
gigatail

2018/04/19 08:24

実は16日の午後から行き詰っております。 Access <--> SQL Server というのは今回が初めてな上、社内は「データベースって何?」って感じなのでWEBからの寄せ集めで奮闘しています。
sazi

2018/04/19 08:53

方法としては、 1.取り敢えず排他は後回し 2.DAOの排他に揃える 3.with()とexecutの組合せ 3は推測の域を出ないですが。
gigatail

2018/04/23 02:29

SQL文実行後に RS_SQL.Close を追記することでエラー表示なく、動作することができました。 お忙しい中、ご教授いただきましてありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問