質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.31%
Access

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

意見交換

28回答

1688閲覧

リレーションシップの設定

PyPyPython

総合スコア132

Access

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

1グッド

0クリップ

投稿2025/05/09 00:46

編集2025/05/09 01:30

お世話になっております。

為替トレードの振り返りノートをAccessで作成しようとしています。
初めて中間テーブルを扱うのですが、リレーションシップの設定はこれで合っていますでしょうか?
全てのリレーションシップは、参照整合性・フィールドの連鎖更新・レコードの連鎖削除のチェックボックスにチェックを入れています。

T_取引履歴(メインテーブル)の1レコードに対し、複数の①エントリー根拠 ②エントリーメンタル ③クローズ根拠 ④クローズメンタルを記録したいので、中間テーブルとして①T_エントリー根拠 ②T_エントリーメンタル ③T_クローズ根拠 ④T_クローズメンタル を作成しました。

M_メンタル(マスタテーブル)は、エントリーとクローズで共通するものが多いため、M_エントリーメンタルとM_クローズメンタルに分割せず共用としています。

軽く語句説明をします。
エントリー根拠→取引を開始した理由
エントリーメンタル→取引開始時の感情(楽観・焦りなど)
クローズ根拠→取引を終了した理由
クローズメンタル→取引終了時の感情(エントリーメンタルと同様)

リレーションシップの設定

hatena19👍を押しています

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

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

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

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

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

回答28

#1

yambejp

総合スコア117740

投稿2025/05/09 01:44

運用方法次第ですがエントリー根拠、エントリーメンタル、クローズ根拠、クローズメンタルは取引履歴に含めるなら含んでも良いような気がします。とくにエントリー//クローズ各メンタルIDがすでに取引履歴に含まれているのでダブルバインドしているかもしれません。根拠は履歴に対して後追いでなんらかの追加的な処理をして入力するのであれば別れていてもよいかも

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

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

#2

igohas

総合スコア14

投稿2025/05/09 01:55

取引履歴にエントリーメンタルID、クローズメンタルIDが入っていることが気になります。
取引履歴とエントリーメンタルなどが1対多の関係で結ばれていますが、これは合っていますか?
もし1つの取引に複数の根拠やメンタルがあるならば取引履歴のメインテーブルにそれらのIDが入っているのは不自然で、中間テーブルの意味がないように思います。

また、M_エントリー根拠テーブルなどにおいて根拠となるものは選択式のデータであるならば多対1の関係で正しいと思いますが、自由記述の形なら1対1になるかと思います。
(ここは正しい気がしましたが私が読み取れなかったため補足まで)

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

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

#3

sk.exe

総合スコア1082

投稿2025/05/09 02:41

編集2025/05/09 03:06

T_取引履歴(メインテーブル)の1レコードに対し、
複数の①エントリー根拠 ②エントリーメンタル 
③クローズ根拠 ④クローズメンタルを記録したい

ということであれば、テーブル[T_取引履歴]に定義されているフィールド[エントリーメンタルID]および[クローズメンタルID]は不要です。

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

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

#4

PyPyPython

総合スコア132

投稿2025/05/09 05:37

編集2025/05/09 05:38

皆さんありがとうございます。

T_取引履歴のフィールドから
・エントリーメンタルID
・クローズメンタルID は削除しました。

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

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

#5

PyPyPython

総合スコア132

投稿2025/05/09 06:09

編集2025/05/09 06:11

入力用フォーム内に配置した『入力確定』ボタンを押した時にのみ、T_取引履歴や中間テーブルにレコードが保存されるようにするには、T_取引履歴や中間テーブルと同じフィールド構成・リレーションシップを持つ入力用テーブル(T_取引履歴_sub、T_エントリ-根拠_sub、T_エントリーメンタル_sub、T_クローズ根拠_sub、T_クローズメンタル_sub)を作り、『入力確定』ボタンのクリック時に追加クエリでT_取引履歴と中間テーブルに入力用テーブルのレコードを追加するようにするのが良いのでしょうか?(ややこしくてすみません)

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

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

