- ベストアンサー
画面のレコードセットの値が読めない
- 画面のレコードセットの値が読めないエラーが発生する場合、原因はオブジェクトが正しくないか、設定されていない可能性があります。
- これは、処理の中で使用するオブジェクトが正しく参照されているかを確認する必要があります。
- また、保存ボタンを再度押す前に画面のサブレコードの値を変更した場合、その変更が正しく反映されていない可能性も考えられます。
- みんなの回答 (9)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
回答No.1 です。 # そろそろリモートで状況を探り合いながら考えるのに限界を # 感じてきています。というか手元に今 Access がないのが # どうにもこうにも。 ○On error Resume Nextとエラー処理開始時点で書いて いるのに止まる ⇒ VBA のエラートラップ設定によっては無視されたと思います ○Me.Recordset.Reqeueryとすると、フォームが非連結 になると書いてあり ⇒ Me.Recordset.Reqeuery のように Recordset を直接 Reqeuery してはダメです。フォームと Recordset が 切れちゃいますので。が、今回元々実行していたのは フォームの Me.Reqeuery の実行で、こちらは大丈夫 だったと思うんですけどねぇ。 ○その場合、Me.Requeryではなく、上の Me.RecordSource = Me.RecordSourceとしています ⇒ Requery に頼らずに、Recordset を自分で再作成して RecordSource に入れなおすのは対策案としてはアリ だと思いますが、それで上手くいくかどうかはフォーム の作りに依存するので私には何とも言えません。 そろそろ私のほうも時間切れです (平日は普通に働いており ますゆえ)。大変申し訳ございませんが、私はギブアップ扱い として頂けますでしょうか。 (今日中に何か天啓が閃いたら開陳します。その前に解決する ようでしたら、一言解決しましたと記載しておいてください…)
その他の回答 (8)
回答No.1 です。 既にマルチポストであちこちに問い合わせてらっしゃる ようなので私はこれでギブアップとさせて頂きます。 お役にたてずにすいませんでした。
お礼
お忙しい中、色々とご回答してくださって、ありがとうございました。 なんとか、調べてみます。
補足
実は、 Set Rec1 = Me.RecordsetClone Set Rec2 = Me.Subform.Form.RecordsetClone この処理の後に・・・ Set WS = DBEngine(0) Ws.BeginTrans メインの処理 Ws.CommitTrans ↓ Me.Requery Me.SubForm.Form.Requery ↓ Rec1.close Set Rec1 = nothing Rec2.close Set Rec2 = nothing Ws.Close Set Ws = nothing としていました。 そこで、Ws→Ws.CommitTransの間の全ての処理、WSも含めてコメント化して、実行すると2回目もうまくいきました。 そして、Wsの最初と最後にある二行を非コメント化にすると、エラーになりました。 ということは、このWorkspaceのとらんのBeginと、Commitが悪さをしていたように見えますが、これはどういう事なのでしょうか? 誰かお分かりの方がおられましたら、教えて頂きたいです。 よろしくお願いします。
回答No.1 です。 『【重要】他の画面Formで、ボタンを作成し、以下のソースを 実行しました』見ました。Me.Requery で Recordset がおかしく なっているとしか思えないですね…。 Me.Requery の前後で Recordset の State プロパティの値が どうなるか確認できますか? 何らかの数値だと思いますが、意味は 以下を参考にしてください。 http://msdn.microsoft.com/ja-jp/library/cc389847.aspx # Requery メソッドは Recordset をいったん Close して、再度 # Open (再検索)するという動作をしますので、Requey 後に # Close 状態だとするとおかしいことになります。 Requery の問題とすると、連結フォームの設定(レコードソースの 設定など)が疑わしくなってくるのですが、そちらは大丈夫でしょうか。 なお、『Rec1はNothingではないのだけど、実態がないからRec1.Close が出来ないと言ってるのですが、何故でしょうか?』は、『もう Rec1 は Close 済みだよ、再度 Close は実行できないよ』ということでしょう。
お礼
マイクロソフトのサイトに、 Me.Recordset.Reqeueryとすると、フォームが非連結になると書いてあり、 画面の表示を再表示スル場合には Me.RecordSource = Me.RecordSource としなくてはけないと書いてありましたが、 そのようにコードを変更しても、エラーに成ってしまいます。 問題の保存ボタンの処理で変更したやり方 ✕ Me.Requery ◯ Me.RecordSource = Me.RecordSource Me.サブフォームコントロール名.Form.RecordSource = _ Me.サブフォームコントロール名.Form.RecordSource あとは、全てのエラー処理をコメントかし、On Error Goto ...もコメント化にして ボタンクリック処理の最初で、以下のコードを実行すると、 Set Rec1 = Me.RecordsetClone '<==2回目実行時にここでエラーになります。 Set Rec2 = mySubFm.RecordsetClone しかし、簡単なテーブルで、1回のボタンクリック時の処理で、繰り返してRstを取得する方法では、成功しました。(ソースは前出) その場合、Me.Requeryではなく、上のMe.RecordSource = Me.RecordSourceとしています。 サブフォームは、メインフォームのレコードソースを再設定すると、自動で再設定されるのでしょうか? よろしくお願いします。
補足
■全く【同じ現象】 >『【重要】他の画面Formで、ボタンを作成し、以下のソースを >実行しました』見ました。Me.Requery で Recordset がおかしく >なっているとしか思えないですね…。 試しに、新しいAccess2013ファイルを作成し、テーブル1個、数行のデータをセットし、IDはオートナンバー型 そして、それからフォームをウィザードを使用して作成して、ボタンを配置。クリックイベントで問題のソース(前回の事例参照)を実行しましたら、全く【同じ現象】が起きてしまいましたぁぁぁぁ!!!!! それと、 >Me.Requery の前後で Recordset の State プロパティの値が >どうなるか確認できますか? これはADO専用のプロパティーとお見受けしますが、DAOではRec.と書いても、Stateのようなプロパティーはありませんでした。 http://msdn.microsoft.com/ja-jp/library/cc389847.aspx ># Requery メソッドは Recordset をいったん Close して、再度 ># Open (再検索)するという動作をしますので、Requey 後に ># Close 状態だとするとおかしいことになります。 新規MDBでも同じ事が起きるというのは、何故でしょうか? >Requery の問題とすると、連結フォームの設定(レコードソースの >設定など)が疑わしくなってくるのですが、そちらは大丈夫でしょうか。 レコードソースは、普通に、1個テーブルを選択して「*」をクリックして、それにリレしーションシップをつけている別テーブルを1個挿入して、→でIDを関連付けさせているだけです。 問題があるようには見えません・・・ >なお、『Rec1はNothingではないのだけど、実態がないからRec1.Close >が出来ないと言ってるのですが、何故でしょうか?』は、『もう Rec1 は >Close 済みだよ、再度 Close は実行できないよ』ということでしょう。 On error Resume Nextと エラー処理開始時点で書いているのに、 If Not (Rec1 is nothing) then Rec1.close '<==★ここでエラーになりますが・・・何故でしょうか? Set Rec1 = Nothing end if デバッグモードだから?
おはようございます。回答No.1 です。 > ?Rec1.AbsolutePosition > 'オブジェクトが設定されていないか、現在設定されていません なるほど。これはおそらく、2回目実行の時には myParFm.Recordset も myParFm.RecordsetClone も Nothing になっていますね。 # Rec1.AbsolutePosition がそのエラーになることから、間接的に # Rec1 が Nothing であること、その元である myParFm.RecordsetClone # も Nothing であるだろうことを推定しています。 # 念のため直接確認されることをお勧めしますが。 回答No.2 の捕捉から、Requery 実行直後では、 myParFm.RecordsetClone は Nothing ではなかったのですよね? そうすると、 『Requery 実行直後から2回目実行までの間に Recordset が消えた』か 『1回目と2回目で Forms(Me.name) で取得されるフォームが実は違う』 あたりが怪しいことになります。 前者である場合は、記載頂いたコード以外の、特にイベント駆動なコード が意図せずに動いていないかがポイントになります。どこで Nothing に なるのか確認する地道な作業になりますよ。(Accessは作るのは簡単なの ですが、いちどトラブルになると大変なことになりやすいです…) 後者は何ですかね? 同じ名前のフォームが複数作られているんですかね (そんなことが本当に できるかは何ともですが) こちらは Requery 実行直後に Forms(Me.name) から Rec1 を取得し なおして、Rec1 が Nothing になるかどうか、まずは確認でしょうか。 これで Rec1 が Nothing になるようなら、フォームの取得に Forms(Me.name) ではない別の手段を考えたほうが良いでしょう。 # Set Rec1 = myParFm.RecordsetClone ではなく # Set Rec1 = Me.RecordsetClone で良さそうな気がするんですが、 # それじゃダメなんですかね?
補足
ご回答大変ありがとうございました。十年以上ぶりのアクセスの開発ですが、全くのゼロから全て作るのは初めてですので、結構パニクっています… ※ 最後に、「■■再テスト結果■■」を記載しました。 また、【重要】の箇所も必ず読んで頂き、考えられる原因がわかれば教えて頂きたいです。 よろしくお願いします。・・・ 以下、私の返信です。 >なるほど。これはおそらく、2回目実行の時には >myParFm.Recordsetも myParFm.RecordsetClone も >Nothing になっていますね。 →もう一度テストをしなおしていますが・・・ ?myParFm.RecordsetClone is nothing : False ?Not(myParFm.RecordsetClone is nothing) : True となります。 そして、Rec1, Rec2の<Is Nothing>は Falseです。 そして、2回目にエラーが出た時、そのままスルーすると最後のエラー処理で □□□□□□□ If Not (Rec1 Is Nothing) Then 'MainFormのレコードセット Rec1.Close '<===ここでエラーになる Set Rec1 = Nothing End If □□□□□□□ Rec1はNothingではないのだけど、実態がないからRec1.Closeが出来ないと言ってるのですが、何故でしょうか? ># Rec1.AbsolutePosition がそのエラーになることから間接的に ># Rec1 が Nothing であること、その元である > myParFm.RecordsetClone ># も Nothing であるだろうことを推定しています。 ># 念のため直接確認されることをお勧めしますが。 →ここは、私の再テスト結果の通り、Nothingではなかったです。 >回答No.2 の捕捉から、Requery 実行直後では、 >myParFm.RecordsetClone は Nothing ではなかったのですよね? →そうですが、2回目実行時もNothingではないです。 >『Requery 実行直後から2回目実行までの間に Recordset が消えた』か >『1回目と2回目で Forms(Me.name) で取得されるフォームが実は違う』 >あたりが怪しいことになります。 →1回目と2回目での取得する親フォーム名は同じでした。 因みに、フォーム名の最後に02をつけたものを新しく作りましたが、これでも同じ現象が起きます。 フォームをコピーセず、新しくテーブルから作り、テキストボックスやラベル、ボタン類は、元のフォームからコピーして作りましたが。 この画面を開く前に、レコードソースの親と子のWorkテーブルのレコードを全て削除し、本テーブルから必要な物だけInsertしていますが、これは影響はないと思います。 画面はDialogモードで開き、データ追加が出来ないように設定しています。 >前者である場合は、記載頂いたコード以外の、 >特にイベント駆動なコードが意図せずに動いていないかがポイントになります。 →画面のイベント、子のイベントを確認しましたが、変数に値をセットするか、または、ボタンのEnabledプロパティの設定ぐらいしかしていません。複雑なのは保存ボタンぐらいです。 しかし、保存ボタンを押した処理で、Set Rec1 = ... と設定していますから、たとえ、その1回目の処理と2回目の処理の間でイベントが走るとしても、フォーム自体のレコードソースを消さない限り、このようなことが起きるとは考えにくいです。 保存ボタン処理で、最後に myParFm.Requery mySubFm.Requery としているのが、唯一レコードセットに影響がありそうなところです。 サブフォームの枠の名前で Me.サブフォームの枠名.Form.Requeryと変えましたが、これでもエラーが2回目に発生します。 サブフォームのRequeryをコメントかし Me.Requeryだけにしてもエラーが2回目に出ます。 >同じ名前のフォームが複数作られているんですかね →ありえないですが、フォームをコピーして別フォームを作成した場合、その新しいフォームのイベントソースを開こうとすると、本フォームのイベントのソースが開いてしまうという変な挙動が時々見られます。それからは、できるだけ、フォームをコピーして作るのは避けていますが。 >こちらは Requery 実行直後に Forms(Me.name) から Rec1 を取得し >なおして、Rec1 が Nothing になるかどうか、まずは確認でしょうか。 →【重要】他の画面Formで、ボタンを作成し、以下のソースを実行しました。 Private Sub コマンド86_Click() Dim Rst As dao.Recordset Set Rst = Me.Recordset MsgBox "ID: " & Rst.Fields("ID").Value Me.Requery Set Rst = Me.Recordset MsgBox "ID: " & Rst.Fields("ID").Value End Sub すると、同じエラーになりました。 どうやら、私のアクセスでは、何故かわかりませんが、Requeryをすると、レコードセットが取得出来ない現象が起きているようです。こういうことは他の人でも経験あるのでしょうか? どうしたら良いのでしょうか。また考えますが、最悪、Requeryしない方法となると、もう出来る事が限られてきます。 ■■再テスト結果■■ ★の部分はご回答に関係しているのでつけました。 1. Set Rec1 = myParFm.RecordsetClone (1)1回目→成功 ・myParFm: CurrentRecord : 1 ・myParFm.RecordsetClone Is Nothing -> False ・Not(myParFm.RecordsetClone Is Nothing) => True ・Rec1.AbsolutePosition: -1 ・Rec1.RecordCount: 1 ・Rec1 Is nothing : False★ ・Rec1 Not(is nothing): True (2)2回目→失敗 ・エラーメッセージ:3420/ オブジェクトが正しくないか、現在設定されていません。 ・myParFm: CurrentRecord : 1 ・myParFm.RecordsetClone Is Nothing -> False ・Not(myParFm.RecordsetClone Is Nothing) => True ・mySubFm→myParFmと同じ結果 ・Rec1.AbsolutePosition: 3420エラー ・Rec1.RecordCount: 3420エラー ・Rec1 Is nothing : False★ ・Rec1 Not(is nothing): True ・Rec2は、Rec1と同様のエラー 2. Set Rec1 = Me.RecordsetClone (1)1回目→成功 ・Me.CurrentRecord: 1 ・Me.RecordsetClone Is Nothing: False★ ・Not(Me.RecordsetClone is Nothing): True ・mySubFm...Meと同様 ・Rec1.AbsolutePosition: -1 ・Rec1.RecordCount: 1 ・Rec1 Is nothing : False★ ・Rec1 Not(is nothing): True ・Rec2→Rec1と同じ (2)2回目→失敗 ・Me.CurrentRecord: 1 ・Me.RecordsetClone is nothing : false★ ・not(Me.RecordsetClone is nothing) : True ・mySubFm→Meと同じ結果 ・Rec1.AbsolutePosition: 3420エラー ・Rec1.RecordCount: 3420エラー ・Rec1 Is nothing : False★ ・Rec1 Not(is nothing): True ・Rec2は、Rec1と同様のエラー ■----------■
回答No.1 です。 > ■1の場合 > Set Rec1 = myParFm.Recordset.Clone > ここでエラーになりました。 いやいやいや、1. の場合は myParFm.RecordsetClone を確認してください。(Recordset と Clone の間にドット はないですよ) 私の回答No.1のアドバイスが正しいとは限らないので、 念のため大本の現象をきちんと整理したいと思ったわけで。
補足
早とちりしてしまい、どうもすみません。見落としていました テスト結果を書きます。 このモジュールのトップには Option Compare Database Option Explicit と書いてあります・・・ 念のため ■ソース Set mySubFm = Me![テーブル子].Form Set myParFm = Forms(Me.name) Set Rec1 = myParFm.RecordsetClone '...1 Set Rec2 = mySubFm.RecordsetClone '...2 Lng受注ID = Rec1.Fields("受注ID").Value '...3 ■テスト結果 1. Set Rec1 = myParFm.RecordsetClone これでエラーになりませんでした。 ◎イミディエイトは・・・ ?Rec1.AbsolutePosition 'オブジェクトが設定されていないか、現在設定されていません ?Rec1.Fields.Count -->'オブジェクトが設定されていないか、現在設定されていません 2. Set Rec2 = mySubFm.RecordsetClone ここでもエラーになりません。 ◎イミディエイトは・・・ ?Rec2.AbsolutePosition 'オブジェクトが設定されていないか、現在設定されていません ?Rec2 is nothing → False ?Rec2.RecordCount → 'オブジェクトが設定されていないか、現在設定されていません ?Rec2.EOF → 'オブジェクトが設定されていないか、現在設定されていません 3. Lng受注ID = Rec1.Fields("受注ID").Value この行に来て、エラーとなりエラー処理に進む・・・ ◎イミディエイトは・・・ ?Rec1.RecordCount → 'オブジェクトが設定されていないか、現在設定されていません ?Rec1.AbsolutePosition → 'オブジェクトが設定されていないか、現在設定されていません ?Rec1.Fields("物件管理ID") is nothing ?isnull(Rec1.Fields("物件管理ID")) 全て、→ 'オブジェクトが設定されていないか、現在設定されていません となりました。 何故、最初の1, 2でエラーにならないのでしょうか? それに、原因が何なのかまだわかりません。何かわかりましたら、教えていただけると非常に助かります。 よろしくお願いします。
現象を整理してください。発生するエラーの場所と内容が 整理されないと、ドツボにはまる一方です。 1. Set Rec1 = myParFm.RecordsetClone の場合 Lng受注ID = Rec1.Fields("受注ID").Value で 「オブジェクトが正しくないか、現在設定されていません」 エラーになる。 ⇒ Rec1、Rec1.Fields、Rec1.Fields("受注ID") のどれかが Nothing になっていませんか? ⇒ Rec1.RecordCount プロパティの値はどうなって いますか? ⇒ Rec1.Fields("受注ID").Value を見る前に、 Rect1.MoveFirst メソッドを実行したらどうなり ますか? 2. Set Rec1 = myParFm.Recordset.Clone の場合 エラーになるのは2回目ですか? エラーの内容は?
お礼
■2の場合・・・Set Rec1 = Me.Recordset.Clone の場合 エラーになるのか、2回目です。1回目は成功します。 1も、同様で、2回目に失敗します。
補足
お時間をかけて頂き大変ありがとうございます。感謝します。 早速、もう一度やってみました。 ■1の場合 Set Rec1 = myParFm.Recordset.Clone ここでエラーになりました。 ...3420「オブジェクトが正しくないか、現在設定されていません」 ◎イミディエイトで見ると・・・ ?myParFm.Recordset is nothing → False ?myparfm.CurrentRecord → 1 ?Rec1 is nothing → True ?Rec1.Fields is nothing → 'ウィズブロック変数が設定されていませんというエラー ?myParFm!受注ID → 11 ■2の場合・・・Set Rec1 = Me.Recordset.Clone の場合 Set mySubFm = Me![Form子].Form '<--OK Set myParFm = Forms(Me.name) '<==OK Set Rec1 = Me.Recordset.Clone '<==ここでエラー エラー内容は、1と同じものです。 ◎イミディエイトでみると・・・ ?me.Name → 「フォーム親」OK ?me.CurrentRecord → 1 ?me.Recordset is nothing → False ?me.RecordsetClone is nothing → エラー:オブジェクトが正しくないか、現在設定されていません この最後のRecordsetと、RecordsetCloneの Is Nothingの結果の違いはなんか変ですね・・・
回答No.1 です。 Lng受注ID = Rec1.Fields("受注ID").Value でエラーに なるのですよね? Rec1 か Rec1.Fields か Rec1.Fields("受注ID") のどれか が Nothing なんだと思うのですが、どれでしょう? (もしくは Nothing ではなけど、オブジェクトが壊れて いるか)
お礼
というか、最初は、以下のように書いていました。 Set mySubFm = Me![テーブル子].Form Set myParFm = Forms(Me.name) '<== 親フォーム Set Rec1 = myParFm.RecordsetClone '<==(2) Set Rec2 = mySubFm.RecordsetClone Lng受注ID = Rec1.Fields("受注ID").Value '<=== ★01 そして、★01の箇所で先に記載しましたエラー内容が発生していました。 そして、次に(2)の行を Set Rec1 = Me.Recordset.Clone '<==(2') と書き換えたところ、この(2')でエラーが起き始めました。 不可解です。
補足
No.2の補足にも、描かせていただきましたが 良く確認してみると、エラーが起きるのは以下の行でした。焦っていて、確認不足でした。すみません。 Set Rec1 = Me.Recordset.Clone '★これでもエラーになる。 Lng受注ID = Rec1.Fields("受注ID").Value ←ここまでは行くことが出来ません。。。
回答No.1 です。 Ws.CommitTrans は今回の現象とは関係ないかと。 確認してほしいのですが、Me.Requery を実行した 直後の myParFm.RecordsetClone はどうなっている でしょうか? Nothing になっていたりするでしょうか。 もし、Nothing になっているのであれば、現在の画面の 実装が Requery を使えるようになっていない可能性が あります。 例えば、Rec1.Restartable プロパティの値はどうなって いるでしょうか? False の場合は Requery を使えません。
補足
イミディエイトウィンドで、以下のように試しました。 ?Rec1.Restartable True ?Rec2.Restartable True ?myParFm.RecordsetClone is nothing False ?mySubFm.RecordsetClone is nothing False これは、保存ボタン_click処理の最後の方にある ・Me.Requery ・mySubFm.Requery を実行後にしました。 ちなみに、保存ボタンクリック2回目(サブフォームのレコードを変更して再度ボタンを押した時)には、 以下のように変えてみましたが、やはり、エラーになります。エラーの起きる行は★印です。 Set mySubFm = Me![Form子].Form Set myParFm = Forms(Me.name) '<== 親Form ' Lng受注ID = Me.受注ID.Value 'Set MainRec = myParFm.Recordset.Clone '<==これはやめて以下の行に変えた Set MainRec = Me.Recordset.Clone '★これでもエラーになる。 'Set SubRec = mySubFm.Recordset.Clone Set SubRec = Me![F00_K00物件管理テーブル子].Form.Recordset.Clone 何か、お気づきになりましたら、アドバイスを教えてください。
Rec1 をどこかで Close していたりしませんか? とりあえず、 Set Rec1 = myParFm.RecordsetClone ではなく、 Set Rec1 = myParFm.Recordset.Clone にして みたらどうですかね。
お礼
試しに、Ws...のところをコメントにしましたが、やはり、同じエラーが出ます。 エラーが出るのは、PGの最初で、画面のレコードセットを生成する時ですので、まだRst.Closeもしていません。 Rst.Close は、全ての処理が終わった時にしています。
補足
恐らく、重要な事を書き忘れていました。 Dim Ws as DAO.Workspaceとして 以下の指定の箇所に入れています。↓ 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 Ws.BeginTrans '<== 全ての更新処理の前に、WorkspaceのBeginTransを実施 ◎メインフォームの本テーブルへの保存処理 ◎ループ処理 Do while Rec2.EOF = False ・レコードセットのデータを、本テーブルに更新する処理 ・自動採番した番号を、レコードセットのIDのフィールドにセット Rec1.Edit Rec1.Fields("ID").value = newID Rec1.Update Loop Ws.CommitTrans dbForceOSFlush '<== Commit ・Me.Requery '<== メインフォームの画面を更新 ・mySubFm.Requery '<==サブフォームの画面を更新 Set Rec1 = Nothing Set Rec2 = nothing End Sub このWk.CommitTrans 何か悪さするのでしょうか?
お礼
ありがとうございました。 この後の問い合わせ、この問題の解決については、hatenaさんの「hatena の Microsoft Access 掲示板」において引き続きさせて頂きたいと思います。 http://hatena-access.progoo.com/bbs/