Accessでレコードを論理削除する方法 削除フラグと復元の設計

概要

この記事の結論
Accessの論理削除は、テーブルにYes/No型の削除フラグを設け、通常の一覧でFalseのレコードだけを抽出する方法です。更新クエリでTrueにすると非表示にでき、Falseへ戻すことで再利用できます。ただし、フラグだけでは過去の帳票、選択候補、CSV出力、権限管理まで自動で切り替わりません。この記事では設定から対象1件の更新、復元、親子データと履歴の扱いまで解説し、物理削除が適するケースも分けて整理します。

この記事でわかること

  • 論理削除とは、レコードを消さずに削除済みの状態を記録し、通常の利用対象から外す方法です。
  • 削除フラグと管理項目を追加する
  • 削除済み一覧から安全に復元する
  • 親子データと過去の帳票を守る

この記事の主な内容

  1. 論理削除と物理削除の使い分け
  2. 削除フラグと管理項目を追加する
  3. 通常の一覧と選択候補から除外する
  4. 対象レコードを更新クエリで論理削除する
  5. 削除済み一覧から安全に復元する
  6. 親子データと過去の帳票を守る
  7. 運用ルールとテスト項目を決める
  8. よくある質問

想定読了時間:約16分~20分


1  論理削除と物理削除の使い分け

論理削除は、レコードを残したまま「通常は使わない」という状態を記録する方法です。例えば廃止した商品を新規受注の候補から外しながら、過去の受注明細との関連を維持したい場合に役立ちます。Accessに専用の自動切替機能があるわけではなく、フラグと抽出条件を組み合わせて設計します。

物理削除は、テーブルからレコードそのものを削除する方法です。不要な作業データを片付けるなど、保存する必要がなく影響範囲も確認できる場合には適切な選択です。「Accessでは物理削除をしてはいけない」と一律に考えるのではなく、復元や履歴が必要かを先に判断します。

観点論理削除物理削除
元のレコード残るテーブルから削除される
通常一覧条件を付けて除外する元の行がなくなる
復元状態を戻す設計が可能バックアップ等からの復旧が必要
容量基本的に減らない空き領域の再利用や最適化も考慮
向く場面廃止・停止、復元や履歴参照不要な一時データ等の整理

連鎖削除は設定によって結果が変わる

参照整合性を有効にした親子関係では、参照されている親の削除を拒否することがあります。さらに連鎖削除を有効にしていると、親の削除に伴い関連する子も削除されます。関係線があるだけで必ず連鎖削除されるわけではありません。まず実際の設定と参照先を確認します。

行を残す論理削除と実際に消す物理削除の違い

2  削除フラグと管理項目を追加する

最小の構成は、商品テーブルにYes/No型の「削除フラグ」を追加することです。本記事ではFalseを通常利用、Trueを削除済みとします。チェックが付いている方が削除済みという意味なので、「有効フラグ」など逆の意味を持つ名前と混在させないようにします。

テーブルを変更する手順

1. データ保存先を含めてバックアップを作り、作業用コピーで対象テーブルを開きます。

2. [デザインビュー]で「削除フラグ」を追加し、データ型を[Yes/No型]にします。

3. 新規登録時に通常利用となるよう、[既定値]をFalseにします。

4. 必要に応じて削除日時、削除者、削除理由を追加して保存します。

5. データシートで既存レコードの値を確認し、意図せず削除済みになっていないか調べます。

既定値の設定は新規登録時の初期値を決めるもので、既存データを都合のよい値に変換する指示ではありません。特に別DBから取り込んだ値やリンク先のNullableな列では、Nullの有無も確認します。Nullを通常利用とみなすかは業務判断なので、無条件でFalseに置き換えないでください。

項目型の例記録する内容
商品IDオートナンバー既存レコードの識別子
商品名短いテキスト商品の名称
削除フラグYes/NoFalseは通常利用、Trueは削除済み
削除日時日付/時刻削除済みにした時点
削除者短いテキスト確認できた操作者の識別情報
削除理由短いテキスト等廃止・誤登録などの理由

日時や削除者を同じ行に記録するだけでは、削除と復元の全履歴は残りません。操作を繰り返した履歴まで必要なら、別の操作履歴テーブルへ日時、対象ID、変更前後、操作者、理由を追記する設計にします。Windows名などを取得するだけで厳密な本人確認になるわけでもありません。

削除フラグに加えて日時、操作者、理由を記録する管理項目

3  通常の一覧と選択候補から除外する