#6

igohas

総合スコア14

投稿2025/05/09 07:27

入力用フォームに入れた値を、複数回のSQL文を叩きそれぞれのテーブルに適切なデータを入れるだけで十分なように見えます。
つまり、確定ボタンを押した時に
1.取引履歴テーブルにデータを入れるinsert文を実行する
2.上記のデータのIDに紐づくかたちで、エントリー根拠などのテーブルに各データを入れるinsert文を実行する
と複数回にわたりSQL文を実行すれば良いと考えています
(他の方法で入らないようにするにはバックエンドで他の方法からinsertするSQLを叩かないようにすれば良いだけなのではないでしょうか…?)

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

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

#7

hatena19

総合スコア34362

投稿2025/05/09 07:49

#5
入力用フォームをどのように設計するかによりますが、
Accessでは一対多の関係のデータの場合、メインサブフォーム形式にするのが一般的です。
つまり、
T_取引履歴をソースとするメインフォームに、各中間テーブルをソースとする帳票フォームをサブフォームとして埋め込むという設計にします。
その場合、メインフォームからサブフォームへ移動する場合、メインフォームのデータは自動でテーブルに保存されるという仕様になってます。
『入力確定』ボタンを押した時のみ、T_取引履歴や中間テーブルにレコード保存されるようにするには、
同じ構成の一時テーブル(入力用テーブル)をソースとするメインサブフォームにして、
『入力確定』ボタンを押した時に、各テーブルに追加あるいは更新する設計になります。
追加や更新方法は、追加クエリ、更新クエリで一気に更新するのが楽でしょう。

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

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

#8

PyPyPython

総合スコア132

投稿2025/05/09 08:18

#6
理解力に乏しくて申し訳ないのですが、入力用フォームにレコードソースを設定せず、入力確定ボタンのクリック時にそれぞれのテーブルにクエリでレコードを追加するということでしょうか?

#7
一時テーブルも、意見交換の最初に添付した画像のように、リレーションシップを設定する必要はありますか?

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

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

#9

hatena19

総合スコア34362

投稿2025/05/09 13:28

#8

一時テーブルも、意見交換の最初に添付した画像のように、リレーションシップを設定する必要はありますか

一時テーブルなのでなくても問題はないと思いますが、
本テーブルに追加後、一時テーブルのデータは削除しますので、そのときに連鎖削除が設定されていれば、T_取引履歴_sub のデータを削除すれば、中間テーブルの方のデータも道ずれで削除してくれるので、一回の削除クエリ実行ですみますね。

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

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

#10

PyPyPython

総合スコア132

投稿2025/05/14 01:04

編集2025/05/14 01:06

一時テーブルにリレーションシップを設定する場合、これでいいのでしょうか?
Temporary Tableという意味で、一時テーブルの名前は『TT_〇〇』としました。

イメージ説明

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

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

#11

hatena19

総合スコア34362

投稿2025/05/15 00:06

#10
ざっと見た限りでは問題なさそうです。

こちらでは同じものを作成して動作確認はできませんので、最終的な動作確認はそちらで十分実施してから実運用にしてください。

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

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

#12

yambejp

総合スコア117740

投稿2025/05/15 00:22

編集2025/05/15 00:23

#10

正直、質問者さんがおっしゃる中間テーブルは正規化の観点からするとあまり意味をなしていないように見受けられます。すべて履歴データ側にもたせるか、外出しにしたいなら(中間?)テーブルは1つでよいでしょう

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

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

#13

PyPyPython

総合スコア132

投稿2025/05/15 02:09

編集2025/05/15 02:10

#11 確認ありがとうございます、動作テストしてみます。

