新規データの登録時にエラーが発生し、画面が正しく表示されない問題の解決方法

このQ&Aのポイント
  • 新規データの登録時にエラーが発生し、画面が正しく表示されない問題の解決方法を教えてください。
  • エラーメッセージ『実行時エラー'7951': RecordSetCloneプロパティに対する不適切な参照を含む式を入力しました』が表示されます。
  • このエラーは、B画面の保存ボタンの処理が正常に実行されていないために発生しています。B画面の保存ボタンの処理を確認し、適切に登録処理が行われるよう修正してください。
回答を見る
  • ベストアンサー

子画面を読んだ後親画面のRecordsetClon

同じレコードソースを持つ帳票フォームAとポップアップ画面Bがあり 新規作成ボタンイベントで、Aからで新規入力用のB画面を acAddNew, acDialogで開き 新規レーコドを追加する作業をして B画面の保存ボタンを押すことでしてレコードを保存しています。 ◆B画面の保存ボタンの処理 Private Sub cmd保存_Click()   '保存処理   Dim i As Long   Dim NewKey As Long   Dim SQL As String   Dim lngCurrentRec As Long      If Me.Dirty = True Then     Ret = MsgBox("入力したデータを保存しますか。", vbQuestion + vbOKCancel)     If Ret = vbCancel Then       cmd取消_Click       GoTo exitH     End If     Set Me.ClsDao_ = New ClsDao     SQL = "Select final_value, [更新日時] from T95ID管理表 "     SQL = SQL & "where "     SQL = SQL & " ID_Name = '作業記録ID';"          NewKey = Me.ClsDao_.SelectID(SQL)     Me.作業記録ID.Value = NewKey          Me.BeforeUpdate = ""     DoCmd.RunCommand acCmdSaveRecord          '採番テーブルに新しいNoで更新をする     ClsDao.UpdateID NewKey     modPub.lngNewRecID = NewKey 'Global変数に新しいID NOをセット(親画面で取得するため)     Set ClsDao = Nothing          BeforeUpdate = "[イベント プロシージャ]"   '  Me.Visible = False     DoCmd.Close   End If End Sub ◆B画面の保存ボタンの処理終わり    その後、呼出元のB画面を開くイベントの処理を継続し A画面を更新し、新規入力されたレコードを選択する処理をしています。 問題は、まず1回目には、新規作成ボタンを押して新規データを登録し A画面でその新規レコードを選択することが1回目は可能で 同じ事を2回目すると、 ※実行時エラー'7951':  RecordSetCloneプロパティに対する不適切な参照を含む式を入力しました。 というエラーが出ます。 その時の画面は、複数行あったのが一レコードだけになってしまい、 各項目のTextboxは、「#Name?」が表示されています。 デバッグボタンを押すと 以下のソースの「Set Rec = Me.RecordsetClone」で止まります。 この解決方法を教えて下さい。 ◆A画面の新規作成ボタンのソースの内容開始 Private Sub cmdNewRec_Click()   Dim ClsDao As ClsDao   Dim SQL As String   Dim NewFm As Form   Dim Rec As Recordset   Dim NewNo As Long   Dim MyFm As Form   Dim StrRecSource As String      Set MyFm = Me.Form    StrRecSource = Me.RecordSource      DoCmd.OpenForm "FXX作業記録(NewEntry_連結版)", acNormal, , , acFormAdd, acDialog      If modPub.lngNewRecID > 0 Then     NewNo = modPub.lngNewRecID     Me.RecordSource = StrRecSource     Me.Requery     Set Rec = Me.RecordsetClone <===ここでエラー     Rec.FindFirst "作業記録ID = " & NewNo     If Rec.NoMatch = False Then '      Me.CurrentRecord = Rec.AbsolutePosition       DoCmd.GoToRecord acDataForm, Me.Name, acGoTo, Rec.AbsolutePosition + 1       Rec.Close       Set Rec = Nothing     End If   End If End Sub ◆A画面の新規作成ボタンのソースの内容終了

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

  • ベストアンサー
  • piroin654
  • ベストアンサー率75% (692/917)
回答No.1

実行しているファイルの参照設定がどうなっているのか 明記されていないので、憶測でしか言えませんが。 エラーが生じるコードの変数宣言で、 Dim ClsDao As ClsDao とありますが、これはクラスモジュールで何かDAOを 定義している、ということでしょうか。そうすると ファイルの参照設定で、DAOはチェックされていない、 あるいはチェックされていてもDAOがADOの上位に 表示されていない、ということなのでしょうかね。 ということであれば一度、参照設定でDAOにチェックを 入れ、 >Dim Rec As Recordset を、 Dim Rec As DAO.Recordset としてみてはどうですか? ところで、もしクラスモジュールでDAOを定義しているならば その理由は?

