Microsoft Access 掲示板

parent.refreshでレコードとフィールドの位置が先頭になってしまう。

17 コメント
views
4 フォロー

宜しくお願い致します

サブフォームから親フォームのレコード更新のため、Parent.refreshを行うとサブフォームの先頭レコードかつ先頭フィールドにフォーカスが移動してしまいます。

親フォームのレコード更新をフォーカスが移動せずに行なう方法はありますか?

あん
作成: 2023/05/31 (水) 11:00:54
通報 ...
1

Parent.Requeryではなくて、Parent.Refresh で間違いないですか。

当方で簡単なサンプルを作成して試してみましたが、そのような現象は確認できませんでした。

Parent.refresh はサブフォームのどのイベントに記述してますか。そのイベントプロシージャ全体を提示してもらえますか。

2
あん 2023/05/31 (水) 12:29:08 927ea@06086

hatena様、ご返答ありがとうございます。

先ほどは確かにフォーカスが移動してしまっていたのですが、いろいろコードをいじっていたらならなくなりました。
すみませんでした。

ですが、Parent.parent.refreshというのもあるのですが、
こちらは実行すると親フォーム(親の親ではなく)の先頭フィールドに移動してしまいます。

コードは以下の通りです。長すぎるので全ては載せきれません。

    If Parent.Parent!書式ID <> 10 And Parent.Parent!書式ID <> 16 And Parent.Parent!書式ID <> 17 Then

        Select Case Parent.Parent!書式ID

            Case 1, 3, 5

                Parent.Parent!巻替検査記録 = True   ←チェックボックス(テーブルと連結)
                Parent.Parent!巻替検査記録ボタン.Visible = True ←コマンドボタン

                Parent.Parent.Refresh  ←ここを処理すると画面の位置が上へ移動してしまいます。

3
あん 2023/05/31 (水) 12:40:25 927ea@06086

追加です。
イベントは、Private Sub Form_AfterUpdate()
です。

4
あん 2023/05/31 (水) 12:49:32 927ea@06086

一番親のフォームはテーブル連結で、いくつかのコマンドボタンとそのボタンの表示非表示の状態を示すチェックボックスがあります。

その子フォームは一番親フォームのボタンを押すと、指定のフォームがソースオブジェクトになり、画面が表示されるようになっています。

その子フォームの子フォームが帳票フォームになっております。そこからの処理です。

5

「先頭レコードかつ先頭フィールドにフォーカスが移動」
「先頭フィールドに移動」
「画面の位置が上へ移動」

複数の表現が混在していますが、現状の動作はどれでしょうか。

また、サブフォームの更新後処理で実行されているのなら、フォーカスはサブフォームにあるはずですので、「先頭フィールドにフォーカス移動」というのは、Refresh では発生するはずがないです。フォーカス移動させるような処理がどこかにあるのではないですか。

6
あん 2023/05/31 (水) 14:35:40 927ea@06086

Parent.parent.refreshの問題に関しては、「先頭フィールドに移動」です。
先頭フィールドに移動し、それにつれて画面が上に移動します。

Parent.parent.refreshの部分でブレークポイントを設定し、そこまではフォームもそのままです。
しかし、ステップインし、コードを実行すると、画面が上に移動します(先頭フィールドに移動)。

処理の中にはSetfocus等の処理は全くありません。

7
あん 2023/05/31 (水) 15:20:13 927ea@06086

別途、簡単なサンプルDBを作り、同じような構成(単票フォームの中に単票フォーム、その中に帳票フォーム)にしました。

その結果、一番子フォームの帳票フォーム内で、先頭レコードに移動する、という結果になりました。

Refreshでもレコードの移動があるようですが。

ファイルをアップできれば、見ていただけるかと思いますが、無理ですね。

8

孫フォームで入力してレコード保存すると(更新処理)、親フォーム(Parent.parent)にフォーカス移動して、画面がスクロールして、先頭フィールドへフォーカスが移動するということですか。

こちらで下記のようなサンプルを作成して実験してみましたが、症状は再現できませんでした。

親テーブル、子テーブル、孫テーブルを作成してサンプルデータを入力。
それぞれをソースとするフォームを作成して、親テーブルフォームに子テーブルフォームをサブフォームとして配置。
子テーブルフォームに孫テーブルフォーム(帳票フォーム)をサブフォームとして配置。

孫テーブルフォームの更新後処理に下記のように記述。

Private Sub Form_AfterUpdate()
    Parent.Parent!チェック1 = True
    Parent.Parent!コマンド6.Visible = True
    Parent.Parent.Refresh
End Sub

親フォームへフォーカス移動しませんでした。

かなり複雑なことをしているようですし、こちらで状況を再現できないので、こちらから原因を特定するのは困難です。

まずは、現状の各フォームのコードをコメントアウトして、孫フォームの更新後処理の下記の部分だけコメントアウトを解除してサブフォームで更新してShift+Enterでレコード保存した場合、症状は出ますか。

                Parent.Parent!巻替検査記録 = True
                Parent.Parent!巻替検査記録ボタン.Visible = True
                Parent.Parent.Refresh
