• 締切済み

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側のプロパティなど調べましたが、見当がつきません。 こういう場合は、どのあたりを手掛かりに調べればよろしいのでしょうか。 キーワードなどなんでも結構です。 用語などまだ理解していないところはありますが、 なにとぞご教示願います。

みんなの回答

  • 30246kiku
  • ベストアンサー率73% (370/504)
回答No.10

動き等、欠片でも参考になるところがあれば お疲れ様です。#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 等、より詳しい人多いですよ。

j-foreman
質問者

お礼

丁寧なご回答ありがとうございます。 本件、もう一度最初から作り直すことにしました。 設計の段階から、甘かったようです。 もう一度基本的なところから勉強しながら作り直しをしています。 今回のご回答は参考にさせていただきます。 ありがとうございました。

  • DexMachina
  • ベストアンサー率73% (1287/1744)
回答No.9

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対多」の関係を持つフィールドが   ないと、新規追加や編集ができなくなるのでご注意ください。   (従来その役割を果たしていた顧客マスタを外すため、関連付け用の   フィールドが別途必要になる可能性がある、と)

j-foreman
質問者

お礼

丁寧なご回答ありがとうございます。 本件、もう一度最初から作り直すことにしました。 設計の段階から、甘かったようです。 もう一度基本的なところから勉強しながら作り直しをしています。 DexMachinaさんの回答は本当に参考になりました。 ありがとうございました。

  • DexMachina
  • ベストアンサー率73% (1287/1744)
回答No.8

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」 (赤枠部分)を指定することで、請求明細テーブルでのレコード の有無によらず、新規追加したものを含めた全顧客の情報が 表示可能になります。 ・・・以上、既にご存知でしたらお目汚しですが(汗)、参考まで。

j-foreman
質問者

お礼

ご回答ありがとうございます。 御礼遅れてすみません。 (突然出張が入ったもので、回答いただいたのは確認できたのですが、  ゆっくり動作確認できませんでした。) 結果: フォームBで選択した値がフォームAにわたりました。 ありがとうございます。 しかし、実行後、 フォームAで過去の顧客情報が、フィルタされているようです。 目的は、フォームAの新規のレコードにBで選択した顧客IDを登録したいのですが、 今回は、Bで選択した顧客の注文履歴がフィルタされています。 これも、かなり使えそうですので参考にさせていただきます。 修正すべきコマンドなどあればご教授いただけないでしょうか。 それとも、結合プロパティなどがおかしいのでしょうか。 作り直したほうがよろしいのでしたら、再作成時のポイントなどアドバイスいただければ幸いです。

  • m3_maki
  • ベストアンサー率64% (295/459)
回答No.7

> ⇒ RunCommand RunCommand acCmdSaveRecord 回答者さんの手が滑ったんでしょう。  DoCmd.RunCommand acCmdSaveRecord です。

  • DexMachina
  • ベストアンサー率73% (1287/1744)
回答No.6

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 ・・・以上です。

j-foreman
質問者

お礼

ご回答本当にありがとうございます。(深謝) 以下の内容で修正しました。 ------------------------- 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)
回答No.5

#3です 私はここまでです。 解決できるといいですね。

j-foreman
質問者

お礼

>私はここまでです。 ありがとうございました。 頭を冷やして、やり直しです。 また機会がありましたら、よろしくお願いいたします。

  • DexMachina
  • ベストアンサー率73% (1287/1744)
回答No.4

【要旨】 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 プロパティを更新」という方法もあり得ますので、今後の参考まで。

j-foreman
質問者

お礼

ご回答ありがとうございます。 >今回のご質問の場合、やりたいこととしては「(既に開いているフォーム >に)絞り込み(フィルタ)を掛けたい」ということになるかと思います。 フォーム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)
回答No.3

#2です > →申し訳ありません。「値を戻す」とはどういうことか、理解できません。 ごめんなさい。私の中での言葉でした。 「値を設定する」に置き換えてください。 まず、そのフォームAで、顧客ID に入力できますか。 (フォームBをオープンする処理時に、オープンしない状態で) また、フォームAの顧客IDのコントロールソースの設定はどうなってますか。 テスト用のフォームA'を作成して、 ・テキストボックス「txt00」を1つ ・コマンドボタンを1つ このコマンドボタンに Me.txt00.SetFocus DoCmd.OpenForm "フォームB" を記述し、実行してみて、 フォームBでボタンをクリックした時の動きはどうなりますか。

j-foreman
質問者

お礼