superwonderful
質問者

お礼

ご回答ありがとうございます。限られた情報でアドバイスを頂き感謝です。 それと、これは私の推測なのですが この私の質問の原因に関して、私がついふと思いついたのですが・・・ テーブルA フォームA帳票型→レコードソース:A フォームB単票型→recordソース:A 1) Aの開くボタンクリック処理:Bを開く(Dialogモード→新規record入力用しか表示しない)。ここで、、処理が一時止まる。 2) Bの保存ボタン:データをコードで保存し、Bを閉じる 3) (1)の処理の継続する。  ・画面をリクエリ-  ・フォームのrecordsetでフィールドの値を検索をする  →エラー この場合に、(1)から(2)に進み新規入力モードでrecordを入れ保存したとき 何故か、Aの画面でも、新規入力モードを覚えているので A.Requeryとすると 全ての項目が「?Name」となってしまい Set Rst = me.RecordsetClone Rst.FindFirst "項目名 = " & 値 を実行しても、Rstの中には何もないですよ・・・というエラーが発生してしまうのでしょうか?

superwonderful
質問者

補足

ご回答ありがとうございます。 クラスモジュールでは、頭で、private prvRs as Recordset となっていました。 ご説明の通り、念のためDAO.Recordset と書き直しました。 まだ、このテストは実施出来ておりませんが、後ほどしてみます。 クラスに関するご質問ですが、 共通化して、自動採番処理に使用しています。 自動採番時は、このクラスが終了するまでは、できるだけ Recordsetはクローズしないような作りにして、もし、複数の人が使用する場合には、それに対応できるようにしようかと考えていました。 無理やりなので、もしかするとうまくいかないかもしれませんが。 OpenRecordsetでは、オプションに「dbDenyRead Or dbDenyWrite」を入れています。 これで、他の人が同じテーブルにアクセスしようとすれば、不可能になりますので。 でも同時に出来ないので、意味がないと言えば、意味がないのでしょうか・・・

その他の回答 (1)

  • m3_maki
  • ベストアンサー率64% (295/459)
回答No.2

この処理が邪魔しているようですが。   Me.RecordSource = StrRecSource 本当に必要ですか?

superwonderful
質問者

お礼

回答して頂きありがとうございます。現在のところ、新規入力フォームとして開かず、編集用モードでフォームを開くようにして問題がありませんので、とりあえず、ここでこの質問を閉じさせていただきます。 原因が今ひとつ分からないのですが、Workspaceの使用、未使用でも何か影響がありそうなのかと考えています。 ありがとうございました。

superwonderful
質問者

補足