削除フラグを作った後は、表示先ごとに参照範囲を揃えます。通常の商品一覧ではFalseだけを表示する選択クエリを作り、フォームのレコードソースへ設定します。次のSQLは「T_商品」に商品ID、商品名、削除フラグがある場合の例です。

SELECT [商品ID], [商品名], [削除フラグ]
FROM [T_商品]
WHERE [削除フラグ] = False
ORDER BY [商品名], [商品ID];

[作成]→[クエリデザイン]からSQLビューを開き、上のSQLを入力して「Q_商品_有効」として保存します。デザイングリッドで作る場合は、削除フラグ列の抽出条件にFalseを設定します。チェック済みのレコードが結果から除外され、元テーブルには残ることを確認してください。

フォームのフィルターだけに頼らない

一時的なフィルターは解除されることがあります。常に有効な商品だけを扱う画面なら、条件を含むクエリを共通の参照元にすると、漏れを減らせます。ただし、それでもテーブルの直接操作や別クエリからの取得は可能です。非表示の仕組みを、アクセス権の制御と同じものと考えないようにします。

商品選択のコンボボックス、検索、集計、CSV出力も点検します。画面の一覧だけ直してCSVの元クエリを変えなければ、削除済み商品が外部へ出る可能性があります。一方、過去帳票では削除済み商品も必要になることがあるため、すべての参照を一律にFalse条件へ変えるのも適切ではありません。

通常一覧、削除済み一覧、過去帳票で参照範囲を使い分ける設計

4  対象レコードを更新クエリで論理削除する

論理削除はDELETE文ではなく、対象の削除フラグをTrueにするUPDATE文で行えます。更新クエリは実行後に通常の元に戻す操作が使えないため、先に同じ条件の選択クエリで対象を確認します。商品名は重複し得るので、主キーの商品IDで1件を指定することが基本です。

最初に対象を選択して確認する

次の例は商品IDが125のデータを対象にします。125は説明用の値です。自分の環境で対象を確認せず、そのまま実行しないでください。作業用コピーでSQLビューから実行し、件数が1件であることと商品名を確認します。

SELECT [商品ID], [商品名], [削除フラグ]
FROM [T_商品]
WHERE [商品ID] = 125 AND [削除フラグ] = False;

対象が0件なら、既に削除済みなのか、IDが違うのか、参照先が違うのかを確認します。そこで条件を消して全件を更新してはいけません。1件を確認できたら、削除日時フィールドを用意したうえで次の更新クエリへ進みます。2つのSQLは別々のクエリとして扱います。

UPDATE [T_商品]
SET [削除フラグ] = True,
    [削除日時] = Now()
WHERE [商品ID] = 125 AND [削除フラグ] = False;

更新後は3か所を照合する

更新対象が1件であること、通常一覧から外れたこと、元テーブルには同じIDの行が残ることを確認します。削除日時も期待する時刻か確認してください。画面が更新されない場合は、未保存の編集を処理してからフォームを再クエリするか、閉じて開き直します。

複数人運用では、事前確認から更新までに他の人が状態を変更する可能性があります。上のSQLはFalseのときだけ更新する条件を持ちますが、画面側で更新件数0を扱う必要があります。ボタン処理に組み込むなら、対象IDと理由の確認、パラメーター化、エラー処理、履歴の記録を合わせて設計します。

主キーで更新対象を限定して論理削除し、結果を照合する手順

レコードの論理削除の設定や運用で困っている場合は

まずはコピー環境で本記事の手順を確認してください。削除済み表示の混入、過去帳票の消失、復元ルール、権限の分離など、影響範囲の判断が難しい場合は、Accessの教科書のお問い合わせフォームから状況をご相談いただけます。使用中の版、対象の画面やテーブル、再現手順を整理すると、相談内容が伝わりやすくなります。


5  削除済み一覧から安全に復元する

復元は、削除済みの行を新しいIDで作り直すのではなく、元の行を通常利用に戻す操作として設計します。商品IDを維持すれば、既存の受注明細との関連も保てます。ただし削除後に同じ業務コードが再登録されている場合などは、そのまま戻してよいとは限りません。

復元用クエリを用意する

「Q_商品_削除済み」は削除フラグ=Trueの条件で作ります。通常の利用者が使う一覧と分け、復元操作が必要な担当者だけに入口を用意します。これは操作導線の分離であり、テーブルへのアクセス権を強制する仕組みとは別です。

