Microsoft Access 掲示板

openrecordset メソッド

11 コメント
views
4 フォロー

お恥ずかしい話ながら、ヘルプなどをみてもよく理解できないので質問いたします。

頂き物のコードの
Set rs1 = db.OpenRecordset (strSQL, dbOpendynaset, dbDenyWrite, dbPessimistic)
部分です。

strSQLはテーブル[MT_F_ID]から作られるクエリのSQL文です。

このコードで動いていたのですが、フォームにコンボボックスを作り、そのソースに[MT_F_ID]を指定したところ、
前述のコード部分で実行時エラー 3008([MT_F_ID]が排他的どうこう)が出るようになりました。

エラーが出る原因はコンボボックスのソースにあることはわかりますが、何が悪いのかがわからず、ヘルプを見ても腑に落ちない状態です。

また、このコードがあるフォーム内で、テーブル[MT_F_ID]の値を参照することはできないのでしょうか。(テーブル内のフィールド[F_ID]の値を入力者が参照したい。現在、苦肉の策で手打ち)

初心者すぎて申し訳ありませんが、ご指導願います。

nokonoko
作成: 2020/07/30 (木) 18:00:28
通報 ...
1

フォームにコンボボックスを作り、そのソースに[MT_F_ID]を指定したところ、

コンボボックスの値集合ソースに MT_F_ID を設定したということでしょうか。

前述のコード部分で実行時エラー 3008([MT_F_ID]が排他的どうこう)が出るようになりました。
エラーが出る原因はコンボボックスのソースにあることはわかりますが

コンボボックスの値集合ソースはスナップショット(読み取り専用)ですので、ほかに影響を与えることは原理的にないです。原因は別にあると思います。

まず、そのVBAはどこに記述してあり、どのタイミングで実行されるのか。
また、そのコードのプロシージャ全体(Sub から End Sub まで)を提示してください。

3
nokonoko 2020/08/03 (月) 14:57:57 修正 653a6@54883

Access英語版です。

cmbF_IDがあり、Property SheetにてRow Sourceを
 Select Right([FV_ID],Len([FV_ID])-5)
 From MT F_ID
 Group By Right([FV_ID],Len([FV_ID])-5)
としています。

ボタンbtn001を押すイベント内で
テキストボックスの入力状態の確認がなされた後、

If fncUpdateMasterTables = False then Exit sub
End If

があって、関数で更新処理を行います。

Private Function fncUpdateMasterTables() As Boolean
On Error GoTo ErrorHandler
 Dim ws As DAO.Workspace
 Dim db as DAO.Database
 Dim rs1 as DAO.Recordset
 (変数宣言中略)

 DoCmd.Hourglass True

 Set ws = DBEngine.Workspaces(0)
 Set db = CurrentDb

 strSQL = "SELECT * FROM[MT_F_ID]" & _
 "WHERE [FV_ID] = '" & Me.txtFV_ID & "'"

 Set rs1 = db.OpenRecordset (strSQL, dbOpendynaset, dbDenyWrite, dbPessimistic)

  中略(レコードセットrs2を参照した後、フォーム内のデータをrs1とrs2で更新)

 ErrorHandler:
 DoCmd.Hourglass False
 Msgbox Err.number & ": " & Err.Description,vbcritical, _
 "Running Error(" & Me.Name & .fncUpdateMasterTables)"

 Resume Exit_fncUpdateMasterTables
End Function

以上です。よろしくお願いいたします

4

On Error GoTo ErrorHandler
の行をコメントアウトして実行してみると、どの行でエラーがでますか。
また、その時の、エラーメッセージも提示してください。

5
nokonoko 2020/08/04 (火) 10:20:43 653a6@54883

Set rs1 = db.OpenRecordset (strSQL, dbOpendynaset, dbDenyWrite, dbPessimistic)
の行です。

エラーメッセージは下記のとおりです。

Run-time error '3008'

The table'M_F_ID' is already opened exclusively by another user, or it is already open through the user interface and cannot manipulated programmatically.

6

フォームのレコードソースが、M_F_ID またはそれを含むクエリになってませんか。
あるいは、提示のコード以外の部分で、M_F_ID を更新するような操作を行ってませんか。

7
nokonoko 2020/08/04 (火) 17:48:09 653a6@54883

フォームのレコードソースが、M_F_ID またはそれを含むクエリになってませんか。

レコードソースは空欄です

提示のコード以外の部分で、M_F_ID を更新するような操作を行ってませんか。

更新はないと思います。MT_F_ID(M_F_IDは誤植でした)については
コンボボックスcmbVerのイベントがあって、一度参照しています。

Private Sub cmbVer BeforeUpdate(Cancel as integer)
(前略)
 strSQL = "SELECT * FROM[MT_F_ID]" & _
 "WHERE [FV_ID] = '" & Me.txtFV_ID & "'"
SET rs1 = db.OpenRecordset(strSQL, dbOpenSnapshot)
With rs1
 If .EOF then
(以下レコードがない場合はExit sub、
ある場合は、非連結テキストボックスに対して、
Me.txtPCardDate=.Fields("PCard_date")とデータを入れただけ)

コンボボックスcmbF_IDのレコードソースにMT_F_ID関連のクエリを組み込んでいないときはエラーが出ませんので、それ以外の部分で更新の影響が出ていることはないと(勝手に)考えております。

8

コンボボックスcmbF_IDのレコードソースにMT_F_ID関連のクエリを組み込んで

コンボボックスの「値集合ソース」プロパティにクエリ名を設定しているということでしょうか。
(コンボボックスにレコードソースはない)

原理的に考えて、コンボボックスの値集合ソースの設定で、排他エラーがでるとは考えにくいです。

他にそのテーブルと連結しているテーブルとか、更新クエリを実行しているとか、別の処理で排他的に開いているとか、、、
があるとしか思えません。

提示されている情報からは、これ以上のアドバイスは無理です。

9

もし、本当にコンボボックスの「値集合ソース」プロパティにクエリを設定しない場合はエラーがでないのなら、
「値集合タイプ」を「値リスト」に設定して、
db.OpenRecordset(strSQL, dbOpenSnapshot) という感じでレコードセットを開いて、ループさせて AddItem でリストを追加すればどうでしょうか。

10
kitasue 2020/08/05 (水) 06:25:18 ce705@e9d43

DJoin関数を導入して、
https://web.archive.org/web/20150517052733/http://www.f3.dion.ne.jp/~element/msaccess/AcTipsVbaDJoin.html
コンボボックスのフォーカス取得時(?)に、
    Me.cmbF_ID.RowSourceType = "Value List"
    Me.cmbF_ID.RowSource = DJoin("Right([FV_ID],Len([FV_ID])-5)", "MT_F_ID", , , ";", True)
としては、いかがでしょうか。

11
nokonoko 2020/08/06 (木) 09:39:32 653a6@54883

たくさんのご回答ありがとうございました。
問題の箇所になっているところの必要性も考え、別の方法で回避します。