#12 何故正規化の観点から意味をなしていないのか教えてください。全てT_取引履歴に持たせる場合、エントリー根拠、エントリーメンタル、クローズ根拠、クローズメンタル関連のフィールド数がとんでもないことになると思うのですが。(例:エントリー根拠1、エントリー根拠2、エントリー根拠3、、、)
また、中間テーブルをひとつにすると、T_取引履歴とT_中間テーブル(仮)はどのようなフィールド構成になりますか?ひとつにまとめると、例えばエントリー根拠が3つでエントリーメンタルが1つの場合、多数のNullデータが発生すると思うのですが。

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

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

#14

yambejp

総合スコア117740

投稿2025/05/15 03:52

#13

私の認識がちがったらすみません
最初に運用次第と書いたとおりなのですが、ご提示の情報だと取引履歴に対して、エントリー根拠*エントリーメンタル*クローズ根拠*クローズメンタルの乗算される要素が発生するということになりますが間違いないですか?であれば#10でも問題ないです

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

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

#15

PyPyPython

総合スコア132

投稿2025/05/15 05:06

編集2025/05/15 05:19

#14

取引履歴に対して、エントリー根拠*エントリーメンタル*クローズ根拠*クローズメンタルの乗算される要素が発生する

これの意味があまりよく理解できないのですが、添付画像のように、T_取引履歴の1レコードに対して各中間テーブルは数レコード増えていく想定です。
イメージ説明

最初に運用次第と書いたとおり

運用次第、というのは入力したデータをどのように活用したいか、ということでしょうか?
・エントリー根拠、クローズ根拠ごとの勝率を知りたい(勝率の高い根拠を知りたい)
・取引方向ごとの勝率を知りたい(買いと売りのどちらが得意なのか知りたい)
・取引対象ごとの勝率を知りたい(相性の良い取引対象を知りたい)
・A4サイズのレポートに、各取引の詳細をまとめたい。(印刷・ファイリングし見返せるようにしたい)
・ファイルを開いた時のフォームに、総合勝率、平均獲得pips、総損益等を表示したい。

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

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

#16

yambejp

総合スコア117740

投稿2025/05/15 05:32

編集2025/05/15 05:53

#15

各追加要素は0個以上の複数ぶら下がるという定義になっているように見受けられます

つまり
特定の取引履歴ID(仮にA1)に対して、

  • エントリー根拠が2つ(B1,B2)
  • エントリーメンタルが3つ(C1,C2,C3)
  • クローズ根拠が4つ(D1,D2,D3,D4)
  • クローズメンタルが2つ(E1,E2)

のデータがぶら下がっていたら取引履歴IDA1は2✕3✕4✕2=48のデータがぶら下がるという意味です。

A1-B1-C1-D1-E1 A1-B2-C1-D1-E1 A1-B1-C2-D1-E1 A1-B2-C2-D1-E1 A1-B1-C3-D1-E1 ・・・・ A1-B2-C3-D4-E2

失礼、選択しない場合や、複数選択した場合も必要なのでもっと多いですね

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

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

#17

sk.exe

総合スコア1082

投稿2025/05/15 06:02

編集2025/05/15 06:17

入力用フォーム内に配置した『入力確定』ボタンを押した時にのみ、T_取引履歴や中間テーブルにレコードが保存されるようにする

T_取引履歴や中間テーブルと同じフィールド構成・リレーションシップを持つ入力用テーブル(T_取引履歴_sub、T_エントリ-根拠_sub、T_エントリーメンタル_sub、T_クローズ根拠_sub、T_クローズメンタル_sub)を作り、『入力確定』ボタンのクリック時に追加クエリでT_取引履歴と中間テーブルに入力用テーブルのレコードを追加するようにする

