- 締切済み
Access 既に開いているフォームへの値渡し
Access初心者です。 業務管理DBを作成し、行き詰ってしまいました。 どなたかアドバイスお願いいたします。 フォームA: 受付日付、担当、顧客情報、注文内容などそれぞれのマスタテーブルからおもなフィールドを クエリで作成 フォームB: 顧客情報テーブルを単票で作成 注文受付時に顧客がリーピータでない場合、フォームAからコマンドボタン実行し、 フォームBを開き、顧客情報テーブルに新規登録します。 《AからBをOpen》 フォームBで顧客情報の新規登録完了後、コマンドボタンを押下し、 その値(顧客ID)をフォームAに渡したいのですが、うまくいきません。 《B→A 値引き渡し》 --------------- Private Sub cmd_BT_Click() DoCmd.OpenForm "フォームA", , , "顧客ID=" & Me.顧客ID End Sub --------------- 他のフォーム間 《A→C》 では、上記のコマンドで正常に動作することを確認できています。 フォームA側のプロパティなど調べましたが、見当がつきません。 こういう場合は、どのあたりを手掛かりに調べればよろしいのでしょうか。 キーワードなどなんでも結構です。 用語などまだ理解していないところはありますが、 なにとぞご教示願います。
- みんなの回答 (10)
- 専門家の回答
みんなの回答
- 30246kiku
- ベストアンサー率73% (370/504)
動き等、欠片でも参考になるところがあれば お疲れ様です。#5です > 解決できるといいですね。 > 目的は、フォームAの新規のレコードにBで選択した顧客IDを登録したいのですが・・・ 現状、解決されていないという認識でよいでしょうか また、見込みもまだない/解決には程遠いという認識でよいでしょうか #3では状況を確認したい記述にしていたので、 #5で、それに対しての補足も要りませんって(まだ記述がなかったので)・・・ 宣言させてもらいました。(という気でいました) でも、記述ありがとうございました。 自己解決されていましたらスルーという事で。(あれから1週間経ってますからね) (補足をいただいたお礼です、と言いつつお礼になっていないかも) > >まず、そのフォームAで、顧客ID に入力できますか。 > 入力できませんでした。 > そもそも、フォームAを作成した当初は顧客IDは存在せず、「既存フィールドの追加」で、 > 顧客テーブルから、オートナンバーの顧客IDフィールドを追加したものでした。 > つまり、フォームAの顧客IDのテキストボックスは、"(新規)"という文字が表示されていて、 > 手動で入力できなくなっています。 > これが問題なのでしょうか。 たぶん、これが原因と思います。 フォームAに指定したクエリがどのようなものかわかりませんが、 フォームAの入力時に「顧客テーブル」を参照する場合、(多側の入力を主とした場合) クエリ上から「顧客テーブル」に関する記述を排除し、 フォームAの「顧客ID」部分で、「顧客テーブル」をルックアップするようにします。 例えば、「注文テーブル」の「顧客ID」をフォームに表示したとすると、 「顧客ID」部分をコンボボックスにして、「顧客テーブル」を見るようにします。 コンボボックス「顧客ID」の値集合ソースを SELECT 顧客ID, 名前, 電話番号 FROM 顧客テーブル とし、連結列を 1 、列数を 3、列幅は適当に、しておくと、 顧客情報内の「名前」「電話番号」を表示したい場合は、テキストボックスを作成し、 そのコントロールソースをコンボボックス「顧客ID」の何列目 =[顧客ID].[Column](1) と記述すると2列目の「名前」 「電話番号」は同様に =[顧客ID].[Column](2) とすることで表示できます。 クエリで2つのテーブルを結びつけた時、どちらのテーブルの「顧客ID」を表示するかによって 更新できる/出来ない等々紛らわしくなるので、私は、ルックアップを結構使います。 (一側のテーブルを参照するところは全部かな・・・極端な言い方かもしれません) このルックアップはテーブルのデザイン上でも設定でき、 テーブルで設定後、フォームウィザードを使ってフォームを作ると、 ルックアップの設定により、自動的にコンボボックス等で作成してくれます。 また、「顧客ID」をテキストボックスのままにしておきたい場合は、 非表示のコンボボックスを上記同様の内容で作成して、 コントロールソースを「顧客ID」とすると テキストボックスの「顧客ID」の値に連動してコンボボックスも動くので 「名前」「電話番号」も容易に表示できます。 (このやり方は、Web上のどこかに触れるものがあったと思います) 非表示のコンボボックス/それを参照している部分を、まるまるサブフォームにして、 サブフォームのレコードソースに、コンボボックスの値集合ソースを記述し、 「名前」「電話番号」を連結し、リンク親子フィールドをともに「顧客ID」とすると、 連動してくれます。 まず、上記の変更を行うと、「顧客ID」部分が "(新規)" になることはないので、 値の受け渡しはスムーズにいくようになると思います。 (「顧客ID」部分が"(新規)"になるようなクエリはどう作ったら・・・わかってません) ただ、上記のようなフォーム構成にすると、顧客を新規登録後、 顧客IDの値を渡すだけではなく、コンボボックスも更新させないといけないので、 フォームAに関数を用意し、フォームBで新規登録後、その関数を呼び出すようにします。 その関数の中で、コンボボックスの再クエリ、値の設定を行うようにします。 フォームA上、「顧客ID」はテキストボックス、非表示コンボボックスを「cbx1」 テキストボックスをダブルクリックした時にフォームBを開く と仮定した場合の例) Public Sub SetText(v As Variant) Me.cbx1.Requery Me.顧客ID = v End Sub Private Sub 顧客ID_DblClick(Cancel As Integer) DoCmd.OpenForm "フォームB" Cancel = True End Sub 起動されたフォームBでの記述例 Dim ctlRet As Form Private Sub Form_Open(Cancel As Integer) On Error Resume Next Set ctlRet = Screen.ActiveControl.Parent End Sub Private Sub 新規登録_Click() ' ' ここで顧客情報の新規登録を行っておく ' 登録後、テキストボックス Me.顧客ID に新規番号があるものとして If (Not ctlRet Is Nothing) Then Call ctlRet.SetText(Me.顧客ID.Value) DoCmd.Close acForm, Me.Name, acSaveNo End Sub Private Sub Form_Close() Set ctlRet = Nothing End Sub 誰から起動されたのか(フォームを)覚えておいて、起動元フォームの関数を呼び出します。 例で用意した関数の引数は Variant にしています。 SetText(Me.顧客ID.Value) なら、値のみが渡っていきますが、 SetText(Me.顧客ID) なら、テキストボックス自体が渡っていきます。 この辺りは、注意が必要です。(テキストボックス自体が必要なら、それはそれで・・・) 例では SetText という名前の関数を用意しましたが、何をするのかは関数内の記述次第・・・ 引数の設定も自由なので、例えば、 Public Sub SetText(bNew as Boolean, v As Variant) If (bNew) Then Me.cbx1.Requery Me.顧客ID = v End Sub と、bNew = True のみコンボボックスを Requery するように記述したとすると 新規に作ったら Call ctlRet.SetText(True, Me.顧客ID.Value) 値のみを設定するのなら Call ctlRet.SetText(False, Me.顧客ID.Value) とかとか・・・ これらの他にも、 値の受け渡しにグローバル変数を使って・・・ 顧客新規登録操作をコンボボックスのリスト外入力時に行う・・・ 等々、実現方法はいろいろとあると思います。 従来のボタンクリックでも・・・ 従来のファームAで、「リーピータでない場合」の判別はどのようにされていましたか。 入力規則を使われていましたか? テキストボックスをコンボボックスに変更し「入力チェック」を「はい」に設定すると 「リスト外入力時」が先に動くようですので、この辺も注意する必要があります。 「いいえ」なら、入力規則でのチェックが生きてきます。 (存在しない顧客IDを入力した場合ですが) 言葉(文字)だけで、どこまで伝わったでしょうか。 (字数制限は 2000 → 4000 字になったようですが:この記述は 3600 弱) (伝える記述が出来ていない私にも問題はあると思いますけど) 参考になる/ならない等々、すべて自己責任でお願いします。 以上 私からはこれが最後です。 ※ Access に関して、Access Club / moug 等、より詳しい人多いですよ。
- DexMachina
- ベストアンサー率73% (1287/1744)
No.8です。 すみません、風邪で体調を崩していました(汗) > フォームAの新規のレコードにBで選択した顧客IDを登録したいのですが、 > 今回は、Bで選択した顧客の注文履歴がフィルタされています。 フォームBは、既存の顧客情報も表示可能になっている、ということで よろしいでしょうか。 (新規追加した顧客には、「注文履歴」はまだないはずなので) だとすると、前回提示のコードは「実行時のカレントレコード=新規顧客」 という前提になっていますので、これに、「新規追加された顧客のレコード への移動」を追加して、「実行時のカレントレコードは常に新規顧客の レコード」という状態にしてやる必要があります。 ※新規顧客を複数追加した場合は、最終追加分のみが対象となります。 (「Forms!フォームB!顧客ID」で参照できるのは、カレントレコード(=フォーム の左端に横向きの「▲」が表示されるレコード)の値のみのため) Private Sub cmd_BT_Click() RunCommand acCmdSaveRecord '念のため、フィルタと並べ替えを解除 Me.FilterOn = False Me.OrderbyOn = False '「顧客ID」で降順で並べ替え(→先頭レコード=最終追加顧客) Me.Orderby = "[顧客ID] Desc" Me.OrderbyOn = True Forms!フォームA.FilterOn = False Forms!フォームA.Filter = "顧客ID=" & Me.顧客ID Forms!フォームA.FilterOn = True End Sub ※フォームBで絞り込みや並べ替えを行わないことを前提にできるなら、 「フィルタと並べ替えの解除&顧客IDでの降順並べ替え」の代わりに 「DoCmd.GotoRecord acForm, Me.Name, acLast」で最終レコード に移動させるだけでもOkです。 これで、フォームAには、「フォームBで新規追加した顧客ID」によるフィルタ がかかることになります。 (但し、前回の回答でも記載した通り、クエリでの結合が「→」型ではなく 「-」型だった場合は、注文履歴がない(=他のテーブルに該当レコードが ない)はずなので、レコードは1件も表示されないことになります) ・・・なのですが、フォームAでの処理内容を改めて考えてみると、フォームA のクエリも作り変えた方がよさそうです(汗) というのは、フォームA用のクエリに顧客情報(マスタ)のフィールドが直接 使用されていると、そのフィールドを(間違って)編集した場合などに、参照 整合性関連のエラーが発生してしまったりするからです。 ですので、フォームA用のクエリからは、顧客マスタの情報は直接参照する のではなく、『顧客マスタを「値集合ソース」としたコンボボックス』か、 『DLookup関数を使用して値の参照のみを可能にしたテキストボックス』を 使用する形をお勧めします。 (より推奨されるのは、前者のコンボボックスを使用した方法です) <フォーム上のコンボボックスで、顧客IDから顧客名を表示させる例> 【書式】タブ 列数: 2 列幅: 3cm; 0cm 【データ】タブ コントロールソース: 顧客ID 値集合タイプ: テーブル/クエリ 値集合ソース: Select 顧客名, 顧客ID From 顧客マスタ; (テーブル名が「顧客マスタ」、表示したいフィールドが「顧客名」の場合) 連結列: 2 ※上では「値集合ソース」にSQL文を指定していますが、テーブルやクエリも 指定できます。 ※「列数」は、「値集合ソース」のテーブル/クエリの、左から何番目の フィールドまでを参照するかを指定します。 ※「列幅」は、コンボボックスのドロップダウンリストでの、上記フィールド群の 表示幅です(「0cm」で非表示) ※「連結列」は、左から何番目のフィールドの値を、「コントロールソース」に 指定したフィールドに格納するかを指定します。 (今回は2番目の「顧客ID」を記録するので、「2」を指定) ※今回のように、「表示フィールド」(=顧客名)と「格納フィールド」(=顧客ID) が異なる場合は、「入力チェック」プロパティは自動で「はい」が選択され、 変更できなくなります。 この形にした場合は、フォームAの「顧客ID」はオートナンバー型ではなくなる はずですので、No.1の方の回答にもあるような「顧客IDの代入」で、新規 レコードを追加することができるようになります。 ※結果、No.4~今回の前半で私が回答してきた「フィルタの適用」は不要 になる、と(汗) Private Sub cmd_BT_Click() RunCommand acCmdSaveRecord Me.FilterOn = False Me.OrderbyOn = False Me.Orderby = "[顧客ID] Desc" Me.OrderbyOn = True 'フォームAの新規レコードに、新規顧客IDを代入 DoCmd.GotoRecord acDataForm, "フォームA", acNewRec Forms!フォームA!顧客ID = Me!顧客ID End Sub ・・・以上です。 ※フォームAのクエリが、顧客マスタ以外の複数テーブルから作成される ことになる場合は、「1対1」または「1対多」の関係を持つフィールドが ないと、新規追加や編集ができなくなるのでご注意ください。 (従来その役割を果たしていた顧客マスタを外すため、関連付け用の フィールドが別途必要になる可能性がある、と)
お礼
丁寧なご回答ありがとうございます。 本件、もう一度最初から作り直すことにしました。 設計の段階から、甘かったようです。 もう一度基本的なところから勉強しながら作り直しをしています。 DexMachinaさんの回答は本当に参考になりました。 ありがとうございました。
- DexMachina
- ベストアンサー率73% (1287/1744)
No.6です。 > 追加した "⇒"の部分が赤文字になり、「コンパイルエラー > 構文エラー」となってしまいます。 すみません、提示コードに間違いがありました(汗) 前回の RunCommand RunCommand acCmdSaveRecord は、 RunCommand acCmdSaveRecord DoCmd.RunCommand acCmdSaveRecord Application.RunCommand acCmdSaveRecord のいずれかお好みのものに変更してください。 ※「RunCommand」はDoCmdオブジェクトとApplication オブジェクトの双方にあります。 このうち、Application配下の場合は「Application.」を 省略可能なため、「RunCommand acCmdSaveRecord」 のみでも機能します。 昨日の回答作成中にIMEのユーザー辞書が壊れたらしく、 「acCmdSaveRecord」の変換がうまくいかなくなったので、 先に打ってあったものをCopy&Pasteしたのですが、その際、 手入力済みだった「RunCommand」を消し忘れてダブりに なってしまったのを、そのまま見落としました(汗) m3_makiさん、フォローありがとうございました。 ----------------------- 前回、画像で追加した件も、ついでで追加説明しておきます。 仮に、今回の添付画像のように「顧客マスタ」と「請求明細」 という2つのテーブルがあったとします。 このとき、顧客マスタに新しい顧客情報を登録したとすると、 当然ながらその直後には、請求明細には対応するレコードが ありません。 そのため、それぞれの「顧客ID」を結合させただけだと、新規 追加した顧客の情報は表示されません。 請求明細に当該レコードがなくても、顧客情報は表示させたい という場合は、添付画像のように、『結合プロパティ』ダイアログ (→結合線(緑枠内)のダブルクリックなどで表示可能)で「2」 (赤枠部分)を指定することで、請求明細テーブルでのレコード の有無によらず、新規追加したものを含めた全顧客の情報が 表示可能になります。 ・・・以上、既にご存知でしたらお目汚しですが(汗)、参考まで。
お礼
ご回答ありがとうございます。 御礼遅れてすみません。 (突然出張が入ったもので、回答いただいたのは確認できたのですが、 ゆっくり動作確認できませんでした。) 結果: フォームBで選択した値がフォームAにわたりました。 ありがとうございます。 しかし、実行後、 フォームAで過去の顧客情報が、フィルタされているようです。 目的は、フォームAの新規のレコードにBで選択した顧客IDを登録したいのですが、 今回は、Bで選択した顧客の注文履歴がフィルタされています。 これも、かなり使えそうですので参考にさせていただきます。 修正すべきコマンドなどあればご教授いただけないでしょうか。 それとも、結合プロパティなどがおかしいのでしょうか。 作り直したほうがよろしいのでしたら、再作成時のポイントなどアドバイスいただければ幸いです。
- m3_maki
- ベストアンサー率64% (296/460)
> ⇒ RunCommand RunCommand acCmdSaveRecord 回答者さんの手が滑ったんでしょう。 DoCmd.RunCommand acCmdSaveRecord です。
- DexMachina
- ベストアンサー率73% (1287/1744)
No.4です。 > 新規登録した顧客情報を、フォームAに渡したいのですが、 > フィルタという概念になるのでしょうか。 ご希望の動作は「フォームBで新規登録したデータを呼び出したい」 ということだと思いますので、そのご理解でOkです。 (「テキストボックス(の(デフォルトプロパティである)Valueプロパティ)」 ではなく、「フォームのFilterプロパティ」への『値渡し』と考えて戴くと わかりやすいかもしれません: 「値渡し」ではあるけれど、その「渡し先」と「渡す値」が異なる、と) ※「デフォルトプロパティ」というのは、大雑把に言うと、「VBAなどで 記述を省略したときに、自動で参照されるプロパティ」のことです。 (「Me.顧客ID.Value」でも「Me.顧客ID」でも同じ値が参照できる のは、フィールドやテキストボックスではValueプロパティがデフォルト プロパティだから、と) > フォームAの顧客IDのテキストボックスは、"(新規)"という文字が > 表示されていて、手動で入力できなくなっています。 > これが問題なのでしょうか。 No.1の方のお礼欄にある「実行時エラー」についてという意味では、 その通りです(=オートナンバー型のフィールドでは値の代入は不可)。 「フォームBで新規登録したデータが反映されない件」については、 これが原因ではありません。 ・・・というか、前回の回答時の、こちらでの確認が不充分でした(汗) 前回の回答では、「そのコードが実行される時点では、既にフォームB でのレコード保存がされている状態」という前提で考えていましたが、 もしもこれが保存されていない場合は、フォームBで追加した(実際には 「追加しようとしている」という状態)レコードは表示できません。 ですので、前回のコードに、「RunCommand acCmdSaveRecord」 などを追加して、レコードの保存を確定させてやる必要があります。 大変失礼致しました(汗) <修正・1案【改】> Private Sub cmd_BT_Click() 'フォームBでの新規追加分を保存 '(このコマンドボタンがもしもフォームB以外にある場合は、 ' あらかじめ、フォームのSetFocusメソッドなどでフォーカスを ' フォームBに移動しておくなどの追加処理が処理が必要) RunCommand RunCommand acCmdSaveRecord Forms!フォームA.FilterOn = False Forms!フォームA.Filter = "顧客ID=" & Me.顧客ID Forms!フォームA.FilterOn = True End Sub ・・・以上です。
お礼
ご回答本当にありがとうございます。(深謝) 以下の内容で修正しました。 ------------------------- Private Sub cmd_BT_Click() 'フォームBでの新規追加分を保存 '(このコマンドボタンがもしもフォームB以外にある場合は、 ' あらかじめ、フォームのSetFocusメソッドなどでフォーカスを ' フォームBに移動しておくなどの追加処理が処理が必要) ⇒ RunCommand RunCommand acCmdSaveRecord Forms!フォームA.FilterOn = False Forms!フォームA.Filter = "顧客ID=" & Me.顧客ID Forms!フォームA.FilterOn = True End Sub ------------------------- 追加した "⇒"の部分が赤文字になり、「コンパイルエラー 構文エラー」となってしまいます。 何か変な設定をしているのでしょうか。 通勤時間なので、詳細な調査は帰宅後に行います。
- 30246kiku
- ベストアンサー率73% (370/504)
#3です 私はここまでです。 解決できるといいですね。
お礼
>私はここまでです。 ありがとうございました。 頭を冷やして、やり直しです。 また機会がありましたら、よろしくお願いいたします。
- DexMachina
- ベストアンサー率73% (1287/1744)
【要旨】 OpenFormメソッドのWhereCondition引数は、実際にフォームが 開かれる時にのみ、有効になります。 (既に開かれているフォームを指定した場合は有効になりません) ですので、対処方法としては a)一旦フォームAを閉じた後(→DoCmd.Close)、再度開くか b)フォームAを指定して、フィルタを適用する (「DoCmd.ApplyFilterを使用する方法」と、「フォームのFilter プロパティ及びFilterOnプロパティを使用する方法」があります) といった方法をとることになるかと思います。 【詳細】 今回のご質問の場合、やりたいこととしては「(既に開いているフォーム に)絞り込み(フィルタ)を掛けたい」ということになるかと思います。 ところが、DoCmd.OpenFormの第4引数(WhereConditions)は、 フォームが開かれる時にのみ適用され、既に展開済みのフォームを 指定した場合には適用されません。 ですので、他の手段が必要となります。 > こういう場合は、どのあたりを手掛かりに調べればよろしいのでしょうか。 私の場合、まず頼りにするのはAccessの「ヘルプ」です。 例えば、今回の件では、 1)Accessのメニューで「ヘルプ(H)→Microsoft Access ヘルプ(H)」を、 またVisual Basic Editor(=VBE:コード入力画面)のメニューで 「ヘルプ(H)→Microsoft Visual Basic ヘルプ(H)」を選択 2)検索条件として「フィルタ」や「絞り込み」を指定して、該当項の内容を 確認 といった手順を踏んで、「ApplyFilter」メソッドや「Filter」メソッドにたどり 着く・・・というのが、j-foremanさんがご自身で解決されようとした場合の 流れになります。 (実際は、検索結果には希望のものと異なるものがかなりの件数で出る ので、必ずしもすんなりとはいきませんが・・・(汗)) ※比較的新しい方のバージョンでは、AccessとVBEでヘルプの内容が 異なる(→Access本体側では、VBA用のヘルプの内容が見られない) ので、両方を見ておく方が無難です。 で、以下が、フォームの「Filter」及び「FilterOn」のプロパティを使用した 場合のサンプルになります。 <現在> Private Sub cmd_BT_Click() DoCmd.OpenForm "フォームA", , , "顧客ID=" & Me.顧客ID End Sub <修正・1案> Private Sub cmd_BT_Click() '念のため、一旦現在のフィルタを解除 Forms!フォームA.FilterOn = False 'Filterプロパティに条件式を設定 Forms!フォームA.Filter = "顧客ID=" & Me.顧客ID 'フィルタを適用 Forms!フォームA.FilterOn = True End Sub ※もしも顧客IDのデータ型が文字列型だった場合は、以下: (「Me.顧客ID」の直前の「=」の後ろ及び末尾の2つの「'」に注目) Forms!フォームA.Filter = "顧客ID='" & Me.顧客ID & "'" また、フォームAを一旦閉じてもよいのであれば(→非連結のテキスト ボックスに、保持させたい値がある場合などはNG)、DoCmd.Closeで 閉じてから、もう一度開きなおしてしまう、という手もあるかと思います。 <修正・2案> Private Sub cmd_BT_Click() 'フォームのデザイン変更があった場合は、保存確認を出した上で '閉じる DoCmd.Close acForm, "フォームA", acSavePrompt DoCmd.OpenForm "フォームA", , , "顧客ID=" & Me.顧客ID End Sub なお、上記で実際に閉じるのをキャンセルすると、エラーが発生します。 このエラーを回避したい場合は、以下のようにします: <修正・3案> Private Sub cmd_BT_Click() 'エラー発生時は、「エラー処理:」の行に飛ばすための宣言 On Error Goto エラー処理 DoCmd.Close acForm, "フォームA", acSavePrompt DoCmd.OpenForm "フォームA", , , "顧客ID=" & Me.顧客ID 終了処理: Exit Sub エラー処理: If Err.Number <> 2501 Then MsgBox Err.Number & ":" & Err.Description, vbCritical, Me.Name End If Resume 終了処理 End Sub ・・・以上です。 【蛇足】 現状ではフィルタを使用されているようなのでその形を踏襲しましたが、 フォームのレコードソースをクエリとすれば、「フォームのRecordSource プロパティを更新」という方法もあり得ますので、今後の参考まで。
お礼
ご回答ありがとうございます。 >今回のご質問の場合、やりたいこととしては「(既に開いているフォーム >に)絞り込み(フィルタ)を掛けたい」ということになるかと思います。 フォームAは、受付日、工事内容、顧客情報など、それぞれのますたから、 クエリで必要なフィールドを連結しています。 フォームBは、顧客情報そのものです。 フォームAで既存の顧客かどうかを判断し、新規の場合は、フォームBを開き、新規顧客を登録します。 新規登録した顧客情報を、フォームAに渡したいのですが、フィルタという概念になるのでしょうか。 いただいた、ソースを試しました。フォームAには情報が渡りませんでした。 ------------------------- <修正・1案> Private Sub cmd_BT_Click() '念のため、一旦現在のフィルタを解除 Forms!フォームA.FilterOn = False 'Filterプロパティに条件式を設定 Forms!フォームA.Filter = "顧客ID=" & Me.顧客ID 'フィルタを適用 Forms!フォームA.FilterOn = True End Sub ------------------------- #2さんにも説明させていただきましたが、 そもそも、フォームAを作成した当初は顧客IDは存在せず、「既存フィールドの追加」で、 顧客テーブルから、オートナンバーの顧客IDフィールドを追加したものでした。 つまり、フォームAの顧客IDのテキストボックスは、"(新規)"という文字が表示されていて、 手動で入力できなくなっています。 これが問題なのでしょうか。
- 30246kiku
- ベストアンサー率73% (370/504)
#2です > →申し訳ありません。「値を戻す」とはどういうことか、理解できません。 ごめんなさい。私の中での言葉でした。 「値を設定する」に置き換えてください。 まず、そのフォームAで、顧客ID に入力できますか。 (フォームBをオープンする処理時に、オープンしない状態で) また、フォームAの顧客IDのコントロールソースの設定はどうなってますか。 テスト用のフォームA'を作成して、 ・テキストボックス「txt00」を1つ ・コマンドボタンを1つ このコマンドボタンに Me.txt00.SetFocus DoCmd.OpenForm "フォームB" を記述し、実行してみて、 フォームBでボタンをクリックした時の動きはどうなりますか。
お礼
ご回答ありがとうございます。 徹夜で直していたもので、お礼が遅れました。 申し訳ありません。 >まず、そのフォームAで、顧客ID に入力できますか。 入力できませんでした。 そもそも、フォームAを作成した当初は顧客IDは存在せず、「既存フィールドの追加」で、 顧客テーブルから、オートナンバーの顧客IDフィールドを追加したものでした。 つまり、フォームAの顧客IDのテキストボックスは、"(新規)"という文字が表示されていて、 手動で入力できなくなっています。 これが問題なのでしょうか。 徹夜でもう一度フォームAを作り直しているのですが、 なんだか集中力が持続せず、ボロボロです。 ちょっと頭を冷やして再チャレンジします。
- 30246kiku
- ベストアンサー率73% (370/504)
操作について補足をお願いしていいですか。 > 《AからBをOpen》 その後 A はどのような状況になっていますか。 ・そのまま ・閉じている(Closeしている) ご質問のタイトルからは、そのままのようだけど ボタンがクリックされた時には OpenForm しているし・・・ また、B を閉じるまでの間、他のフォームを Open することはありますか。 ・A はそのままで閉じていない。 ・他のフォームを Open することはない この条件での簡単な方法は、 B を Open する前に、値が欲しいテキストボックスにフォーカスをあてておく Me.txtXXX.SetFocus DoCmd.OpenForm "フォームB" B は、値を戻してから閉じるんですよね。 であれば、 Me.Visible = False Screen.ActiveControl = Me.顧客ID DoCmd.Close acForm, Me.Name, acSaveNo 自分を非表示にすると、前のフォームがアクティブになり、 フォーカスのあたっているところが ActiveControl で示されます。 なので、そこに値を代入します。 単なる代入なので、受け取った txtXXX ではイベントは何も起きなかったかと。 更新後処理等のイベントを起こしたい時には、 Screen.ActiveControl.Text = Me.顧客ID 条件が違う等、補足をお願いします。
お礼
ご回答、本当にありがとうございます。 > 《AからBをOpen》 その後 A はどのような状況になっていますか。 ・そのまま ・閉じている(Closeしている) →そのままです。 また、B を閉じるまでの間、他のフォームを Open することはありますか。 →・A はそのままで閉じていない。 ・他のフォームを Open することはない まずはじめにAを開きます。 注文が既存の顧客でない場合はBを開き、顧客テーブルに新規登録します。 Bに登録した顧客IDを、Aのフォームに渡したいのです。 他のフォームはOpenしません。 この条件での簡単な方法は、 B を Open する前に、値が欲しいテキストボックスにフォーカスをあてておく →フォームAの、Bを開くときのコマンドボタンに以下のソースを割り当てました。 --------------- Private Sub cmd_BT_B-Open_Click() Me.顧客ID.SetFocus DoCmd.OpenForm "フォームB" End Sub --------------- ここで、フォームBが新規レコードで開きます。 B は、値を戻してから閉じるんですよね。 →申し訳ありません。「値を戻す」とはどういうことか、理解できません。 フォームBで、顧客の新規登録(入力)を済ませます。 この新規登録したBの、顧客IDをフォームAに渡したいのです。 (Aには、他に名前、電話番号などの属性も表示されるようにしています。) ここで問題の、B→A のコマンドボタンのソースを以下にして、実行しました。 --------------- Private Sub cmd_BT_Click() Me.Visible = False ⇒ Screen.ActiveControl = Me.顧客ID DoCmd.Close acForm, Me.Name, acSaveNo End Sub --------------- しかし、「エラー2448、値を代入することはできない」 というポップアップが表示され、 デバックボタンを押下すると、上記矢印の部分が黄色ハイライトされていました。 フォームAの状況は、何も変わらず、そのままの状態です。
- bin-chan
- ベストアンサー率33% (1403/4213)
フォームBのコマンドボタンに以下の行を設定し、オブジェクトに代入してしまう。 'ここでのMeとはフォームBのことです。 Forms![フォームA]![顧客ID] = Me.顧客ID
お礼
ご回答ありがとうございます。 以下のコマンドで実行したのですが、エラーが出てしまいます。 -ソース----------------------- Private Sub CMD_BT_Click() Forms![フォームA]![顧客ID] = Me.顧客ID End Sub ------------------------------- ------------------------------- 実行時エラー'2448' このオブジェクトに値を代入することはできません。 ------------------------------- フォームの作りに問題があるのでしょうか。
お礼
丁寧なご回答ありがとうございます。 本件、もう一度最初から作り直すことにしました。 設計の段階から、甘かったようです。 もう一度基本的なところから勉強しながら作り直しをしています。 今回のご回答は参考にさせていただきます。 ありがとうございました。