ms access 複数のテーブルをもとにしたクエリ _ に対応するフォーム _保存用ボタンの動作


ms accessにおいて 

単一のテーブルをもとにしたフォームを作成し

そこにボタンを追加し、

そのボタンを押したときの動作に


     ' Saves the current record

        DoCmd.RunCommand acCmdSaveRecord 


と、記述すると、

そのフォームに対応するテーブルへレコードが保存されると思うのですが、


それとは別に、

複数のテーブルをもとにしたクエリを作成し、


そのクエリに対応するフォームを作成したとき、


そこに配置したボタン内に

上記のコードを記述すると、


そのフォーム内に配置されているのであれば、

その入力欄に対応する各テーブルにたいして、

レコードが記録されるのでしょうか?



Access のフォームにおいて、

`DoCmd.RunCommand acCmdSaveRecord`

 を使用した場合のデータ保存の動作は、

 

 フォームのデータソース(**RecordSource**)が単一のテーブルか、

 複数のテーブルを結合したクエリ(SELECTクエリ)かによって変わります。


---


## **1. 単一のテーブルをもとにしたフォーム**


この場合、フォームのデータソースは 1 つのテーブルであり、

フォーム内のコントロール(テキストボックスなど)に入力したデータは、

そのテーブルに保存されます。


`DoCmd.RunCommand acCmdSaveRecord` を実行すると、

そのレコードが該当のテーブルに保存されます。


---


## **2. 複数のテーブルをもとにしたクエリをデータソースとするフォーム**


### **(1) クエリの種類による影響**


複数のテーブルを結合したクエリ(SELECTクエリ)を

フォームのデータソースに設定した場合、


`DoCmd.RunCommand acCmdSaveRecord` の動作は、

クエリの編集可能性に依存します。



**編集可能なクエリである場合**


- `DoCmd.RunCommand acCmdSaveRecord` を実行すると、

フォームに表示されているフィールドに対応する 

**各テーブル** にデータが保存される。


**編集不可のクエリである場合**


- クエリが更新不可能な場合(例えば、クエリが `DISTINCT` を使っていたり、

集計関数を含んでいたり、結合関係が正しく設定されていない場合)、

フォーム内でデータ入力ができず、


したがって

 `DoCmd.RunCommand acCmdSaveRecord` を実行してもエラーが発生する。


---


### **(2) 編集可能なクエリの条件**


クエリが編集可能であるためには、次の条件を満たしている必要があります:


- **主キー(またはユニークキー)が各テーブルに存在し、

    結合が適切に設定されている**


- **結合(JOIN)が適切に設定されている**

  - `INNER JOIN` または `LEFT JOIN` が適切に設定されていること

  - `RIGHT JOIN` や `FULL OUTER JOIN` ではデータの編集ができない可能性がある

  

- **一部の集計関数

(`SUM`, `AVG`, `COUNT`, `GROUP BY`, `DISTINCT` など) を使っていない**


- **クエリに副問合せ (`SELECT ... FROM (SELECT ...)`) を使っていない**


- **クエリに計算フィールドがある場合、それが主キーの役割を持っていない**


---


### **(3) 正しくレコードが保存されるか確認する方法**


1. フォームのレコードソースとなっているクエリを開いて、

直接レコードを編集できるか確認する。


2. もしクエリ内でデータを編集できるなら、

`DoCmd.RunCommand acCmdSaveRecord` を実行したときに、

フォーム上の各コントロールに対応するテーブルに

レコードが反映される可能性が高い。

3. クエリ内でデータを編集できない場合は、

テーブルの結合方法やクエリの構造を見直す必要がある。


---


### **(4) 例: 2つのテーブルを結合したフォーム**

たとえば、次のような2つのテーブルがあるとします。


**`顧客` テーブル**

| 顧客ID | 名前   | 住所         |

|--------|--------|-------------|

| 1      | 田中   | 東京        |

| 2      | 鈴木   | 大阪        |


**`注文` テーブル**

| 注文ID | 顧客ID | 商品名   | 数量 |

|--------|--------|--------|------|

| 101    | 1      | 本      | 2    |

| 102    | 2      | ペン    | 5    |


これらを結合するクエリを作成するとします。


```sql


SELECT 顧客.顧客ID, 顧客.名前, 顧客.住所, 注文.注文ID, 注文.商品名, 注文.数量

FROM 顧客 INNER JOIN 注文 ON 顧客.顧客ID = 注文.顧客ID;


```


このクエリを元にフォームを作成した場合:


- **このクエリが編集可能であれば**、

フォームで新しい注文を追加したり、顧客情報を更新したりすると、

両方のテーブルにデータが保存される。


- **クエリが編集不可である場合**、

レコードの追加・変更ができず、ボタンを押してもエラーが発生する。


---


### **(5) 編集可能なクエリにするためのポイント**


- クエリに **主キーを含める**


- `INNER JOIN` を使用し、

片方のテーブルのデータがない場合は `LEFT JOIN` を適用


- `GROUP BY` や `DISTINCT` を使用しない


- `ORDER BY` などのソートは編集に影響しないが、

クエリのパフォーマンスに影響を与える場合がある


---


## **結論**


### **Q: `DoCmd.RunCommand acCmdSaveRecord` を実行すると、

結合クエリの各テーブルにデータは保存されるか?**


→ **クエリが編集可能であれば保存される。


ただし、クエリが編集不可の場合は保存されない。**



### **おすすめの確認手順**


1. クエリを直接開いて編集できるか確認


2. フォーム上でデータ入力できるか確認


3. `DoCmd.RunCommand acCmdSaveRecord` を実行し、

データが適切に保存されるかテスト


もしデータが保存されない場合は、クエリの構造を見直し、

編集可能な形に調整する必要があります。



コメント