これを消して、 Me.Requeryとしても、2回目に同じ処理を実行すると、Rst.FindFirstのところでRstがおかしいと言って叱られます。 以下、その他のソースです。 明細フォームと単票フォームは、作業記録テーブルというテーブルがレコードソースです。 主キーは、作業記録ID 採番は、採番テーブル(後述)で管理しています。 '明細フォームの新規ボタンクリック実行処理 Private Sub cmdNewRec_Click()   Dim ClsDao As ClsDao   Dim SQL As String   Dim NewFm As Form   Dim Rec As Recordset   Dim NewNo As Long   Dim MyFm As Form   Dim StrRecSource As String      Set MyFm = Me.Form    StrRecSource = Me.RecordSource      modPub.flgBackFromNewEntryWindow = True   modPub.pubStrCallFormName = Me.name   DoCmd.OpenForm "FXX作業記録(NewEntry_連結版)", acNormal, , , acFormEdit, acDialog   '↑ここで、保存ボタン押すまで、処理が止まる   '↓新規入力したレコードのID番号を取得し、それで自画面の検索をし、   ' そのレコードを選択する処理   If modPub.lngNewRecID > 0 Then     NewNo = modPub.lngNewRecID     Me.Requery     Set Rec = Me.RecordsetClone     Rec.FindFirst "作業記録ID = " & NewNo '<--- 2回目にこの処理を実行すると、ここでエラーに成る。     If Rec.NoMatch = False Then '      Me.CurrentRecord = Rec.AbsolutePosition       DoCmd.GoToRecord acDataForm, Me.name, acGoTo, Rec.AbsolutePosition + 1       Set Rec = Nothing        End If   End If End Sub テーブル情報 【T95ID管理表】 1)主キー 2)主キーフィールド名 3)final_value 4)新規作成日時 5)更新日時 6)削除日時 ここでは、(2)に、「作業記録ID」がセットされている。 上の新規ボタンで開く単票フォームのフッターにある保存ボタンの処理 Private Sub cmd保存_Click()   '保存処理   Dim NewKey As Long   Dim SQL As String      If Me.Dirty = True Then     Ret = MsgBox("入力したデータを保存しますか。", vbQuestion + vbOKCancel)     If Ret = vbCancel Then       cmd取消_Click       GoTo exitH     End If     Set Me.ClsDao_ = New ClsDao     SQL = "Select final_value, [更新日時] from T95ID管理表 "     SQL = SQL & "where "     SQL = SQL & " ID_Name = '作業記録ID';"          '採番テーブルに新しいNoで更新をする     NewKey = ClsDao.UpdateID(SQL)          Me.作業記録ID.Value = NewKey     Me.BeforeUpdate = ""     DoCmd.RunCommand acCmdSaveRecord          modPub.lngNewRecID = NewKey     Set ClsDao = Nothing     BeforeUpdate = "[イベント プロシージャ]"     DoCmd.Close acForm, Me.name   End If    exitH:     BeforeUpdate = "[イベント プロシージャ]"   Exit Sub    EditErr:   MsgBox Err.Number & "(" & Err.Description & ")"   Resume exitH    End Sub 'ClsDAOの処理、採番テーブルからIDを取得する Public Function UpdateID(strSQL As String) As Long      Dim TempKeyValue As Long   UpdateID = -1      On Error GoTo NKV_Err   ' 90ms から 150ms の範囲でランダムに遅延時間を設定しする   DBEngine.SetOption dbLockDelay, 90 + Rnd * 60      If Me.objWS Is Nothing Then    Set Me.objWS = DBEngine(0)   End If      'objDBは、クラスのInitiateでSetする。      On Error GoTo errOpenRec   Set Me.objREC = Me.objDb.OpenRecordset(strSQL, dbOpenDynaset, _         dbDenyRead Or dbDenyWrite)      ' リード キャッシュをリフレッシュ   DBEngine.Idle dbRefreshCache      TempKeyValue = Me.objREC.Fields("final_value").Value   NewNo = TempKeyValue + 1      On Error GoTo CommitTransErr      Me.objWS.BeginTrans   Me.objREC.Edit   Me.objREC.Fields("final_value").Value = NewNo '   Me.objREC.Fields("更新日時").Value = Format(Now(), "yyyy/mm/dd hh:MM:ss")   Me.objREC.Update   ' 遅延書き込みキャッシュをフラッシュ   Me.objWS.CommitTrans dbForceOSFlush      Me.objREC.Close   Me.objDB.Close   Me.objWS.Close      UpdateID = NewNo      Exit Function NKV_Abort:   On Error Resume Next   If objREC Is Nothing Then     Me.objREC.Close   End If   If objDB Is Nothing then    Me.objDB.Close   end if   If Me.objWS Is Nothing Then     Me.objWS.Close   End If      Exit Function NKV_Err: '  On Error Resume Next   MsgBox Err.Number & "(" & Err.Description & ") in GetMaxKey_noUpdate procedure"   Resume NKV_Abort      errOpenRec:   MsgBox Err.Number & "([OpenRecordsetエラー]" & Err.Description & ") in GetMaxKey_noUpdate procedure"   Resume NKV_Abort CommitTransErr:   On Error Resume Next   Me.objWS.Rollback   GoTo NKV_Abort      End Function

