🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
VBA

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

Access

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

Q&A

解決済

1回答

2580閲覧

ACCESSにてサブフォーム付きのフォームを新規ページに複製したい。

death-o

総合スコア1

VBA

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

Access

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

0グッド

0クリップ

投稿2023/03/06 15:52

実現したいこと

ACCESSにてサブフォーム付きのフォームを新規ページに丸ごと複製したい。

前提

このたびはお世話になります。
vbaのコピー&ペーストについてです。
サブフォーム付きのレコードを丸々新規レコードにコピーする方法を探しております。

まず、親フォームをコピー→新規レコードに複製
そのあと、元レコードに戻って、サブフォームに移動→コピー(ここまでは作動しております)
新規レコードに戻って、サブフォーム移動→コピー

このタイミングで、サブフォームの内容が反映されません。

ちなみにコピー内容はエクセルにペーストしてみたところ、ちゃんとコピーされておりました。

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

サブフォームにいくつか更新後処理項目があり、それぞれのプロシージャがあるのですが、
これらのvbaに強制的にとばされていることがわかりました。
そして、すべての更新後処理の項目をサブフォームのデータ数分周回した後、再び元のvbaに戻ってきて一連のプログラムが終わるようなことになっております(この手順ですとサブフォームの内容は反映されます)。

ですがステップインでなく実際に実行すると、サブフォームの内容は白紙のままで止まってしまいます。
サブフォームの内容をコピペするにはどのようにすればよいでしょうか?

該当のソースコード

◆親フォームのコピペ
DoCmd.RunCommand acCmdSelectRecord 'レコードの選択
DoCmd.RunCommand acCmdCopy 'コピー
DoCmd.RunCommand acCmdRecordsGoToNew '新規レコードへ
DoCmd.RunCommand acCmdSelectRecord
DoCmd.RunCommand acCmdPaste '貼り付けを実行

◆コピー元のレコードに移動
Dim rst As Recordset
Dim varBookMark As Variant
Set rst = Me.Recordset 'フォームのレコードセットを変数にセットします
varBookMark = rst.Bookmark 'レコードセットのブックマークを取得します
Me.Requery'フォームを再クエリーします
rst.Bookmark = varBookMark 'カレントレコードを保存されているブックマークに設定します
(T’s Wareさんより引用)

◆元のサブフォームをコピー
On Error Resume Next
'再描画を停止
Echo False
'サブフォームにフォーカスを移動
Me!サブフォーム.SetFocus
'すべてのレコードを選択
DoCmd.RunCommand acCmdSelectAllRecords
'[コピー]を実行
DoCmd.RunCommand acCmdCopy
'再描画を再開
Echo True

◆Me.作業日.SetFocus’親フォームに移動→コピーした新規親フォームに移動
DoCmd.RunCommand acCmdRecordsGoToLast

Me!サブフォーム.SetFocus
DoCmd.RunCommand acCmdRecordsGoToNew '新規レコードへ
DoCmd.RunCommand acCmdSelectRecord
DoCmd.RunCommand acCmdPaste '貼り付けを実行
↑ここでトラブルが起きています。更新処理のプロシージャに飛ばされます。

Me.作業日.SetFocus
Me.Refresh

試したこと

デバッグのステップインで調べてみたところ、
すべての更新後処理の項目をサブフォームのデータ数分周回した後、再び元のvbaに戻ってきて一連のプログラムが終わるようなことになっております(ちなみに、この手順ですとサブフォームの内容は反映されます)。

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

使用環境
ウインドウズ10
Access2016

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

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

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

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

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

guest

回答1

0

ベストアンサー

コピー&ペーストでは、フォームの更新関係のイベントは実行されないというのはAccessの仕様のようです。

コピー&ペーストではなくVBAでレコードセットを利用してデータ転記するようにして、同時に更新後処理と同様のコードを実行するように設計変更することをお勧めします。
あるいは、同様の処理をする追加クエリを実行するという方法も考えられます。

詳細が不明なので、とりあえずサブフォームの方の簡単なサンプルコードを提示ておきます。
サブフォームのレコードソースのフィールドは F1, F2, F3, F4 と仮定。

vba

1 Dim rs1 As DAO.Recordset 2 Set rs1 = Me.サブフォームコントロール.Form.RecordsetClone 'サブフォームのレコードセットの複製 3 Dim rs2 As DAO.Recordset 4 Set rs2 = CurrentDb.OpenRecordset("テーブル1", dbOpenTable, dbAppendOnly) 'サブフォームのレコードソースのテーブルのレコードセット 5 6 rs1.MoveFirst 7 Do Until rs1.EOF 8 rs2.AddNew 9 rs2!F1.Value = rs1!F1.Value 10 rs2!F2.Value = rs1!F2.Value 11 rs2!F3.Value = rs1!F3.Value 12 rs2!F4.Value = rs1!F4.Value 13 14 '更新後処理と同じ処理 15 16 rs2.Update 17 rs1.MoveNext 18 Loop

投稿2023/03/07 03:13

hatena19

総合スコア34073

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

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

death-o

2023/03/07 05:08 編集

この度はご返信ありがとうございます。 明快にわかりやすく、とても感謝しております。 すいません、ご回答につきましていくつか質問があります。 まず'更新後処理と同じ処理、書いている部分ですが、 プロシージャをそれぞれPrivate Sub フィールド名_AfterUpdate()~end sub内に記述しているので、 その内容をそれぞれつらつらと書いていってみましたが、「メソッドまたはデータ メンバが見つかりません」となってしまいました。 むしろ更新関係を無視して項目だけを貼り付ける、という挙動で構わないのですが、その際も更新後処理と同じ処理の記述は必要ですか?
hatena19