復元前には、商品コードの重複、参照するカテゴリなどの親の状態、再利用してよい商品かを調べます。問題がなければ、元のIDを指定してフラグをFalseへ更新します。次の例も商品ID125だけを対象にしています。

UPDATE [T_商品]
SET [削除フラグ] = False
WHERE [商品ID] = 125 AND [削除フラグ] = True;

この例では削除日時をあえて消していません。「最後に削除した日時」として保持する考え方です。現在の状態は削除フラグで判定します。復元日時・復元者を別途残し、全履歴が必要なら履歴テーブルへ追記してください。削除日時だけで削除済みを判断するクエリが残っていないかも確認します。

削除済みデータを復元する前に確認する項目

6  親子データと過去の帳票を守る

廃止商品の新規選択を止めることと、過去の注文を表示することは別の目的です。すべてのクエリを「有効な商品だけ」に統一すると、過去の受注明細を結合したときに行が消える場合があります。新規入力用と履歴参照用のデータ元を分けると、この事故を防ぎやすくなります。

コンボボックスで過去の商品名が空欄になる例

商品IDを保存し、商品名を表示するコンボボックスで、値集合ソースから削除済み商品をすべて外すと、既存伝票が持つIDの表示名を探せなくなることがあります。新規選択候補を限定しつつ、既に保存された商品名は別の読み取り専用欄へ表示するなど、入力と参照を分ける設計を検討します。

過去の単価は現在のマスターだけに依存させない

論理削除は商品名や単価の変更履歴を自動保存しません。過去の請求書を再発行する際に現在の商品単価を参照すると、当時の請求額と違う結果になるおそれがあります。伝票の明細には、確定時点の商品名、単価、数量など、再現に必要な情報を保持する方法を検討します。

利用場面参照範囲の例守りたいこと
新規注文の商品選択通常利用の商品のみ廃止品を新たに選ばせない
過去注文の表示保存済み明細と必要な商品情報当時の明細を消さない
削除済みの管理削除フラグ=True理由確認と復元の判断
外部連携連携仕様に従う廃止状態の通知漏れを防ぐ

親を論理削除しても、子の削除フラグは自動では切り替わりません。「顧客停止後は新規受注を禁止するが既存受注は残す」など、親の状態が業務へ与える影響を決めます。複数テーブルの状態をまとめて変更するなら、途中失敗で一部だけ変わらないよう、トランザクション等を含めて設計します。

廃止した商品の新規選択を止め、過去伝票の内容を維持する設計

7  運用ルールとテスト項目を決める

論理削除を使う画面では、通常の物理削除操作をどう扱うかも決めます。フォームの[削除の許可]を[いいえ]にする方法はありますが、これはそのフォームからの削除に関する設定です。テーブル直接操作、別のクエリ、別フォームまで一括で禁止するものではありません。

不要データが残り続ければ容量や検索対象も増えます。論理削除をしただけでファイルが軽くなるとは限りません。保管期間、アーカイブ、最終的な削除の担当を決め、保存先やバックアップへのアクセスも合わせて管理します。機密情報の閲覧制限には、保存先側の権限など別の対策が必要です。

テスト期待する結果
1件を論理削除対象だけTrue、他の行は変わらない
同じ操作を再実行既に削除済みと判断し、重ねて履歴を壊さない
通常一覧と候補削除済みを新規利用の対象にしない
過去の帳票必要な明細と確定時点の値を維持する
復元元のIDで再表示され、復元を記録する
CSVや集計出力目的どおりの範囲になる
エラーと同時操作0件更新や競合を検知できる

論理削除は、フラグを作る工程だけで完了しません。画面・帳票・選択候補・外部出力のどこで除外するか、どう復元するかまで揃えて初めて運用できます。用途ごとの抽出条件を一覧にしておくと、新しい画面を追加するときも確認しやすくなります。

論理削除がアクセス権、容量削減、完全な操作履歴を代替しないこと

よくある質問

A. 復元や過去データの参照が必要なら論理削除が候補になります。例えば廃止商品を新規選択から外しつつ、過去の注文に残したい場合です。一方、保存不要の一時データなどは、影響範囲を確認して物理削除する方が適することがあります。論理削除は容量を減らさず、抽出条件の漏れにも注意が必要です。すべてのテーブルへ一律に導入するのではなく、残す理由、復元の必要性、最終的な整理方法を業務ごとに決めてください。