T_取引履歴をソースとするメインフォームに、各中間テーブルをソースとする帳票フォームをサブフォームとして埋め込むという設計

  • そのフォームに実装しようとしている機能は「[T_取引履歴]の新規レコードの追加」および「([T_取引履歴]の新規レコードに従属する)中間テーブルの新規レコードの追加」だけなのか。それとも「既存のレコードの更新」を行う機能も同じフォームに実装するのか。

  • 「[T_取引履歴]に保存されているレコードの検索」および「[T_取引履歴]に保存されているレコードの削除」もそのフォームが担うのか。それとも、それらの機能を持つフォームは別途作成するのか。

  • [T_取引履歴]の主キーであるフィールド[取引履歴ID]のデータ型は何であるか。

  • [T_取引履歴]のフィールド[取引履歴ID]のデータ型がオートナンバー型ではない場合、新規レコードの[取引履歴ID]の値はどのようにして決まるのか。ユーザーが直接入力するのか、それとも独自のID生成処理によって自動的に割り当てるのか。

一時テーブルも、意見交換の最初に添付した画像のように、リレーションシップを設定する必要はありますか?

  • そのデータベースファイルを使用するのは1人のユーザーのみか。それとも、ネットワーク上の共有フォルダに保存し、複数のユーザーが同時にアクセスできるようにすることを想定しているのか。

  • (マルチユーザーアクセスを前提とする場合)そのデータベースファイルをバックエンド用とフロントエンド用に分割しないのか。

以上の点がどのようになっているか次第かと。

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

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

#18

PyPyPython

総合スコア132

投稿2025/05/15 06:05

#16
現在のテーブル構成だと、#14 で挙げたデータ活用ができなかったりする可能性はありますか?

また、現在のテーブル構成と、yambeさんの仰っている「全て履歴テーブルに持たせる」or「履歴テーブル+中間テーブル1つ」ではそれぞれどのようなメリット・デメリットがありますか?

また、「全て履歴テーブルに持たせる」場合と「履歴テーブル+中間テーブル1つ」の場合の、フィールド構成とリレーションの設定を教えてください。

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

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

#19

PyPyPython

総合スコア132

投稿2025/05/15 06:49

#17

そのフォームに実装しようとしている機能は「[T_取引履歴]の新規レコードの追加」および「([T_取引履歴]の新規レコードに従属する)中間テーブルの新規レコードの追加」だけなのか。それとも「既存のレコードの更新」を行う機能も同じフォームに実装するのか。

→現時点での構想ですが、新規入力と既存レコードの更新の両方をこのフォーム(F_入力とします)で行えるようにしようと考えています。取引一覧フォームと取引詳細フォームを作成し、取引詳細フォームの「編集」ボタンをクリックするとクエリでT_取引履歴のレコードをTT_取引履歴に、T_○○(中間テーブル)をTT_○○(中間テーブルの一時テーブル)に追加して編集できる状態にし、「編集完了」ボタンを押すと更新クエリでT_取引履歴と中間テーブルを更新

「[T_取引履歴]に保存されているレコードの検索」および「[T_取引履歴]に保存されているレコードの削除」もそのフォームが担うのか。それとも、それらの機能を持つフォームは別途作成するのか。

→上記の取引一覧フォームからレコードの検索を行えるようにする予定です。削除は取引一覧か取引詳細フォームから行えるようにする予定です。

[T_取引履歴]の主キーであるフィールド[取引履歴ID]のデータ型は何であるか。
[T_取引履歴]のフィールド[取引履歴ID]のデータ型がオートナンバー型ではない場合、新規レコードの[取引履歴ID]の値はどのようにして決まるのか。ユーザーが直接入力するのか、それとも独自のID生成処理によって自動的に割り当てるのか。

→今のところオートナンバーでフィールドを作成しています。もしオートナンバーではない方が良い場合は、T_次回取引履歴IDというテーブルを作成し、登録時にT_取引履歴の履歴IDに追加します。

そのデータベースファイルを使用するのは1人のユーザーのみか。それとも、ネットワーク上の共有フォルダに保存し、複数のユーザーが同時にアクセスできるようにすることを想定しているのか。
(マルチユーザーアクセスを前提とする場合)そのデータベースファイルをバックエンド用とフロントエンド用に分割しないのか。

