- ベストアンサー
1つのフォームから5つのテーブルに情報を登録する方法
- 1つのフォームから5つのテーブルに情報を登録する方法を教えてください。
- 現在、5つのテーブルがあり、それぞれ品番、設備名に対する異なる情報が記録されています。
- 新しい品番が追加された場合、設備名、単価、生産能力、材料使用名、担当者名のテーブル全てに新しい項目を追加する方法を教えてください。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
#1、2です 補足がないですが、まとめてみました。 以下、やりたいことになっていなかったらスルーしてください。 ※ 試される時には、バックアップは忘れずに 1)クエリの作成 2)クエリをもとに表形式のフォームを作成 の順で記述します。 1)クエリの作成 テーブル名を1番~5番と略記します。 ・クエリをデザインから、1番~5番を表示します。 ・1番から各2番~5番へ矢印が向く結合線を「品番」「設備名」で設定します。 ・表示するフィールドを指定していきます(以下順でダブルクリック) 1番の「品番」「設備名」 2番の「品番」「設備名」「単価」 3番の「品番」「設備名」「生産能力」 4番の「品番」「設備名」「使用材料名」 5番の「品番」「設備名」「担当者名」 ・下に表示されているフィールド欄の重複している「品番」「設備名」を変更します。 テーブル欄が2番のは「T2_1: 品番」「T2_2: 設備名」 テーブル欄が3番のは「T3_1: 品番」「T3_2: 設備名」 テーブル欄が4番のは「T4_1: 品番」「T4_2: 設備名」 テーブル欄が5番のは「T5_1: 品番」「T5_2: 設備名」 ・クエリを「Q1」名で保存します。 2)クエリをもとに表形式のフォームを作成 クエリ「Q1」をもとに、フォームウィザードでフォームを作成していきます。 ・クエリ「Q1」を選択し、漢字部分を「>」ボタンで追加していきます。 (品番、設備名、単価、生産能力、使用材料名、担当者名) ・表形式で作成します。 ・フォーム名を決定し、編集で完了させます。 2-1)フォームの修正 ・プロパティを表示させ、 フォームの「レコードセット」を「ダイナセット(矛盾を許す)」に変更します。 ・フォームの「更新前処理」を[イベントプロシージャ]にし、右横の「・・・」をクリックします。 Private Sub Form_BeforeUpdate(Cancel As Integer) End Sub が表示されるので以下の様に記述します (2番~5番の主キーがオートナンバであると仮定) Private Sub Form_BeforeUpdate(Cancel As Integer) If (IsNull(Me.品番) Or IsNull(Me.設備名)) Then Cancel = True Exit Sub End If If (Not IsNull(Me.単価)) Then Me.T2_1 = Me.品番 Me.T2_2 = Me.設備名 End If If (Not IsNull(Me.生産能力)) Then Me.T3_1 = Me.品番 Me.T3_2 = Me.設備名 End If If (Not IsNull(Me.使用材料名)) Then Me.T4_1 = Me.品番 Me.T4_2 = Me.設備名 End If If (Not IsNull(Me.担当者名)) Then Me.T5_1 = Me.品番 Me.T5_2 = Me.設備名 End If End Sub 各テーブルに登録/更新する際に必要となる、「品番」「設備名」を設定します。 各テーブルに必要なものが入力されていたらという条件で設定しています。 「品番」「設備名」「単価」が入力されたとすると、1番、2番に設定されます。 3番~5番には、レコードは存在しません。 クエリを作成する時に2番~5番に別途主キーが設定されていたとして、 「T5_3: 主キー項目」の様に追加しておいたとすると、 登録時に主キーを生成する処理を盛り込むと、 If (Not IsNull(Me.担当者名)) Then If (IsNull(Me.T5_3)) Then Me.T5_3 = "XXXX" ' 主キーの設定 End If Me.T5_1 = Me.品番 Me.T5_2 = Me.設備名 End If 「品番」「設備名」が入力されたら、無条件に2番~5番へレコード追加するのであれば (2番~5番の主キーがオートナンバであると仮定) Private Sub Form_BeforeUpdate(Cancel As Integer) If (IsNull(Me.品番) Or IsNull(Me.設備名)) Then Cancel = True Exit Sub End If Me.T2_1 = Me.品番 Me.T2_2 = Me.設備名 Me.T3_1 = Me.品番 Me.T3_2 = Me.設備名 Me.T4_1 = Me.品番 Me.T4_2 = Me.設備名 Me.T5_1 = Me.品番 Me.T5_2 = Me.設備名 End Sub レコードセレクタを使って削除すると、全テーブルから削除されます。 2番~5番の「品番」「設備名」が主キーになっているのなら、#1で書いたように 1番から各2番~5番の「品番」「設備名」に矢印が向く結合になっていれば、 > 品番、設備名、単価、生産能力、使用材料名、担当者名をクエリ表示する時には、 > 品番、設備名は、1番テーブル、他は各テーブルからのものにします。 のクエリだけで各2番~5番の「品番」「設備名」は設定されます。 (2番~5番の主キーがオートナンバであると仮定した場合) ただし、例えば「担当者名」をNULLにすると、5番の「品番」「設備名」は残ります。 残った時の処理は同じように(以下)しないとだめだと思います。 更新の時に、表示されたものをNULLにすると、そのテーブルには、 「品番」「設備名」のみのものが残ることになります。 (指定した部分はNULLに更新されます) 例えば、5番「担当者名」に記述していたものを、NULLにすると、 担当者名がNULLの、「品番」「設備名」が残ることになります。 一対多ということなので、単純に削除してよいものかわかりませんが、削除するとしたら フォームの「更新後処理」イベントに記述します。 Private Sub Form_AfterUpdate() Dim sSql As String Dim iPos As Long Dim bDel As Boolean bDel = False If (IsNull(Me.単価) And (Not IsNull(Me.T2_1))) Then sSql = "DELETE * FROM 2番 WHERE 品番='" & Me.T2_1 _ & "' AND 設備名='" & Me.T2_2 & "';" CurrentProject.Connection.Execute sSql bDel = True End If If (IsNull(Me.生産能力) And (Not IsNull(Me.T3_1))) Then sSql = "DELETE * FROM 3番 WHERE 品番='" & Me.T3_1 _ & "' AND 設備名='" & Me.T3_2 & "';" CurrentProject.Connection.Execute sSql bDel = True End If If (IsNull(Me.使用材料名) And (Not IsNull(Me.T4_1))) Then sSql = "DELETE * FROM 4番 WHERE 品番='" & Me.T4_1 _ & "' AND 設備名='" & Me.T4_2 & "';" CurrentProject.Connection.Execute sSql bDel = True End If If (IsNull(Me.担当者名) And (Not IsNull(Me.T5_1))) Then sSql = "DELETE * FROM 5番 WHERE 品番='" & Me.T5_1 _ & "' AND 設備名='" & Me.T5_2 & "';" CurrentProject.Connection.Execute sSql bDel = True End If If (bDel = True) Then iPos = Me.Recordset.AbsolutePosition Me.Requery Me.Recordset.AbsolutePosition = iPos End If End Sub 「品番」「設備名」をテキスト型とした時の例です。 各入力項目がNULLで、品番にあたる部分がNULLでなかったら、削除します。 部分的に削除が行われると、フォーム上の表示は #Deleted になるので、Requery します。 単純に Requery すると、表形式のために表示は先頭に戻ります。 Requery しても操作をした行から外れないように、後半の If (bDel ・・・ 部分で処理します。 クエリを作成する時に2番~5番に別途主キーが設定されていたとして、 「T5_3: 主キー項目」の様に追加しておいたとすると、 If (IsNull(Me.担当者名) And (Not IsNull(Me.T5_3))) Then sSql = "DELETE * FROM 5番 WHERE 主キー項目='" & Me.T5_3 & "';" CurrentProject.Connection.Execute sSql の様にも変形できます。(主キー項目がテキスト型だった場合) ※※ 一対多といっても、各2番~5番内で「品番」「設備名」が重複しない場合のものです。 各2番~5番内で重複する場合は、1番が親フォーム、2番~5番が各サブフォームで、 リンク親/子フィールドに「品番」「設備名」を設定します。 前述同様に2番~5番の更新前処理で、それぞれの主キーを設定する記述が必要になります。 この親子フォームの作成手順が必要であれば、補足してください。 (親子フォームも1つのフォームと思いますので)
その他の回答 (2)
- 30246kiku
- ベストアンサー率73% (370/504)
> リレーションシップは1対多になっています 1番、2番テーブルのサンプルを載せてもらえませんか。 2~3件でも 2番テーブルの主キーはどのようなものに設定されていますか。 できれば他の3番~5番テーブルも
- 30246kiku
- ベストアンサー率73% (370/504)
1番テーブルから、2番~5番テーブルへのリレーションシップ設定はどのようになっていますか。 (一対一の関係でしょうか) リレーションシップは、1番テーブルから2番~5番テーブルへ矢印が向く設定にします。 品番、設備名、単価、生産能力、使用材料名、担当者名をクエリ表示する時には、 品番、設備名は、1番テーブル、他は各テーブルからのものにします。 品番、設備名、単価を設定し登録すると、1番、2番テーブルのみに登録されます。 後で、担当者名を入力すると、5番テーブルにのみ追加されます。 1番テーブルにあっても、2番~5番の各テーブルに無いものは空欄になります。 (空欄=そのテーブルにレコードがないことになります) > フォームで、新品番、設備名・・・を入力すれば、5つのテーブル全てに新品番が登録され、それぞれのデータが入力される様にするにはどの様にしたらいいでしょうか? 上記クエリをレコードソースとするフォームとします。 動きとしては前述の様になりますが、必ず全テーブルに登録したいのであれば、 空欄を作らないように「既定値」を設定しておきます。 (単価、生産能力、使用材料名、担当者名の各既定値に)
補足
1番のテーブルが品番、設備名の2つを主キーにしているので、リレーションシップは1対多になっています。 このままでは無理でしょうか?
お礼
丁寧な回答本当にありがとうございます。 只今、出張先でして、一通り読ませて頂きましたが、帰ってから実行してみたいと思います。