2023/03/07 06:16

サブフォームの更新後処理のコードをそのままではだめです。 更新後処理に何をしているのか不明なのですが、サブフォーム内のコードだとサブフォームのコントロールとかフィールドに対しての処理だと思いますが、それをレコードセットに対する処理に書き換える必要があります。 > むしろ更新関係を無視して項目だけを貼り付ける、という挙動で構わないのですが、その際も更新後処理と同じ処理の記述は必要ですか? それなら、更新後処理は必要ないです。
death-o

2023/03/07 07:32

ご返信ありがとうございます。 そのままコピペして使わせていただきましたが、現状うまく作動しておりません。 サブフォームのテーブルにレコードが記録されません。 少し理解を深めたいのですが、 rs1を設定、セット前に、まず複製したいレコードに行っておく必要がありますよね? そこで、まず自分の記述している◆コピー元に移動をした後、ご教授いただいたコードを付け加えました。 そして、rs2という新しいレコードセットをサブフォームのテーブルに新規レコードとして入力していく、という作業かと思うのですが、この解釈であってますでしょうか?
hatena19

2023/03/07 07:57 編集

> rs1を設定、セット前に、まず複製したいレコードに行っておく必要がありますよね? はい、そうです。 > そして、rs2という新しいレコードセットをサブフォームのテーブルに新規レコードとして入力していく、という作業かと思うのですが、この解釈であってますでしょうか? 正確にいうと、 サブフォームのレコードセット(rs1)を先頭から最後まで移動しながら、そのカレントレコードのデータを、サブフォームのレコードソースのテーブルに順次新規追加していくという作業になります。 うまく行かないということですが、エラーメッセージとかでてませんか。出ているならそれを提示してください。 また、デバッグでステップ実行するなどして、想定通りの動作になっているか確認してみてください。
death-o

2023/03/07 13:45

ご返信遅くなりました。 >>サブフォームのレコードセット(rs1)を先頭から最後まで移動しながら、そのカレントレコードのデータを、サブフォームのレコードソースのテーブルに順次新規追加していくという作業になります。 ということは、データの移行は、テーブルのフィールドを『全て』 rs2.AddNew rs2!F1.Value = rs1!F1.Value rs2!F2.Value = rs1!F2.Value rs2!F3.Value = rs1!F3.Value rs2!F4.Value = rs1!F4.Value にて新規追加ということですね。 私は、表示に必要とされるフィールド(F○)だけを記述しておりました。 これではダメなのですね。 >>エラーメッセージとかでてませんか。 エラーが全く出ません。 また、その時々によって挙動が変わったりします。 例えば親フォームのコピぺも、今日のステップインではBeforeUpdateのプロシージャに飛ばされましたが、昨日は正常に挙動しておりました。 ところが、実行すると正常にコピペできます。 まさにランダムな挙動をしております。 どこかおかしいことはわかるのですが…。
hatena19

2023/03/08 00:31

> 私は、表示に必要とされるフィールド(F○)だけを記述しておりました。 > これではダメなのですね。 当然、代入したフィールドだけしか入力されません。 コピー&ペーストでもフォームに配置されているフィールドのみしか入力されないはずです。 > まさにランダムな挙動をしております。 > どこかおかしいことはわかるのですが…。 イベントの具体的なコードや転記処理のコードの全体像が分かりませんので回答が難しいのですが、 コントロールやフォームに設定してあるイベント処理はいろいろ挙動が複雑になるので、 それを利用しない(イベントが発生しない)ような処理を考えた方が確実だと思います。 つまり、コピー&ペーストだとイベントが発生することもあったりしますので、 フォームのUIを使用しないまったく別ルートでの転記(新規追加)をするのがいいでしょう。 別ルートとは例えば、レコードセットの利用とか追加クエリです。 メインフォームの方もコピー&ペーストではなく、レコードセットを開いてそこにAddNewするというようにします(あるいは追加クエリ)。
death-o

2023/03/08 00:51

おはようございます。 考え方が色々とわかって大変助かりました。 やろうとしていることに全く知識が追いついていないこともわかったので、 まずはデータベースの勉強を一通りやってみてからかもしれません。 ちなみに、メインフォームの方も、先日授けていただいたコードの応用でできますか? また、少々このスレッドの意図と外れますが、 勉強は、どのようにやっていけばいいのでしょうか?
hatena19

2023/03/08 01:42

> ちなみに、メインフォームの方も、先日授けていただいたコードの応用でできますか? はい、できます。メインの方は1レコードのみでいいのでループは必要ないです。 AccessのVBAからテーブルのデータ操作(更新、新規追加、削除等)をする場合、DAOまたはADOというライブラリを使います。Accessのテーブル操作ならDAOの方が適しています。回答のコードもDAOを使ってます。 DAOまたはADOについて調べてみるといいでしょう。 ひとつ参考リンクを紹介しておきます。 アクセスVBA講座_Recordsetの作成(DAO編) http://www7b.biglobe.ne.jp/~cbcnet/DAO/database.html
death-o

2023/03/08 12:00

何から何までありがとうございます。 一通り勉強して、もう一度設計してみて、またわからないところが出てきましたら、質問しに参ります。 その際はまた改めてよろしくお願いいたします。 重ねてお礼申し上げます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問