ご回答ありがとうございます。 徹夜で直していたもので、お礼が遅れました。 申し訳ありません。 >まず、そのフォームAで、顧客ID に入力できますか。 入力できませんでした。 そもそも、フォームAを作成した当初は顧客IDは存在せず、「既存フィールドの追加」で、 顧客テーブルから、オートナンバーの顧客IDフィールドを追加したものでした。 つまり、フォームAの顧客IDのテキストボックスは、"(新規)"という文字が表示されていて、 手動で入力できなくなっています。 これが問題なのでしょうか。 徹夜でもう一度フォームAを作り直しているのですが、 なんだか集中力が持続せず、ボロボロです。 ちょっと頭を冷やして再チャレンジします。

  • 30246kiku
  • ベストアンサー率73% (370/504)
回答No.2

操作について補足をお願いしていいですか。 >  《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 条件が違う等、補足をお願いします。

j-foreman
質問者

お礼

ご回答、本当にありがとうございます。 >  《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)
回答No.1

フォームBのコマンドボタンに以下の行を設定し、オブジェクトに代入してしまう。 'ここでのMeとはフォームBのことです。 Forms![フォームA]![顧客ID] = Me.顧客ID

j-foreman
質問者

お礼

ご回答ありがとうございます。 以下のコマンドで実行したのですが、エラーが出てしまいます。 -ソース----------------------- Private Sub CMD_BT_Click() Forms![フォームA]![顧客ID] = Me.顧客ID End Sub ------------------------------- ------------------------------- 実行時エラー'2448' このオブジェクトに値を代入することはできません。 ------------------------------- フォームの作りに問題があるのでしょうか。