データベースファイルを使用するのはわたし1人のみで、わたし以外が開くことはありません。バックエンドとフロントエンドに分割もなく、このデータベースファイル1つで完結します。

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

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

#20

sk.exe

総合スコア1082

投稿2025/05/15 07:20

#12
#14

この場合の「入力用テーブル」というのは、いわば「バッチ更新用のローカルキャッシュ代わりに使用するテーブル」ぐらいの意味合いでしょう。

Accessの連結フォームにおいて、フォームと連結しているテーブルのレコードの保存は基本的に1件ずつ行われます。
フォームに表示されているカレントレコード上のいずれかの連結コントロールに対して何らかの入力操作を行われた後、

  • カレントレコードを別のレコードに移動する。

  • メインフォームからサブフォームに(またはサブフォームからメインフォームに)フォーカスを移動させる。

  • そのフォームを閉じる。

  • [レコードの保存]コマンドを実行する。

といった操作を行なうだけで、(キー違反などの問題がなければ)編集されたカレントレコードの保存が完了します。

「編集された複数件のレコードを任意のタイミングでバッチ更新する」、「ある特定の操作が行なわれるまで、カレントレコードが保存されるのを抑制する」といったことは、連結フォームの持つ機能だけでは出来ません(マクロや VBA を使用する必要がある)。

そのため、バックエンド側のマスターテーブルを直接フォームに連結させるのではなく、マスターテーブルと同一の構造を持つローカルテーブルをフロントエンド側に設けてフォームに連結させることによって「フォーム上でのレコードの編集操作」と「マスターテーブルの更新処理」を分離する、という今回のような手法が用いられることも( Access 界隈では)珍しくありません。

「キャッシュ代わりのテーブルにまでリレーションシップが必要か?」といえば、hatena さん#9 が既におっしゃっているように「一時テーブルなのでなくても問題はない」です。

もしデータベースファイルをバックエンド用とフロントエンド用に分割する(予定である)ならば、#10 に添付された画像でいうところのM系テーブルとTT系テーブルとの間にリレーションシップを作成する必要は全くありません。

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

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

#21

sk.exe

総合スコア1082

投稿2025/05/15 08:26

#19

データベースファイルを使用するのはわたし1人のみで、わたし以外が開くことはありません。バックエンドとフロントエンドに分割もなく、このデータベースファイル1つで完結します。

ならば、M系テーブルとTT系テーブルのリレーションシップについては「あってもなくてもどっちでもよい」です。

取引一覧フォームと取引詳細フォームを作成

上記の取引一覧フォームからレコードの検索を行えるようにする予定です。削除は取引一覧か取引詳細フォームから行えるようにする予定です。

[T_取引履歴]の「レコードの検索」および「レコードの削除」については、上記の仕組みで問題ないと思います。

新規入力と既存レコードの更新の両方をこのフォーム(F_入力とします)で行えるようにしようと考えています。

[F_入力]に〈新規入力モード〉と〈更新モード〉があり、下記が後者に関する記述であるとして、

取引詳細フォームの「編集」ボタンをクリックするとクエリでT_取引履歴のレコードをTT_取引履歴に、T_○○(中間テーブル)をTT_○○(中間テーブルの一時テーブル)に追加して編集できる状態にし、「編集完了」ボタンを押すと更新クエリでT_取引履歴と中間テーブルを更新

各中間テーブルをレコードソースとする帳票フォーム(またはデータシートフォーム)をサブフォームとして埋め込むことになるでしょうから、[T_取引履歴]の既存のレコードに従属する中間テーブルの「新規レコードの追加」および「既存のレコードの削除」にも対応しなければならないでしょう。

また、〈新規入力モード〉については

[T_取引履歴]のフィールド[取引履歴ID]のデータ型

オートナンバーでフィールドを作成しています

