非連結フォームから更新クエリでテーブルを一括更新する作り方
編集フォーム(F60資材編集)は、DLookup関数を使ってテーブルから該当レコードの値を取得し、各コントロールへ表示する仕組みになっています。フォーム自体はテーブルに連結していないため、画面上でどれだけ値を書き換えても、そのままでは元のテーブルには一切反映されません。表示されている内容はあくまで「その時点のコピー」であり、編集した結果を実際のデータとして確定させるには、別途テーブルへ書き戻す処理が必要になります。この「編集内容をテーブルへ書き戻す」という役割を担っているのが、本記事で解説する更新クエリです。追加クエリがフォームの入力内容を新規レコードとしてテーブルへ追加する仕組みだったのに対し、更新クエリは既存のレコードを1件特定したうえで、その内容を編集後の値で上書きするという点が異なります。
非連結フォームと更新クエリの関係
資材マスタ編集フォーム(F60資材編集)を例に、DLookupで表示した内容を更新クエリで書き戻す一連の流れを解説します。まずはこのフォームがどのような画面になっているかを確認し、そのうえで非連結フォームを採用している理由を整理します。
資材マスタ編集フォーム
追加クエリのときと同じ理由で、この編集フォームも非連結にしています。連結フォームで直接編集する方式と、非連結フォーム+更新クエリ方式の違いを整理すると次のとおりです。
連結フォームで直接編集する方式と非連結フォーム+更新クエリ方式の比較
| 項目 | 連結フォームで直接編集 | 非連結フォーム+更新クエリ |
|---|---|---|
| データの反映方法 | コントロールの値を変更した時点で自動反映 | 「編集更新」ボタンを押した時だけ一括反映 |
| 複数人同時使用時の排他エラー | 発生しやすい(レコードロック) | 発生しない |
| 変更ミス時のやり直し | 反映済みのため手戻りが発生しやすい | ボタンを押すまでは反映されないため、画面を閉じればやり直せる |
| 更新対象フィールド | 変更したフィールドのみ | 変更の有無に関わらず全フィールド |
| レコードの特定方法 | フォームが該当レコードに直接連結 | 主キー(ID)を抽出条件に指定 |
更新クエリならではの設計ポイント
追加クエリと同じ「コピペで式を量産する」考え方はそのまま使えますが、更新クエリには追加クエリにはない設計上の判断がいくつかあります。作り方に入る前に、次の3点を整理しておきます。
更新クエリ設計上のポイント
| 項目 | 内容 | 理由 |
|---|---|---|
| 更新対象フィールド | 変更の有無に関わらず全フィールドを毎回上書き | 変更したフィールドだけを個別判定する仕組みにすると条件が複雑になるため |
| 反映タイミング | 「編集更新」ボタンを押すまでテーブルへ書き込まれない | 入力を間違えた場合、画面を閉じるだけでやり直せるようにするため |
| 主キー(ID)の扱い | 「レコードの更新」欄には式を入れず、抽出条件としてのみ使用 |
更新クエリの土台を作る
更新クエリも追加クエリと同じく、まずは通常のクエリデザインから作り始めます。テーブルを1つ追加し、クエリの種類を切り替えるところまでが土台作りです。
① テーブルを選択クエリのクエリデザインで追加する
「作成」タブの「クエリデザイン」から新規クエリを開き、更新対象のテーブル(本例ではT60資材M)を追加します。全フィールドをフィールド欄に並べておくのは追加クエリのときと同様です。
② 選択クエリを更新クエリに変更する
「クエリの種類」から「更新」を選ぶと、グリッドの行が「表示」ではなく「レコードの更新」に変わります。ここが追加クエリとの見た目上の大きな違いです。
「クエリの種類」から「更新」を選択すると、グリッドに「レコードの更新」の行が表示される
抽出条件でレコードを特定する
更新クエリでは、どのレコードを書き換えるかを抽出条件で1件に絞り込む必要があります。ここでは主キーであるIDを使い、フォーム上で選択されているレコードのIDと一致するものだけを更新対象にします。
③ IDの抽出条件に[Forms]!のパスを設定する
ID列の抽出条件欄で、追加クエリのときと同じ手順([Forms]!と入力→候補からフォーム名を選択→続けて!を入力→候補からIDを選択)を行い、[Forms]![F60資材編集]![ID]という式を完成させます。
IDの抽出条件欄に[Forms]![F60資材編集]![ID]の式を設定した状態
レコードの更新欄をコピペで量産する
IDの抽出条件パスが完成すれば、あとは追加クエリのときと同じコピペ技で、他のフィールドの「レコードの更新」欄を量産していきます。手打ちする箇所はここでも一切ありません。
④ 完成済みのパスからフォーム部分だけを範囲指定してコピーする
先ほど完成させた[Forms]![F60資材編集]![ID]のうち、[Forms]![F60資材編集]![までの部分だけをドラッグで範囲指定し、コピーします。
[Forms]![F60資材編集]![までを範囲指定してコピーする
⑤ 隣のフィールドのレコードの更新欄に貼り付けて候補を選ぶ
コピーした文字列を、隣のフィールド(本例では所属部署コード)のレコードの更新欄に貼り付けると、このフォームに配置されているコントロールの候補リストが表示されます。フィールド名と同じコントロールを選択すると、更新先パスが確定します。
貼り付けるとコントロールの候補リストが表示されるので、フィールド名と同じものを選択する
⑥ 同じ操作を残りのフィールドすべてに繰り返す
確定した式([Forms]![F60資材編集]![所属部署コード])をさらに次のフィールドへ貼り付け、同様に候補から選択する操作を繰り返します。この一連の流れは追加クエリのコピペ技とまったく同じです。
指定先パスが確定した式を隣のフィールドへ貼り付け、候補から種別コードを選択する
⑦ 全フィールド分の更新式が完成したらクエリ名を付けて保存する
すべてのフィールドのレコードの更新欄が埋まったら完成です。追加クエリと異なり、更新クエリではテーブルを削除する必要はありません。クエリ名をQ60資材編集更新として保存します。
全フィールドのレコードの更新欄に[Forms]!のパスが設定された完成形。IDのレコードの更新欄だけは空欄のまま
まとめ
非連結フォームからの更新クエリ作成は、次の流れで整理できます。
- 選択クエリでテーブルを追加し、更新クエリに変換する
- 主キー(ID)の抽出条件に[Forms]!のパスを候補選択で設定する
- 完成したパスの共通部分をコピーし、他のフィールドのレコードの更新欄へ貼り付けて候補から選択する
- すべてのフィールド(ID以外)に同じ操作を繰り返す
- クエリ名を付けて保存する(テーブルの削除は不要)
追加クエリとの一番の違いは、フィールド欄が「レコードの更新」欄になることと、IDを抽出条件として使う点、そしてテーブルを削除しない点です。それ以外のコピペによる式の量産方法は共通しているため、追加クエリの作り方を理解していれば迷わず作成できます。
本サイトではマクロを用いた構築手順を中心に紹介していますが、決してマクロを唯一の正解として推奨しているわけではありません。VBAが扱える環境であれば、より多彩で柔軟なプログラムが組めるVBAでの構築をむしろ推奨したいと考えています。
ここでマクロという選択肢を提示しているのは、VBAにハードルを感じている方への「もう一つの入り口」として、また将来的な後継者への引き継ぎ負荷を抑えるという実務上のメリットを考慮してのことです。設計の考え方の一つとして、状況に合わせて活用してください。