関連するQ&A

  • ACCESS フォームからフォームへの連携

    例えば  A_テーブル(フィールド:会員NO・顧客名・連絡  先)でのA_フォーム上でコマンドボタン「B」を  作成しています。ボタンをクリックすると   Docmd. OpenForm"B_フォーム" が実行されます。  実行され新しく開いた  B_フォーム(フィールド:管理NO・会員NO・備考) の会員NOの中に、その時開いていたA_テーブルの会 員NOが入っている状態にすることは可能でしょう  か? 乱文で大変申し訳ありません。 現在顧客管理のデータベースを作りはじめましたが なにぶん手探り状態ですので、今後ともよろしくお 願いいたします。 ( WindowsXP : Access2000)

  • Access2000 フォーム間での値渡しについて

    お世話になります。 フォームA、Bがありまして、AからBに値を渡し、Bフォームの初期表示としたいのですが、 下記ロジックにて値を渡した後にBフォームを開くと消えてしまします。 ************************************************** 呼出し先(Bフォーム) Public Sub 値渡しで展開(値) Text=値 DoCmd.OpenForm B 呼出し元(Aフォーム) Call B.値渡しで展開(値) ************************************************** VBにて同じ方法にて実現できているのですが、VBAでは異なるのでしょうか? ご回答よろしくお願いいたします。

  • ACCESS VBA 一覧から別フォームを開きたい

    顧客管理をしようとしています。 表形式のフォームで一覧を表示させています。 一覧の詳細セクションに「詳細」というボタンをつけていて、 すべての行に、詳細ボタンを表示させています。 この詳細ボタンを押したら、この顧客カード(単票形式のフォーム)を開きたいと思っています。 現在、下記の記述をしていますが、 「抽出条件でデータ型が一致しません」とのエラーメッセージが出ます。 どこを修正したら良いかわかりません。 わかる方、よろしくお願いいたします。 現在の記述 Private Sub コマンド29_Click() If Me.NewRecord Then MsgBox "新規レコードから詳細情報を表示することはできません。" Else DoCmd.OpenForm "顧客フォーム", , , "顧客ID='" & 顧客ID & "'" End If End Sub

  • Accessでコマンドから空のフォームを開くには?(初心者です)

    Access2003を使用して顧客名簿を作成しています。 コマンドボタン「新規入力」を押すと空のフォームが 開くようにしたいのですが、どのようにしたら良いのでしょうか? 一応、初心者なりに Private Sub コマンド4_Click() Dim namae namae = "個人住所フォーム" DoCmd.OpenForm namae, acNormal End Sub まではやったのですが、開いたフォームは名簿の一番最初の方の データでした・・・。

  • Access2002 フォーム間のデータ受け渡し条件による動作分岐

    いつもお世話になっております。 未だ初心者のものです。 表題ではわかりにくいと思いますが、ああしか書けなかったのでお許し下さい。 本題ですが、人員の情報フォーム(フォームA)に、コマンドボタンを設け、他のフォーム(フォームB)を開く作りにしています。 コマンドボタンを作成するときに自動起動されるウィザードにしたがって、人員のIDとマッチするデータを表示するよう、コマンドボタンは設定されています。 フォームBの元になっているテーブルに、その人員のIDと付帯情報が入っていればフォームBはうまく表示されるのですが、まだ付帯情報が入っていない場合、当たり前ですが空白のフォームが現れます。 そこでご相談なのですが、フォームBの元テーブル(あるいはクエリ)にデータがない場合はフォームB用のデータ入力をさせるフォーム(フォームC)を表示させる様にはできませんでしょうか? これだけの情報ではイメージできないかも知れませんので、追加情報が必要であれば、逆質問をお願いします。 よろしくご回答のほど、お願いします。

  • MS-ACCESSのフォーム切り替え表示について

    フォームA(少量データ)からフォームB(大容量データ)を呼び出して表示させる方法について 教えてください。 まず、フォームAは複数の個人名のボタンとサブフォームで全員の最新情報が表示される ものを作っています。 この個人名のボタンをクリックするとフォームBにその個人の全情報を表示させる仕組みなのですが、フォームBは情報量が多い為、表示させるのに時間がかかります。 そこで下記のようなVBAを記述し、Do~LoopでフォームBが開くまでの時間を稼ごうと思っても 次の処理が行なわれてしまい、エラーになってしまいます。 Private Sub ボタン_Click() DoCmd.OpenForm "フォームB" Do Until SysCmd(acSysCmdGetObjectState, acForm, "フォームB") = acObjStateOpen DoEvents Loop Application.Forms![フォームB].Controls![担当者名] = "担当A" Me.フォームB.Requery End Sub これでフォームBが開くまで待ってから次のステップのフォームB内の条件設定や Requery処理を行なうと思っているのですがうまくいきません。 DoEvents処理が入っているせいかと思い、はずしたのですがそれでもうまくいきません。 もともとはフォームBだけで運用していたのですがデータ量が増えて表示に時間がかかり すぎるので新たに項目は同じで件数の少ない最新情報のみのテーブルを作成し、 それをもとにフォームAを作成しています。 ですのでフォームA,Bともに同じようなサブフォームになっており、またそれぞれの サブフォームを構成するテーブルが異なる為に1つのフォームでの処理ができません。 拙い説明ですがどなたかご教授願います。

  • テーブル・クエリ・フォーム どれがいい?

    アクセス初心者の為、よくわからないので教えてください。 テーブル1があり そこには ID(主キー/オートナンバー型) フィールド1(テキスト型)があります。 そのテーブルを基にクエリ1作成してます。 [SELECT テーブル1.* FROM テーブル1;] です。 また、テーブル1をレコードソースとしたフォーム1も作成しています。 そして図のようにメインメニューフォームを作成し それぞれのコマンドボタンを設置しました。 モジュールには --------------------------------------------------------- Option Compare Database Option Explicit Private Sub コマンド0_Click() DoCmd.OpenTable "テーブル1", acViewPivotTable End Sub Private Sub コマンド1_Click() DoCmd.OpenQuery "クエリ1", acViewPivotTable End Sub Private Sub コマンド2_Click() DoCmd.OpenForm "フォーム1", acFormPivotTable End Sub --------------------------------------------------------- と書いたので どのボタンを押してもピボットテーブルを開けます。 しかしどれか一つにしたいのですが 今後運用するにおいてどれで開けばいいのでしょうか? ピボットテーブルビューで開くならどれも同じでしょうか? 今回はピボットテーブルビューで表示していますが データシートビューでも表示させたい場合があれば 「フォームなら条件付き書式が設定できるからフォームが良いかなー」 と思っています。 確かテーブルやクエリでは条件付き書式はできなかったような・・・ 全てのビューで開くにおいて テーブル・クエリで開くメリットがあれば教えてください。 ご回答よろしくお願いします。

  • access検索フォームからメイン、サブフォームへ

    access初心者です。 先日、「メイン、サブフォームの入力」について質問した者です。 取引先の会社情報を管理するために、access2007で顧客管理を作成しています。 現在、取引先本社情報とその支店情報を新規登録及び既存顧客を編集するフォーム「会社登録フォーム」と「会社検索フォーム」を主にVBAで作成しています。 <実現したいこと>: 既存顧客を編集する場合は「会社検索フォーム」から抽出し、「選択」ボタンで会社情報を「会社登録フォーム」に呼び出し、本社及びその支店情報を編集する。 <困っていること>: 「会社検索フォーム」から顧客を選択後、「会社登録フォーム」では、支店情報は変わりますが、本社情報が変わりません。 (メッセージ:「リレーションシップが設定されたレコードがテーブル'支店テーブル'にあるので、 レコードの削除や変更を行うことはできません。」というメッセージがでます。) <会社登録フォームの環境>: 会社の本社情報をメインフォーム、その会社の支店情報をサブフォームに、単票形式のタブコントロールで複数画面にして、支店ごとに分けて入力できる登録フォームを作成しています。 本社テーブルの会社IDを主キーに、支店テーブルの支店IDを主キーにしてリレーションシップを設定し、クエリ「Q_本社支店」というテーブルを作成しています。 <会社検索フォームの環境>: ・「Q_本社支店」テーブルを元に「会社検索フォーム」を作成しています。 ・「会社名」「支店名」等で検索し、データシートで表示します。 ・ 抽出されたレコードの「選択」ボタンで、「会社ID」を「会社登録フォーム」の本社情報の「会社ID」に代入します。 色々調べてやってはみたのですが、上手くいきません。 行き詰まり感があり、困っております。 ご教授のほどよろしくお願いいたします。

  • Accessのフォーム その2

    すいません、以前にも同じ質問をしたのですが、私の質問の仕方が悪くてうまくいきませんでした。 回答してくださった方、ありがとうございました! もう一度、詳しく質問しなおします。 顧客データを登録しているのですが、テーブルを元に登録フォームを作成しました。 商品がたくさんあって、4つのコードに分かれています。フォームの中に[A][B][C][D]と4つのコンボボックスを作成し、絞込み検索ができるようにはしました。 しかし、選んだデータの[A]しかテーブルに表示されません。例えば[A]のコンボボックスの中から[1010]を選択、[B]のコンボボックスから選択しようとしても空っぽです。 テーブルを見ると、[A]で選んだ[1010]だけが表示されています。 非連結のときはうまく出てたんですが・・。 もしかして連結列が間違ってるのでしょうか?? 元になるテーブルは Aコード A  Bコード B Aコード Cコード C Bコード Dコード D Cコード この2列目を表示したいのです。(2列目が[1010]など表示したいデータ) 列数はそれぞれ「2」で連結列は「2」です。 更新後処理は以下の通りです。 Private Sub コンボ0_AfterUpdate() Me!コンボ2.Requery End Sub Private Sub コンボ2_AfterUpdate() Me!コンボ4.Requery End Sub Private Sub コンボ4_AfterUpdate() Me!コンボ6.Requery End Sub ぜひよろしくお願いします。

  • アクセスフォームについて教えて下さい。

    アクセスフォームについて教えて下さい。 テーブル T_設備 設備管理No. 状態ID(フィールドプロパティ→コンボボックス) 分類ID(フィールドプロパティ→コンボボックス) 設備名 (その他項目あり) T_状態 ID  001  稼動中 002  停止中 T_分類 ID 001  専用機 002  マシニング T_設備、T_状態、T_分類はリレーションシップを組んでいます。 クエリ T_設備を元にクエリを作成 Q_設備 (全データを表示) 稼動中の設備を抽出 Q_稼働設備 停止中の設備を抽出 Q_停止設備 フォーム Q_稼働設備を元にフォームを作成 F_稼働設備一覧(表形式) Q_稼働設備を元にフォームを作成 F_稼働詳細(単票形式) 表形式のフォーム(F_稼働設備一覧)にコマンドボタン(コマンド1)を作成、 OPENFORMメソッドでクリックした行のデータを表示させるようにしました。 (単票形式のF_稼働詳細でデータの詳細を確認したい) Private Sub コマンド1_Click() DoCmd.OpenForm "F_設備詳細" Forms!F_設備詳細!設備管理No. = Forms!F_稼働設備一覧!設備管理No. End Sub しかし、コンボボックスの内容を変更(稼動中から停止中へ)し、フォームを閉じ、 再度F_稼働設備一覧を開くと、データがQ_停止設備へ移動しておらず、 コンボボックスも稼動中に戻ってしまっています。 コマンド1ボタンからではなく、直接F_設備詳細を開き、コンボボックスの停止中を 選択した場合は、データはQ_停止設備へ移動します。 OpenFormメソッドの記入に問題があるのでしょうか? 色々と試しましたが、解決できませんでした。 よろしくお願いいたします。   

専門家に質問してみよう