オートナンバー型のフィールドの値が判るのは「そのテーブルに新規レコードが挿入された後」ですので、

  1. [T_取引履歴]に新規レコードを 1 件追加する。

  2. 上記 1 によって追加されたレコードの[取引履歴ID]の値を取得する。

  3. TT系の中間テーブル(一時テーブル)のレコードをT系の中間テーブル(マスターテーブル)に追加する際、追加されるレコードの[取引履歴ID]の値が上記 2 において取得された値と同じになるようにする。

といった操作が必要になります。

いずれにしても、「[T_取引履歴]に新規レコードを追加した後、中間テーブルへの新規レコードの追加に失敗した(結果、[T_取引履歴]にだけレコードが追加された)」といった事態にならないよう、トランザクション処理を行うようにすることが望ましいです。

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

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

#22

yambejp

総合スコア117740

投稿2025/05/15 08:34

#18

改めて考えてみましたが、根拠とメンタルは同じテーブルにして分岐用のカラムをつけるだけの方が合理的だと思います。また仕様上1履歴IDに対して0個以上の複数の根拠・メンタルが選べるのであればご提示のものでも仕方ないのかなと思い改めました。0個または1個しか選べないなら中間テーブルはやめたほうがいいでしょう。

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

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

#23

sk.exe

総合スコア1082

投稿2025/05/15 09:37

#15

添付された画像だと、[M_エントリー根拠]と[M_クローズ根拠]に格納されているレコードが全く同一なのですが、敢えて 2 つのテーブルに分けた理由は何なのでしょうか。

例えば ID が 4 であるレコードを両方のテーブルに追加したとして、その〈根拠〉の意味付けがテーブルによって異なったりすることがあり得るのでしょうか。

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

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

#24

PyPyPython

総合スコア132

投稿2025/05/16 04:41

編集2025/05/16 04:42

#22
理解力に乏しくて申し訳ありません。

0個以上の複数の根拠・メンタルが選べるのであればご提示のものでも仕方ないのかなと思い改めました。0個または1個しか選べないなら中間テーブルはやめたほうがいいでしょう。

この意味がよく理解できておりません。0個または1個しか選べないとは?複数選択できるようなテーブル構成にしているつもりなのですが。

根拠とメンタルは同じテーブルにして分岐用のカラムをつけるだけの方が合理的だと思います。

この場合のT_取引履歴とT_根拠メンタル(仮)の各テーブルのフィールドの構成、リレーションシップの設定を教えてください。

#23
これについては例示がちょっと悪かったです。
エントリー根拠とクローズ根拠は重複する内容もありますが、全く同じではありません。例えばクローズ根拠には「利益確保」「証拠金に対する2%の含み損」など、エントリーには無い根拠があります。

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

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

#25

PyPyPython

総合スコア132

投稿2025/05/20 00:54

#21

ならば、M系テーブルとTT系テーブルのリレーションシップについては「あってもなくてもどっちでもよい」です。

→TT_のリレーションシップはやめました。

各中間テーブルをレコードソースとする帳票フォーム(またはデータシートフォーム)をサブフォームとして埋め込むことになるでしょうから、[T_取引履歴]の既存のレコードに従属する中間テーブルの「新規レコードの追加」および「既存のレコードの削除」にも対応しなければならないでしょう。

→これはどういうことでしょうか?また、どのように対応すればよいでしょうか?

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

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

#26

sk.exe

総合スコア1082

投稿2025/05/20 02:31

#25

以下、[F_入力]を〈更新モード〉で開く場合の話であるとして、

取引一覧フォームと取引詳細フォームを作成し、取引詳細フォームの「編集」ボタンをクリックするとクエリでT_取引履歴のレコードをTT_取引履歴に、T_○○(中間テーブル)をTT_○○(中間テーブルの一時テーブル)に追加して編集できる状態に

となるわけで、その状態から更に各サブフォーム上に表示されたTT系の中間テーブルに対する編集操作(レコードの追加/更新/削除)が行われることになります。