A. 通常利用と削除済みの2状態なら、Yes/No型が分かりやすい方法です。「削除フラグ」という名前ならFalseを通常、Trueを削除済みとし、新規登録の既定値をFalseにします。ただし、申請中、停止、承認済み、廃止など複数状態が必要な場合は、状態コードを持つ設計も検討します。2状態のフラグを増やし続けると、矛盾した組み合わせが生まれやすくなります。日時や理由を記録したい場合は、フラグとは別の項目を追加します。

A. AccessのYes/No値ではFalseが0、Trueが-1として扱われます。削除フラグの意味を読み取りやすくするには、通常一覧の条件をFalseと書く方法が分かりやすいでしょう。ただし数値の比較と真偽判定を混同し、Trueを1と決めつけた式にしないことが大切です。また、SQL Serverなどのリンク先では型や実行先が異なります。本記事のSQLはAccess側のクエリを前提とし、移行時は接続先での型と条件の評価を改めて確認します。

A. 削除済み一覧で対象を確認し、元の主キーを指定して削除フラグをFalseへ戻します。新しいIDの行を作り直す方法では、過去の明細との関連が分かれやすくなります。復元前には、同じ商品コードが別の行に使われていないか、関連する親データが利用可能かも確認してください。操作した日時、担当者、理由を残し、通常一覧へ再表示されることを確認します。削除日時を残すか消すかは、その項目が何を意味するかを決めたうえで統一します。

A. フラグを付けるだけなら元の行は残りますが、帳票の元クエリが「削除フラグ=Falseの商品だけ」を内部結合していると、過去の明細が結果から外れる場合があります。新規選択候補と履歴参照では必要な範囲が違うため、クエリを分けて確認します。また、当時の名称や単価まで再現したい場合は、論理削除だけでは不十分です。確定時の伝票情報を保持する設計にし、再印刷して元の内容と一致するかを検証してください。

A. 削除済みフラグはアクセス権を制御する機能ではありません。通常のフォームから隠れていても、テーブルや別のクエリ、出力ファイル、バックアップへアクセスできる人はデータを取得できる可能性があります。閲覧できる人を制限したい場合は、保存先やデータベース側の権限、利用経路、出力先も管理する必要があります。また、本当に情報を消す必要がある場合、フラグを付けるだけでは目的を満たしません。状態管理と情報管理を分けて検討します。

A. 通常は小さくなりません。レコードはテーブル内に残り、日時や履歴の追加によってデータ量が増える場合もあります。通常一覧の件数が減ることと、保存されているデータ量が減ることは別です。容量対策が必要なら、保管期間を決めて別領域へアーカイブする、不要データを適切に整理する、保存先を見直すなどの方法を検討します。最適化や修復も、論理削除済みの行を自動で物理削除してくれる機能ではありません。

A. 既存ボタンがレコード削除命令を実行しているなら、そのままでは物理削除になります。論理削除へ切り替える際は、フラグを更新する処理に変更し、対象ID、確認メッセージ、理由の記録、更新件数、表示更新まで確認します。フォームの削除の許可をいいえにすることも検討できますが、別フォームやテーブル直接操作までは防げません。画面上の名称も「利用停止」「削除済みにする」など、実際の処理が伝わる表現に揃えると誤操作を減らせます。

レコードの論理削除の設定や運用で困っている場合は

まずはコピー環境で本記事の手順を確認してください。削除済み表示の混入、過去帳票の消失、復元ルール、権限の分離など、影響範囲の判断が難しい場合は、Accessの教科書のお問い合わせフォームから状況をご相談いただけます。使用中の版、対象の画面やテーブル、再現手順を整理すると、相談内容が伝わりやすくなります。

関連記事

Accessのテーブルとは

Accessのフォームフィルター

Accessのデータ入力用フォーム

AccessからSQL Serverへ移行する方法


参考情報

1. テーブルリレーションシップ
https://support.microsoft.com/en-us/access/guide-to-table-relationships

2. リレーションシップの編集
https://support.microsoft.com/en-us/access/create-edit-or-delete-a-relationship

3. UPDATE
https://learn.microsoft.com/en-us/office/client-developer/access/desktop-database-reference/update-statement-microsoft-access-sql

4. Form.AllowDeletions
https://learn.microsoft.com/en-us/office/vba/api/access.form.allowdeletions

5. データ型とフィールドプロパティ
https://support.microsoft.com/ja-jp/access/introduction-to-data-types-and-field-properties

6. Form.Requery
https://learn.microsoft.com/en-us/office/vba/api/access.form.requery

TOP