関連するQ&A

  • 2回目に画面のレコードセットの値が読めない

    メインフォームとサブフォームの画面゛て レコードソースは、ワークテーブルを参照し メインフォームの保存ボタンの処理で、 Private Sub 保存ボタン_Click()  Set mySubFm = Me![テーブル子].Form  Set myParFm = Forms(Me.name) '<== 親フォーム  Set Rec1 = myParFm.RecordsetClone  Set Rec2 = mySubFm.RecordsetClone  Lng受注ID = Rec1.Fields("受注ID").Value  Dim Rtn As Integer  ・レコードセットのデータを、本テーブルに更新する処理  ・自動採番した番号を、レコードセットのIDのフィールドにセット   Rec1.Edit   Rec1.Fields("ID").value = newID   Rec1.Update  ・Me.Requery '<== メインフォームの画面を更新  ・mySubFm.Requery '<==サブフォームの画面を更新  Set Rec1 = Nothing   Set Rec2 = nothing End Sub この処理を一度行い、更に、画面のサブレコードの値を変更して、保存ボタンを再度押すと、 Lng受注ID = Rec1.Fields("受注ID").Value の行で、 「オブジェクトが正しくないか、現在設定されていません」というエラーになります。 この原因はどうしたら解決出来ますでしょうか? よろしくお願いします。

  • Access2007 サブフォームのレコードを一括印刷する方法

    お世話になっております。 サブフォームは帳票型になっており、下記で表示されている全レコードのチェックが入ります。 これと平行して、各レコードを印刷したいのですが、カーソルがあるレコードのみがレコードの数だけ印刷されてしまいます。 これを各レコードごとに印刷したいと思います。 Dim dbs As Database Dim rst As Recordset Dim strSQL As String Set dbs = CurrentDb Set rst = Me.RecordsetClone With rst If .RecordCount > 0 Then .MoveFirst Do Until .EOF .Edit !チェック = True DoCmd.OpenReport "印刷", acNormal, , "コード=" & Me.コード .Update .MoveNext Loop End If .Close End With ご教授いただければ幸いです。よろしくお願いいたします。

  • vb ado → vb2005 ado.net変換

    お世話になります。初めて投稿させていただきます。 VB6.0で下記のようなコードでコンボボックスcboMakerへフィールド値を格納しているのですがこのコードをVB2005のado.netで記述したいのですが可能でしょうか?可能であればどのようなコードを書けばよいのでしょうか。フィールドの値を1レコードづつ取得することは可能なのでしょうか? 初心者ですみません。宜しくお願いします。 Dim con As ADODB.Connection Dim rec As ADODB.Recordset Dim sql As String Dim recCnt As Long con = New ADODB.Connection con.ConnectionString "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=" & パス con.Open() rec = New ADODB.Recordset sql = "SELECT * FROM " & テーブル名 rec.Open(sql, con, adOpenStatic, adLockReadOnly) If rec.RecordCount < 1 Then 'レコードが存在しない MsgBox("未登録です。", G_MB_CAUTION, G_SYSTEM_NAME) Exit Function Else ReDim CboMakerId(rec.RecordCount) End If 'コンボボックスに値を挿入 ※「.List(recCnt)」から値を挿入する With Me.cboMaker .Clear() recCnt = 0 .List(recCnt) = "" .ItemData(recCnt) = 0 Do Until rec.EOF recCnt = recCnt + 1 .List(recCnt) = rec("Name") .ItemData(recCnt) = rec("ID") rec.MoveNext() Loop End With Me.cboMaker.ListIndex = 0 rec.Close() : rec = Nothing con.Close() : rec = Nothing End Function

  • RecordCount(ADO)が変わる?ADP+SQLServer

    ACCESS2000(ADP)+SQLServerにて作成したものですが、 あるクライアント(1台)だけRecordCountがおかしいのです。 <フォームAのボタンクリック時の処理> DoCmd.OpenForm "フォームB", , , , , , Me!コード <フォームBの読み込み時の処理> Dim rs AS ADODB.Recordset Set rs = Me.RecordsetClone rs.Find "コード=" & Me.OpenArgs, 0, adSearchForward If not rs.EOF then Me.Bookmark = rs.Bookmark End if 問題のないクライアント(他の2台)では、 フォームBにてOpenArgに指定したコードが検索され, 該当のレコードが表示されます。 問題のクライアントでは、 「一部」のレコードを指定した場合にレコードが検索されず、 最初のレコードが表示されました。 原因を調べているうちに分かったことは、 Set rs = Me.RecordsetClone で取得したレコードセットがあるタイミングでは、 一部かけた状態になっているということです。 その際に使用した方法は、 Set rs = Me.RecordsetClone rs.MoveLast MsgBox rs.RecordCount MsgBox rs.RecordCount としてレコードの件数を調べて判明しました。 MsgBox rs.RecordCountが2つあるのは記述ミスではありません。 該当のテーブル(レコード)は757件ありますが、 問題のないクライアントでは2回ともに757を返します。 問題のクライアントでは、 1回目のRecordCountは500 2回目のRecordCountは757を返してきます。 しかも、何回も実行していると 1回目が400、450、500とランダムで変化します。 (500が2回続いたりするときもあります) 以上のことから、考えられる原因は何かありますでしょうか。 よろしくお願いいたします。

  • Accessでのログインについて

    Private Sub txtCountPass_AfterUpdate() Dim TextBoxA As TextBox Dim TextBoxB As TextBox Set TextBoxA = Me.txtNamePass ' Set TextBoxB = Me.txtCountPass Const NamePass = "sample" ' Const CountPass = "1234" If TextBoxA = NamePass Then ' If TextBoxB = CountPass Then ' DoCmd.OpenForm "frm_メニュー" ' DoCmd.Close , "frm_パスワード" Else MsgBox "パスワードが異なります。", vbOKOnly + vbCritical End If Else MsgBox "IDが異なります。", vbOKOnly + vbCritical End If End Sub 上記VBAを使ってログインしようとしているのですが、実行されません。frmの2行が間違っているのでしょうか、それとも他が違うのでしょうか?

  • レコード移動について

    単票フォームで何件かレコードがあります。 それを DoCmd.GoToRecord , , acNext で1つずつ移動させ、今何番目のデータなのか?をメッセージで出し、 最後のレコードになったら「最後のレーコード」というメッセージの後に Exit Sub させたいのですが... F8 で1つ1つコンパイルさせるとできるのですが、 データベース画面から直接フォームをDBCLして開こうとすると いきなり「最後のレコード」になってしまいます。 記述のが悪いのでしょうか?それともフォーム自体が悪いのでしょうか? 教えてください Private Sub Form_Current() If Me.CurrentRecord >= Me.RecordsetClone.RecordCount Then MsgBox "最後のレコード" Exit Sub Else MsgBox "途中のレコード" DoCmd.GoToRecord , , acNext   End If End Sub

  • DAOでテーブルの内容を検索したいのですが…

    DAOでテーブルの内容を検索したいのですが… アクセス初心者です。 フォームで取得した値をテーブルで検索して命令するために,次のようなことをしてみましたが,FindFirstのところでエラーがでます。 どうしたらよいのかご指導ください。 コマンドボタンのイベントプロシージャで Private Sub テストテーブル作成_Click() Dim gakki As Integer Dim test As Integer Me.学期 = gakki Me.テスト = test Call testテーブル作成 End Sub として,標準モジュールに Sub testテーブル作成() Dim myDB As DAO.Database Dim myRS As DAO.Recordset Set myDB = CurrentDb Set myRS = myDB.OpenRecordset("T_生徒テスト") myRS.FindFirst "学期ID=" & "" & "gakki" & "" & "AND テストID =" & "" & "test" & "" If myRS.NoMatch = False Then DoCmd.OpenQuery "Q_TSテストA" DoCmd.OpenForm "F_テスト" DoCmd.Close Else DoCmd.OpenQuery "Q_TSテスト" DoCmd.OpenQuery "Q_テスト" DoCmd.Close DoCmd.OpenForm "F_テスト" End If myRS.Close: Set myRS = Nothing myDB.Close: Set myDB = Nothing End Sub としました。よろしくお願いします。

  • これも 教えて欲しい

    Private Sub 問題作成B_Click() '======================================================================= ' 単語の読み '======================================================================= Dim REC_ID(1000) As Long Dim CT, MAX_N, I, J As Integer Dim Q(5) As Long '問題のID登録用 問1_V = "" 問2_V = "" 問3_V = "" 問4_V = "" 問5_V = "" 写1_1_V = "" 写1_2_V = "" 写2_1_V = "" 写2_2_V = "" If 段級_V = 0 Then MsgBox "段か級を入力して下さい。", 0, "段/級 未設定" Exit Sub End If Dim dbsCurrent As Database, rstEmployees As Recordset Set dbsCurrent = CurrentDb Set rstEmployees = dbsCurrent.OpenRecordset("M_読み", dbOpenTable) rstEmployees.Index = "段/数" 'インデクッス CT = 0 rstEmployees.MoveFirst Do Until rstEmployees.EOF If rstEmployees!段か = Me![段か_V] And rstEmployees!段級 = Me![段級_V] Then CT = CT + 1 REC_ID(CT) = rstEmployees!ID End If rstEmployees.MoveNext '次のレコードへ Loop rstEmployees.Close

  • 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

  • Access2010 「演算子がありません」エラー

    フォーム上に別フォームを開くボタンがあるのですが、クリックすると実行時エラーが表示されます。 実行時エラー 3075 クエリ式”コード IN(○○,××)の構文エラー 演算子がありません。 コードを数値型からテキスト型に変更したのが原因だと思います。 エラーが出ない方法を教えていただければ助かります。 よろしくお願いいたします。 Dim rst As Recordset Dim strWhere As String Set rst = Me.RecordsetClone With rst If .RecordCount = 0 Then Beep Exit Sub End If .MoveFirst strWhere = "" Do Until .EOF strWhere = strWhere & IIf(Len(strWhere) > 0, ",", "") & !コード .MoveNext Loop .Close strWhere = "コード IN (" & strWhere & ")" End With DoCmd.OpenForm "フォーム", , , strWhere