「編集完了」ボタンを押すと更新クエリでT_取引履歴と中間テーブルを更新

更新クエリ( SQL でいうところの UPDATE 文)に出来るのは、あくまで「既存のレコードの更新」だけです。
テーブルに新たなレコードを追加したり、(任意の条件に該当する)既存のレコードを削除したりすることはできません。

また本件の場合、T系およびTT系の中間テーブルの主キーはそれぞれのテーブルの全てのフィールドによって構成されています。
そのいずれかのフィールドの値を変更することは、即ち「主キーの値の変更」と同じです。
([取引履歴ID]の値を変更することはないので、実質的にはそれ以外のフィールドが対象となる)

例えば、[T_エントリー根拠]から複写された[TT_エントリー根拠]のいずれかのレコードの[エントリー根拠ID]の値が 1 だったとして、サブフォームを介してそのレコードの[エントリー根拠ID]の値が 2 に変更された場合、その時点で複写元である[T_エントリー根拠]のレコード([エントリー根拠ID]の値は 1 のまま)と紐づけることは出来なくなってしまいます。

つまり(少なくとも現在のテーブル設計のままでは)、T系とTT系の中間テーブルを互いの主キー同士で紐づける形で更新クエリを実行させても全く無意味である、ということです。

[T_取引履歴]の既存のレコードに従属する中間テーブルの「新規レコードの追加」

この場合は「TT系の中間テーブルにあってT系の中間テーブルにはないレコード」が追加対象となります。

および「既存のレコードの削除」

TT系の中間テーブルから削除されたレコードは、複写元であるT系の中間テーブルの既存のレコードと紐づけようがありません。
したがって、この場合は「T系の中間テーブルにあってTT系の中間テーブルにはないレコード」が削除対象となります。

どのように対応すればよいでしょうか?

[T_取引履歴]から[TT_取引履歴]に複写されるレコードが1件のみである場合は、

  1. T系の中間テーブルのうち、フィールド[取引履歴ID]の値が[F_入力]([TT_取引履歴])のカレントレコードの[取引履歴ID]の値と同じである全てのレコードを削除する。

  2. TT系の中間テーブルのうち、フィールド[取引履歴ID]の値が[F_入力]([TT_取引履歴])のカレントレコードの[取引履歴ID]の値と同じである全てのレコードをT系の中間テーブルに追加する。

という流れで、[取引履歴ID]単位でのレコードの入れ替えを行う形になるかと。
レコードの削除は削除クエリ( DELETE 文)で、レコードの追加は追加クエリ( INSERT INTO 文)で行えばよいでしょう。

但し、削除クエリを実行した後に追加クエリの実行に失敗する(結果、既存のレコードの削除だけが行われる)こともあり得ますので、前述の通りトランザクション処理を行うことが望ましいです。

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

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

#27

PyPyPython

総合スコア132

投稿2025/05/20 02:53

#26
説明ありがとうございます。
更新クエリではなく削除クエリと追加クエリを用いて、「編集完了」ボタンを押した時に、当該の取引履歴IDのT_〇〇のレコードを削除し、TT_○○のレコードをT_〇〇に追加する、というイメージで合っていますでしょうか?

トランザクション処理というのは、今回の場合だとどのように行えばよいでしょうか?
こちらの参考例のようにすればよいでしょうか?

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

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

#28

sk.exe

総合スコア1082

投稿2025/05/20 05:26

#27

更新クエリではなく削除クエリと追加クエリを用いて、「編集完了」ボタンを押した時に、当該の取引履歴IDのT_〇〇のレコードを削除し、TT_○○のレコードをT_〇〇に追加する、というイメージで合っていますでしょうか?

中間テーブルに関しては概ねそういうことです。
親テーブルである[T_取引履歴]については更新クエリで対応して下さい。

トランザクション処理というのは、今回の場合だとどのように行えばよいでしょうか?

