ACCESS フォームからサブフォームのデータを更新・入力したい
tbl_プロジェクトというテーブルにIDとプロジェクトコード、プロジェクトの基本情報を持たせ、f_プロジェクトフォームからプロジェクトコード、件名、契約日等のデータ及び、f_テーマサブフォームにテーマを入力できるようなフォームを作成しています。フォームで入力したものをそれぞれのテーブルに保存したいのですがうまくいかない部分があります。
フォームから入力すると、tbl_プロジェクトに所属する情報は更新されます。そのtbl_プロジェクトに所属するプロジェクトコードをサブフォームのtbl_テーマのプロジェクトコードにも反映したいのですがどのようにしたらよいでしょうか?
そういったことは可能でしょうか?分かりにくい説明で申し訳ないですが教えていただけると助かります。よろしくお願いします!
DBの構成
【テーブル】
tbl_プロジェクト (1件1件のIDとプロジェクトコードを持つ)
(フィールド:P_ID、プロジェクトコード、件名、契約日など)
tbl_テーマ(プロジェクト毎に関連のあるキーワードを持つ)
(フィールド:P_ID、プロジェクトコード、テーマ)←これのプロジェクトコードにtbl_プロジェクトのデータが入るようにしたい。
tbl_顧客(プロジェクトを依頼した顧客情報を持つ)
【クエリ】
q_テーマ(プロジェクト、テーマ、顧客を抽出するクエリ)
【フォーム】
f_プロジェクト (プロジェクトを1件ずつ表示・参照・新規作成するフォーム)
f_テーマサブフォーム (f_プロジェクトフォームのプロジェクトコードにづきテーマを
表示・入力するサブフォーム)
リレーションはP_IDをキーに一対多で作成しています。
No.6ベストアンサー
- 回答日時:
No.4です。
前回の回答は、「レコードの新規登録」のみを想定していました(汗)
大変失礼致しました。
【「メインフォーム」-「サブフォームの新規レコード」間の不一致について】
(=No.4の補足での、2個目の「◆」の件)
メインフォーム側の「レコード移動時」イベントで、『プロジェクトコード』の
更新後イベントと同様の処理を行えば、解消すると思います。
(先頭1行が「Private Sub Form_Current()」となる他は、前回のVBAと全く
同じなので、今回は省略します)
【既存レコードでの『プロジェクトコード』の空白について】
(=No.4の補足での、1個目の「◆」の件)
対処法としては、
a)更新クエリを使用して、tbl_テーマの『プロジェクトコード』を一括更新
(→tbl_テーマに入力済みの『P_ID』の再確認が不要な場合)
b)「メインフォーム上のプロジェクトコードを、サブフォームの全レコードに
一括代入」するためのコマンドボタンを、メインフォームに追加
(→tbl_テーマの『P_ID』が正しいかを目視確認してから代入する場合)
の、2つの考え方があります。
「a」については添付画像をご覧いただくとして、ここでは「b」について説明
します。
メインフォームに『コード転記』コマンドボタンを作成したら、そのクリック時
イベントに以下のコードを記載して下さい:
Private Sub コード転記_Click()
If MsgBox("サブフォームにプロジェクトコードを追記します", vbOKCancel, "確認") = vbCancel Then Exit Sub
'サブフォームの全レコードを上書き更新
With Me![サブフォームのコントロール名].Form.RecordsetClone
Do Until .EOF
.Edit
!プロジェクトコード = Me!プロジェクトコード
.Update
Loop
End With
'更新を反映
Me![サブフォームのコントロール名].Form.Refresh
MsgBox "追記しました", , "確認"
End Sub
なお、「a/b」のどちらを採った場合でも、サブフォームの『P_ID』の上書き
編集に合わせて『プロジェクトコード』も連動して更新させるには、別途、
以下のような『P_ID』の更新後イベントでの対応が必要です:
Private Sub P_ID_AfterUpdate()
'メインではなくサブフォームの『P_ID』テキストボックスの更新後イベント
If IsNull(Me!P_ID) Then
Me!プロジェクトコード = Null
Else
Me!プロジェクトコード = DLookup("[プロジェクトコード]", "tbl_プロジェクト", "[P_ID]=" & Me!P_ID)
'『P_ID』がテキスト型の場合は上記ではなく以下のコード
'Me!プロジェクトコード = DLookup("[プロジェクトコード]", "tbl_プロジェクト", "[P_ID]='" & Me!P_ID & "'")
End If
End Sub
また、この対応を組み込んで戴けば、
> テーマを修正するとフォーム上では10001が入力される。
> tbl_テーマには反映されない。
の件も解消すると思います。
(但し、別のレコードに移動したり、メニューから「レコード(R)→レコードの
保存(O)」を選択する等して、レコードが保存してからでないと、テーブル
には反映されないので、確認の際はご注意下さい)
・・・以上です。
ご報告が遅くなり、申し訳ありません。
新規作成の場合、tbl_テーマにプロジェクトコードを登録することが出来ました。
既存レコードのプロジェクトコードの更新がまだうまくいきませんが、なんとか
試してみます。
また、今後はもう少し勉強して、テーブル作成時にきちんと正規化することを
心がけたいと思います。
本当に親切に詳しくご説明いただき、ありがとうございました。また質問させて
いただくと思いますがよろしくお願いいたします。
No.5
- 回答日時:
以下でどうなりますか。
パターン0)(現状? リンク親/子フィールドが P_ID)
「f_テーマサブフォーム」の挿入前処理で、「プロジェクトコード」を親から持ってきます。
Private Sub Form_BeforeInsert(Cancel As Integer)
If (IsNull(Me.Parent.プロジェクトコード)) Then
Cancel = True
Else
Me.プロジェクトコード = Me.Parent.プロジェクトコード
End If
End Sub
If の判別は、
IsNull(Me.Parent.P_ID) Or IsNull(Me.Parent.プロジェクトコード)
でも。
親が設定されていなければ編集状態にしない判別をしているだけです。
挿入前処理なので、新規への設定になります。
パターン1)
f_プロジェクトのレコードソースが、tbl_プロジェクト
f_テーマサブフォームのレコードソースが、tbl_テーマ
だった場合、
リンク親フィールド、リンク子フィールドともに、
P_ID;プロジェクトコード
親が空欄なら編集状態にさせないようにするには、子側で
Private Sub Form_BeforeInsert(Cancel As Integer)
If (IsNull(Me.Parent.P_ID) Or IsNull(Me.Parent.プロジェクトコード)) Then
Cancel = True
End If
End Sub
パターン2)
f_プロジェクトのレコードソースが、tbl_プロジェクト
f_テーマサブフォームのレコードソースは、tbl_テーマをベースに
抽出条件で P_ID = [Forms]![f_プロジェクト]![P_ID] と親フォームを参照
だった場合、(リンク親/子フィールドが空欄だった場合)
パターン0と同様に
Private Sub Form_BeforeInsert(Cancel As Integer)
If (IsNull(Me.Parent.P_ID) Or IsNull(Me.Parent.プロジェクトコード)) Then
Cancel = True
Else
Me.P_ID = Me.Parent.P_ID
Me.プロジェクトコード = Me.Parent.プロジェクトコード
End If
End Sub
サブフォームの再クエリは、必要なタイミングで行います。
パターン3)(パターン0,2と複合して)
既に何件か関連付けられたデータがあって、メインのプロジェクトコードを変更した時に
サブ側のプロジェクトコードも変更したい。
っていう場合?
メイン側の更新前処理でプロジェクトコードに変更があったか判別し、更新後処理で変更
Dim bChg As Boolean
Private Sub Form_BeforeUpdate(Cancel As Integer)
bChg = False
If (Not Me.NewRecord) Then
If (Nz(Me.プロジェクトコード) <> Nz(Me.プロジェクトコード.OldValue)) Then
bChg = True
End If
End If
End Sub
Private Sub Form_AfterUpdate()
Dim sSql As String
If (bChg) Then
sSql = "UPDATE tbl_テーマ SET プロジェクトコード = "
sSql = sSql & IIf(IsNull(Me.プロジェクトコード), "Null", Me.プロジェクトコード)
sSql = sSql & " WHERE P_ID = " & Me.P_ID & ";"
CurrentDb.Execute sSql
End If
End Sub
※プロジェクトコードは数値型とした時のものになります。
※現在tbl_テーマ内のプロジェクトコードが完全じゃない場合、以下クエリで設定します。
UPDATE tbl_テーマ INNER JOIN tbl_プロジェクト ON tbl_テーマ.P_ID = tbl_プロジェクト.P_ID
SET tbl_テーマ.プロジェクトコード = tbl_プロジェクト.プロジェクトコード;
試される時には戻せる状態にしてから・・・
No.4
- 回答日時:
※長文ですが、P_IDとプロジェクトコードが一対一でない場合は、後半
は無視して下さい(汗)
【ご質問の内容通りの動作を行わせる方法】
リレーションシップが設定されている『P_ID』と(ほぼ)同様の動作を
『プロジェクトコード』に行わせるには、メイン側の『プロジェクトコード』
の更新後イベントで、サブ側に既定値を設定します。
<VBAの場合>
Private Sub プロジェクトコード_AfterUpdate()
Dim DefVal As String
'入力値を確認
If IsNull(プロジェクトコード) Then
'値を削除したときは既定値を解除
DefVal = ""
Else
'値を設定したときは既定値を設定
'(数値型/文字列型の双方に対応するため「"」(=Chr(34))で
' 括りましたが、数値型の場合はなくてもOK)
DefVal = Chr(34) & プロジェクトコード & Chr(34)
End If
'上で変数に記録した値を、既定値プロパティに設定
Me![サブフォームのコントロール名]!プロジェクトコード.DefaultValue = DefVal
End Sub
<マクロの場合>
メイン側の『プロジェクトコード』の更新後イベントに以下のマクロを設定:
アクション: 値の代入
アイテム: Forms![メインフォーム名]![サブフォームのコントロール名]!プロジェクトコード.DefaultValue
式: IIF(IsNull(Forms![メインフォーム名]!プロジェクトコード), "", Chr(34) & Forms![メインフォーム名]!プロジェクトコード & Chr(34))
※アイテム・式の一部に、自動で角括弧が追加されます。
【データベースで推奨される方法】
提示サンプルを見ると、『P_ID』と『プロジェクトコード』は一対一の
関係にあるようですが、この場合、『プロジェクトコード』は『P_ID』
からの演算で表示可能なので、サブ側には『P_ID』のみを記録
するのが一般的です。
(サブ側での入力は不要(というか『プロジェクトコード』はなくなる
ので、不可能)になります)
具体的には
a)【検索×・編集×】フォームで演算コントロールを追加
b)【検索○・編集×】クエリで演算フィールドを追加
c)【検索○・編集○(P_IDと連動)】フォーム又はクエリで、『P_ID』
から『プロジェクトコード』を表示させるコンボボックスを追加
等です。
以下、それぞれの概要です:
a)『f_テーマサブフォーム』のデザインビューで、ツールバーから
テキストボックスを新たに追加するか、既にある『プロジェクト
コード』テキストボックスを選択したら、プロパティシートの
『データ』タブの『コントロールソース』に以下のような式を指定
します(先頭に「=」が必要):
=DLookup("[プロジェクトコード]", "tbl_プロジェクト", "[P_ID]=" & [P_ID])
b)『tbl_テーマ』を元とするクエリのデザインビューで、『フィールド:』
欄に以下のような式を指定します(『テーブル:』欄は空白):
プロジェクトコード: DLookup("[プロジェクトコード]", "tbl_プロジェクト", "[P_ID]=" & [tbl_テーマ].[P_ID])
※前半(「:」の左側)は、演算結果を表示させる際の名前になります。
(特に指定しない場合、「式1」などが自動で入力されます)
c)以下、クエリでの例:
1)『tbl_テーマ』を元とするクエリをデザインビューで開く
2)『P_ID』のデータの表示が不要なら1個、表示が必要なら2個、
『P_ID』を表示対象として追加
3)『フィールド:』欄の「P_ID」の1つを、「プロジェクトコード: P_ID」に
変更
4)右クリックメニューなどからこのフィールドのプロパティシートを
開き、『ルックアップ』タブを選択
5)『表示コントロール』に「コンボ ボックス」を指定
6)表示項目が増えるので、以下のように設定:
・値集合タイプ: テーブル/クエリ
・値集合ソース: Select Distinct プロジェクトコード, P_ID From tbl_プロジェクト Order by プロジェクトコード;
・連結列: 2
・列数: 2
・列幅: 5cm;0cm
・・・以上です。
長文、失礼致しました(汗)
この回答への補足
なかなか試すことが出来ず、お礼と報告が遅くなりすみませんでした。
ご指摘いただいたとおり、テーブルを正しい構成にしてCの案を試そうと思っていますが、
取り急ぎ、VBAだけで対処できればと思って試行錯誤しています。
ご回答いただいたVBAを試したところ、サブフォームのプロジェクトコードに関わらず、
メインフォームに入力したプロジェクトコードが表示されてしまいます。そしてやはり
テーブルには反映できません。やはりテーブルを修正しないと思う動作はしないでしょうか??
◆メインに10001と入力すると何も入っていないサブフォームのフィールドには反映される。
また、テーマを修正するとフォーム上では10001が入力される。tbl_テーマには反映されない。
メインフォーム
| [P_ID] [プロジェクトコード] [プロジェクト名]
| 1 10001 新型テレビ
|_______________________________________________
|サブフォーム
|[テーマ] [p_ID] [プロジェクトコード]
|[テーマ1] 1
|[テーマ2] 1
|何も入っていないレコード 10001
________________________________________________
◆メインに10001と入力してから他のプロジェクトコードに移動すると既に入力されている既存のコードは
表示されているが、何も入っていないレコードには10001と表示されている。テーマを修正すると10001が
表示される。
※プロジェクトコードが既存で入っているのは初期データはエクセルに入力後に読み込んだからです。
メインフォーム
| [P_ID] [プロジェクトコード] [プロジェクト名]
| 1 20001 エアコン
|_______________________________________________
|サブフォーム
|[テーマ] [p_ID] [プロジェクトコード]
|[テーマ1] 1 20001
|[テーマ2] 1 20001
|何も入っていないレコード 10001
________________________________________________
No.2
- 回答日時:
すみません。
前回回答は無視して下さい。ほかの用途と混同してました。対応になってません。メインのフォームで入力した内容はメインのレコードソースに更新されるが、同時にサブフォームのレコードソースへも反映させたいようなことでしょうか?。
この回答への補足
はい。そういうことです。メインフォームの中に開かれているサブフォームのプロジェクトコードに
自動的に反映したいのです。
テーブルのリレーションで繋がっているP_IDはメイン、サブともにテーブルに自動的に反映されるのですが、
プロジェクトコードはどうしても反映されません。P_IDは主キーに設定しています。
フォームのイメージとしては↓のような形です。宜しくお願いいたします。
|メインフォーム
| [P_ID] [プロジェクトコード] [プロジェクト名]
| 1 10001 新型テレビ
|_______________________________________________
|サブフォーム
|[テーマ] [p_ID] [プロジェクトコード]
|[テーマ1] 1 10001
|[テーマ2] 1 10001
|[テーマ3] 1 10001
________________________________________________
No.1
- 回答日時:
「f_プロジェクトフォームからプロジェクトコードを入力したとき、」
に
tbl_テーマのプロジェクトコードに【値の代入】をし、その後で再クエリ、かと思われます。
この回答への補足
tbl_テーマのプロジェクトコードに【値の代入】とは、f_テーマサブフォームのプロジェクトコード部分に
設定するということでよいのでしょうか?
テーブルのフィールドに【値の代入】を設定する方法があるのでしょうか?わかっていなくてすみません~~。
また、【値の代入】、再クエリを設定するのはどのイベントが適切なのでしょうか?色々と試していますが
なかなかうまくいきません。宜しくお願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
許せない心理テスト
私は「あなたの目の前にケーキがあります。ろうそくは何本刺さっていますか」と言われ「12本」と答えたら…
-
フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
あなたが普段思っている「これまだ誰も言ってなかったけど共感されるだろうな」というあるあるを教えてください
-
映画のエンドロール観る派?観ない派?
映画が終わった後、すぐに席を立って帰る方もちらほら見かけます。皆さんはエンドロールの最後まで観ていきますか?
-
海外旅行から帰ってきたら、まず何を食べる?
帰国して1番食べたくなるもの、食べたくなるだろうなと思うもの、皆さんはありますか?
-
天使と悪魔選手権
悪魔がこんなささやきをしていたら、天使のあなたはなんと言って止めますか?
-
Access サブフォームでの選択行の取得
その他(データベース)
-
レコードを保存するコード アクセスvba
その他(Microsoft Office)
-
サブフォームの新規レコードに移動したい アクセス
Access(アクセス)
-
-
4
Access 別フォームへの再クエリ(更新)がしたい。
その他(データベース)
-
5
サブフォームに対してGoToRecordするには?
その他(Microsoft Office)
-
6
ACCESSのフォームからデータの追加ができない
その他(データベース)
-
7
Accessで、フォームからフォームへ値を引き継ぐやり方
Access(アクセス)
-
8
accessで重複を防ぎたい
Access(アクセス)
-
9
アクセスでテキストボックスの値が空白だったら
Access(アクセス)
-
10
Accessのレポート上のテキストボックス値を設定したい
その他(データベース)
-
11
ACCESSで空白のデーターをクエリで判定/識別する方法を教えてくださ
Access(アクセス)
-
12
access別のテーブルを参照してテキストボックスに値を表示、編集したい
Access(アクセス)
-
13
Accessで埋め込んだサブフォーム(データシート形式)でデータ追加ができない
Access(アクセス)
-
14
Accessでフォームから別フォームのテキストボックスの値を設定する
Visual Basic(VBA)
-
15
Access VBA サブフォームの更新
その他(データベース)
-
16
Accessのサブフォームから値を参照する方法について
その他(データベース)
-
17
ACCESSで値を代入できないとは?
Visual Basic(VBA)
-
18
親フォームからサブフォームのレコードソースを設定
Access(アクセス)
-
19
Accessでデータシートに同じデータがいくつもでてしまいます。
その他(データベース)
-
20
Access 最後のレコードに到達するまでループ処理を行う方法
Access(アクセス)
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Access レポート印刷するときに...
-
access2021 強制終了してしまう
-
Accessのスプレッドシートエク...
-
access2021 VBA メソッドまたは...
-
実行時エラー3131 FROM 句の構...
-
Accessレポートのチェックボッ...
-
Microsoft365にAccessってあり...
-
accessデータを指定したExcel、...
-
Access 複数条件検索の設定が上...
-
access クエリ yes/no型のクエ...
-
accessの代わりになるもの
-
Accessで作ったデータベースをw...
-
Accessのクエリで、replace関数...
-
Accessでフォームに自動入力し...
-
Access Error3061 パラメータが...
-
Accessのリンクテーブルのパス...
-
Accessで独自メニューバーまた...
-
アクセス レポートを開いたとき...
-
AccessVBAで任意の複数リンクテ...
-
Access DAOのExecuteメソッドの...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
プロジェクトとワーキングの違い
-
EclipseのF3で宣言を開けないで...
-
キックオフ・・
-
「意図と目的」の違いとは?
-
「委員会」「ワーキンググルー...
-
ACCESS フォームからサブフォ...
-
EXCEL VBA 1004 一般ODBCエラー1
-
プロジェクトリーダは無能なエ...
-
クリエイティブディレクターの...
-
古田敦也のFプロジェクトとは?
-
客先の入館証を紛失し、契約取...
-
コンソーシアムとプロジェクト...
-
プロジェクトリーダー要件定義...
-
財務部に属する会社員です。部...
-
システムエンジニア(フリーラ...
-
プロジェクトとプロブラムの違...
-
プロジェクトリーダーの彼
-
IT表現の確認
-
先方に打つメールの文が思いつ...
-
VB6のプロジェクトロードエラー...
おすすめ情報