9

上記の回答を書いてから下記の追記に気が付きました。

その結果、一番子フォームの帳票フォーム内で、先頭レコードに移動する、という結果になりました。

孫フォームで先頭レコードへ移動するという現象ですか。
それなら、当方のサンプルでも現象を再現できました。

ちょっと対策を検討してみますのでお待ちください。

10
あん 2023/05/31 (水) 15:51:06 修正 927ea@06086

hatena様、ありがとうございます。

ご指示の内容を行なってみましたが、やはり症状は出ます。

なお、
「孫フォームで入力してレコード保存すると(更新処理)、親フォーム(Parent.parent)にフォーカス移動して、画面がスクロールして、先頭フィールドへフォーカスが移動するということですか。」
について。

親フォーム(Parent.parent)にフォーカス移動して → 中間のフォーム(Parent)にフォーカス移動して
です。

すみません。遅くなりましたが、大事なことを伝え忘れていました。
テーブルはSQL ServerよりODBCリンクです。

11

3階層のサブフォーム構成の場合、一番上のフォームでRefreshすると、3番目のサブフォームは再読込されるという仕様のようです。なぜこのような仕様なのか1ユーザーからは伺いすることはできませんが、各リンクテーブルのデータ整合性を保つために必要なことなのかもしれません。どちらにしても、このような内部処理をユーザーから変更するのは難しいかと。

とりあえず、当方のサンプルでは、

Private Sub Form_AfterUpdate()
    Parent.Parent!チェック1 = True
    Parent.Parent!コマンド6.Visible = True
'    Parent.Parent.Refresh
End Sub

というようにRefreshをコメントアウトしておくと、先頭レコードへ移動せずにチェックが入りました。
ただし、テーブルにはすぐには反映せずに、メインフォームへフォーカスを移動するとテーブルに反映されました。

※「チェック1」はチェックボックス名

Accessのローカルテーブルでの確認ですので、SQL Serverだと動作が異なるかもしれません。

12
あん 2023/06/01 (木) 10:13:44 927ea@06086

なるほど。そういう仕様もあるのですね。
ユーザーからは制御不能ですよね。

Parent.parent.Refreshを行わないと、すぐにはテーブルに反映しないのが引っかかります。
フォーカスを移動するなど、レコードを保存するタイミングにならないと保存されないと、
それまでの間にAccessがクラッシュやフリーズした際にレコードが保存されないのが問題になりますよね?

以下のどちらかを取るかと思っています。
Refreshをして、レコードが移動してしまい、ユーザー操作がやりづらくなったり入力ミス等が発生するかもしれないが、データの完全性を保持する事を優先するか。

Refreshをせず、レコードが移動しないことで、ユーザー操作に影響がないが、データの完全性に大きなリスクを背負わせるか。

hatena様ならどちらを取りますか?それとも他のお考えがございますか?

13

Parent.parent.Refreshを行わないと、すぐにはテーブルに反映しないのが引っかかります。
フォーカスを移動するなど、レコードを保存するタイミングにならないと保存されないと、
それまでの間にAccessがクラッシュやフリーズした際にレコードが保存されないのが問題になりますよね?

これを気にするなら、Parent.parentのチェックボックスは非連結にしておいて、レコードソースのテーブルのフィールドを更新クエリかDAOまたはADOで直接更新するようにすればどうでしょう。

14

DAOで、フォームのレコードセットのコピーを生成して、それに対して更新する方法でどうだろう。

Private Sub Form_AfterUpdate()
    With Parent.Parent.Recordset.Clone 'フォームのレコードセットのコピー
        .Bookmark = Me.Bookmark 'カレントレコードを同期
        .Edit
        !chk = True
        .Update
    End With
    Parent.Parent!チェック1 = True
    Parent.Parent!コマンド6.Visible = True
End Sub

Chk はレコードソースのフィールド名
Chk1 はチェックボックス名(非連結)

チェックボックスは非連結なので、親フォームのレコード移動時にフィールド値を代入するなどの処理は別に必要。

ちょっと今出先なので、サンプルで動作確認してはしていませんので、うまくいくかは不確定。

15
あん 2023/06/01 (木) 12:16:28 927ea@06086

分かりました。
DAOの方法でやってみます。
他の作業が入ってきたので、やってみたら、またご連絡いたします。

ありがとうございます。

16
あん 2023/06/05 (月) 10:37:33 927ea@06086

DAOの方法でうまくいきました。
Recordset.Cloneのおかげで、フォーカスが移動せずに済んでいます。
ありがとうございました。

17

うまく行きましたか。それはよかった。

前の回答でも書きましたが、チェックボックスは非連結なので、レコード移動時やユーザーがチェックボックスを更新した場合にテーブルと同期させる処理は必要なのでご留意ください。