DAO を使用する場合は Workspace オブジェクト、ADO を使用する場合は Connection オブジェクトの各種メソッドを適宜呼び出して下さい。
大まかな流れとしては、例えば次のような形になるでしょう。

〈新規入力モード〉の場合

  1. 新しいトランザクションを開始する。

  2. [TT_取引履歴]のレコード1件を[T_取引履歴]に新規レコードとして追加する(追加クエリの実行)。この時、[取引履歴ID]以外のフィールドの値を新規レコードの各フィールドに出力する形とすること。

  3. 上記 2 において追加された新規レコードの[取引履歴ID]の値(オートナンバー)を取得する。

  4. [TT_エントリー根拠]の全てのレコードの[取引履歴ID]の値を上記 3 で取得した値に更新する(更新クエリの実行)。

  5. [TT_エントリーメンタル]の全てのレコードの[取引履歴ID]の値を上記 3 で取得した値に更新する(更新クエリの実行)。

  6. [TT_クローズ根拠]の全てのレコードの[取引履歴ID]の値を上記 3 で取得した値に更新する(更新クエリの実行)。

  7. [TT_クローズメンタル]の全てのレコードの[取引履歴ID]の値を上記 3 で取得した値に更新する(更新クエリの実行)。

  8. [TT_エントリー根拠]の全てのレコードを[T_エントリー根拠]に追加する(追加クエリの実行)。

  9. [TT_エントリーメンタル]の全てのレコードを[T_エントリーメンタル]に追加する(追加クエリの実行)。

  10. [TT_クローズ根拠]の全てのレコードを[T_クローズ根拠]に追加する(追加クエリの実行)。

  11. [TT_クローズメンタル]の全てのレコードを[T_クローズメンタル]に追加する(追加クエリの実行)。

  12. 現在のトランザクションを終了(コミット)し、上記 2 から 11 までに行われた変更を保存する。

〈更新モード〉の場合

  1. 新しいトランザクションを開始する。

  2. [T_取引履歴]と[TT_取引履歴]を[取引履歴ID]同士で内部結合し、[T_取引履歴]側の([取引履歴ID]を除く)各フィールドの値を[TT_取引履歴]側の同名のフィールドの値に更新する(更新クエリの実行)。

  3. [T_エントリー根拠]と[TT_取引履歴]を[取引履歴ID]同士で内部結合し、[T_エントリー根拠]のレコードを削除する(削除クエリの実行)。

  4. [T_エントリーメンタル]と[TT_取引履歴]を[取引履歴ID]同士で内部結合し、[T_エントリーメンタル]のレコードを削除する(削除クエリの実行)。

  5. [T_クローズ根拠]と[TT_取引履歴]を[取引履歴ID]同士で内部結合し、[T_クローズ根拠]のレコードを削除する(削除クエリの実行)。

  6. [T_クローズメンタル]と[TT_取引履歴]を[取引履歴ID]同士で内部結合し、[T_クローズメンタル]のレコードを削除する(削除クエリの実行)。

  7. [TT_エントリー根拠]の全てのレコードを[T_エントリー根拠]に追加する(追加クエリの実行)。

  8. [TT_エントリーメンタル]の全てのレコードを[T_エントリーメンタル]に追加する(追加クエリの実行)。

  9. [TT_クローズ根拠]の全てのレコードを[T_クローズ根拠]に追加する(追加クエリの実行)。

  10. [TT_クローズメンタル]の全てのレコードを[T_クローズメンタル]に追加する(追加クエリの実行)。

  11. 現在のトランザクションを終了(コミット)し、上記 2 から 10 までに行われた変更を保存する。

例外処理について

  • トランザクションが開始されてから終了するまでの間に呼び出されるいずれかの処理において、もし何らかの実行時エラーが発生した場合はロールバック処理と警告メッセージの表示を行うよう、適宜エラートラップの設定を行うこと。

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

この意見交換はまだ受付中です。

会員登録して回答してみよう

アカウントをお持ちの方は

関連した質問