- ベストアンサー
Access 帳票フォームに得意先のコンボボックスを配置し、入力の手助けをしたい
- Accessの帳票フォームに得意先のコンボボックスを配置し、入力の手助けをしたいと思います。一部を入力したらリストが絞り込まれるようなものにしたいです。
- 単票フォームに同様の機能があり、非連結のテキストボックスに入力をすると、コンボボックスに絞り込まれたリストが自動的に表示されるようになっています。
- しかし、帳票フォームにおいて同様の機能を実現するのは難しいことが分かっており、Access2003で可能かどうか不明です。可能であれば実現したいですが、無理であれば諦めます。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
【要旨】 一部の特殊パターンを除き一般的には無理ですが、代替策があります。 【詳細】 > 帳票フォームでこのようなことは可能でしょうか? コンボボックスの値が、値集合ソースに指定したテーブル/クエリに存在しない 場合、その値自体が表示されたと思いますので、「コンボボックスに格納された 値がテキスト」(で、『入力チェック』プロパティが「いいえ」)なのであれば、 ご質問の動作も可能です。 ですが、既にそうされていると思いますが、コンボボックスの選択肢となるデータ を別のテーブルに分割(→正規化)している場合は、コンボボックスに格納される のはID(数値)の類になりますので、「検索条件に指定したものに合致しない レコードの当該フィールドの表示が一時的に変になっても構わない」という ことでもない限り、無理ということになります。 ただ、考え方を少し変えて、【検索条件に合致したものだけ、コンボボックスの リストに表示】ではなく、【検索条件に合致したものをコンボボックスのリストの 前半に、合致しなかったものを同じく後半に、それぞれまとめて表示】とすれば、 条件に合致しなかったレコードのデータが非表示になることなく、『入力支援』 という目的を果たすことができるかと思います。 また、別の方法としては、別途ポップアップフォームを作成して、「検索条件 を指定する非連結テキストボックス」と「合致したデータを表示する非連結 リストボックス」(と取消用の「閉じる」コマンドボタン)を用意しておき、リスト ボックスのダブルクリックで呼出元のフォームにリストボックスの値を渡す (そして自動で閉じる)、というものもあり得るかと思います。 (ポップアップフォームのOpenイベントで、「Dim objFrm As Form」と変数を 宣言した上で、「Set objFrm = Screen.ActiveForm」としてやれば、 呼出元で「Me!得意先」とするのと同様の操作を、「objFrm!得意先」と いった式を使って行えます) ※呼出元からのポップアップフォームの呼び出しには、コマンドボタンを新設 してもいいですし、運用上問題ないようなら(→入力担当者次第)、当該 コンボボックスのダブルクリックなどで開くようにしてもいいかと思います。 (当該コンボボックスからの起動なら、フォームではなくコントロールを参照 する変数を宣言して、Screen.ActiveControlを使用すると更に楽です) 後者の方が簡単(なはず)ですが、そちらはご自身で組めるのではないかと 推測して、以下では前者の手段で、非連結テキストボックスの名前を 『条件欄』とした場合のサンプルコードを提示してみます: ※お勧めの手段は、あくまで後者(ポップアップフォーム)です。 Private Sub 条件欄_AfterUpdate() On Error GoTo エラー処理 Dim dbs As DAO.Database, DRS As DAO.Recordset Dim sVal As String, sRS As String, iTemp As Integer, sOrd As String '※『得意先』コンボボックスの既定の『値集合ソース』を定数として宣言 ' (『得意先』コンボボックスの連結フィールドが『得意先ID』という想定) Const BaseRS As String = "Select 得意先名, 得意先ID, 検索カナ From Q:得意先" '※『Q:得意先』クエリ(?)に存在しない『得意先ID』を定数として宣言 ' (→条件合致なしだった場合の、データの上書き回避に使用) Const cDefID As Integer = -1 '『得意先ID』の最小値を「0」と想定 '◆『条件欄』に入力された検索条件に合わせて、コンボボックスの ' 『値集合ソース』の並べ替えを切替 sVal = Nz(条件欄, "") Select Case True '空白の場合は『検索カナ』だけで並べ替え Case sVal = "" sOrd = "検索カナ;" '※『得意先名』で並べ替える場合は以下を有効にします: ' (言うまでもないとは思いましたが(汗)、次のCaseとの ' 対比させる意味で、明示することにしました) 'sOrd = "得意先名;" '検索条件が「*」つきの場合は、それをそのまま使用 '(「曖昧検索/前方一致/後方一致/部分一致」の任意指定に対応) Case InStr(1, sVal, "*", vbBinaryCompare) sOrd = "(Nz(検索カナ) Like '" & sVal & "'), 検索カナ;" '※合致分の中での並べ替えを『得意先名』にする場合は以下: ' (この時も第1条件は「Nz(検索カナ)~」のままの点に注意) 'sOrd = "(Nz(検索カナ) Like '" & sVal & "'), 得意先名;" '検索条件が「*」を含まない場合は曖昧検索用に「*」を追加 Case Else sVal = "*" & sVal & "*" sOrd = "(Nz(検索カナ) Like '" & sVal & "'), 検索カナ;" '※既定動作を「先頭一致」にしたい場合は以下: 'sOrd = "(Nz(検索カナ) Like '" & sVal & "*'), 検索カナ;" End Select sRS = BaseRS & vbCrLf & "Order by " & sOrd '◆検索条件に合致するものがあれば、その先頭の値を取得 Set dbs = CurrentDb Set DRS = dbs.OpenRecordset(sRS) iTemp = cDefID '初期化 With DRS '抽出条件なし(並べ替え条件のみ)なので「レコードなし」はない 'とは思いますが、一応念のためにEOFを確認 If .EOF = False Then .MoveFirst '先頭レコードが条件に合致していたら、その得意先IDを変数に記録 If (!検索カナ Like sVal) Then iTemp = Nz(!得意先ID, cDefID) End If End If End With '◆合致ありの場合はその値を代入、なければ現在の値のままで、 ' ドロップダウンリストを表示 With 得意先 .RowSource = sRS '条件に合致する得意先があった場合は、記録した得意先IDを代入 '(代入不要なら、以下の行は削除でOk) If (iTemp <> cDefID) Then .Value = iTemp 'ドロップダウンリストを表示 '(フォーカスを持たせないとDropdownはエラーになります) .SetFocus .Dropdown End With 終了処理: '念のため、明示的にメモリを解放 If Not (DRS Is Nothing) Then DRS.Close Set DRS = Nothing Set dbs = Nothing '全レコードの非連結テキストボックスで同じ値が表示されるのを '避けたい場合は、以下の1行を有効化させます: '条件欄=Null Exit Sub エラー処理: MsgBox Err.Number & ":" & Err.Description Resume 終了処理 End Sub ・・・長くなりましたが(汗)、以上です。 【全くの余談(汗)】 かなり昔に回答したものですが、末尾の『「.」は無用』というのは 間違いでしたので、ここでお詫びの上、訂正させて戴きます。 (当時「RecordsetClone」プロパティと「Recordset」オブジェクトは 知っていましたが、後者に「Clone」メソッドがあることを知らなかった ため、「無用」としてしまいました) 大変失礼致しました(汗) http://okwave.jp/qa/q5509319.html
その他の回答 (2)
- 30246kiku
- ベストアンサー率73% (370/504)
#2です 参照先をみて悩まれているようでしたら、以下でわかるでしょうか。 理解されていましたら、余計なお世話という事でスルーしてください。 帳票フォームの「得意先ID」を入力する部分がコンボボックスになっている。 つまり、コントロールソースが 得意先ID コンボボックスには、得意先名が表示されている、とします。 下側に配置するコンボボックス名を「コンボ後」と仮定します。 値集合ソースを SELECT 得意先ID, 得意先名 FROM Q得意先; 列数:2 連結列:1 列幅:0cm;3cm (得意先ID は表示しない様に) 入力チェック:はい コントロールソースは 得意先ID 検索文字列を入力する非連結テキストボックス名を「txt検索」と仮定します。 上記で出来上がった「コンボ後」をコピーし「コンボ前」とします。 「コンボ前」のプロパティを変更していきます。 値集合ソースを以下に変更 SELECT 得意先ID, 得意先名 FROM Q得意先 WHERE IIF(IsNull([txt検索]),True,検索カナ LIKE '*' & [txt検索] & '*'); 背景スタイルを透明にします。 「コンボ後」のタブストップを「いいえ」にした後、 「コンボ後」「コンボ前」を重ねます。(「コンボ前」が上(前面)になるように) そして、以下のイベントで処理します。 Private Sub txt検索_AfterUpdate() Me.コンボ前.SetFocus End Sub Private Sub コンボ前_Enter() Me.コンボ前.Requery End Sub Private Sub コンボ前_GotFocus() Me.コンボ前.Dropdown End Sub なぜ、重ねるか 「コンボ前」は絞り込まれた内容になります。 そこに、連結した「得意先ID」がなければ何も表示されません。 ですが、 背景スタイルが透明になっているので、透けて「コンボ後」の表示が見えます。 「得意先ID」があれば、同じ文字列を表示することになるので、 重ね方がズレていなければおかしくはなりません。 「コンボ前」は、フォーカスを得ると透けなくなるようです。 「txt検索」が帳票フォームのどの位置に配置されているか、ですが、 ・ヘッダ/フッタ部分であれば上記で終了です。 コンボボックスに並べて、詳細に配置しているのなら、 処理しているレコード(行)以外での表示は邪魔になると思います。 邪魔と感じなければ上記で終了です。 以下は、「txt検索」を隠す方法になります。 ただ、レコードを特定できるもの(オートナンバ等)がなければできません。 この帳票で表示しているレコードにオートナンバ「an」が存在すると仮定します。 ヘッダ部に非表示のテキストボックス「txt0」を配置します。 詳細部分に「txt検索」より、ひと回り大きいテキストボックス「txt1」を配置します。 「txt1」のプロパティを変更していきます。 背景スタイル:透明 境界線スタイル:透明 フォント名:Webdings フォントサイズ:「txt検索」の倍以上 前景色:詳細の背景と同じ色 コントロールソース: =IIf(IsNull([an]) And IsNull([txt0]),"",IIf([txt0]=[an],"","gggg")) この「txt1」を「txt検索」に重ねて、「txt1」が上(前面)になるようにします。 上記でのイベントに加え、以下のイベントを追記します。 Private Sub Form_Current() Me.txt0 = Me.an ' Me.txt検索 = Null End Sub Private Sub txt1_Enter() Me.txt検索.SetFocus End Sub 現在選ばれているレコードを特定できる「an」を「txt0」に設定します。 「txt1」では、選ばれているレコードであれば何も表示しません。 背景スタイルを透明にしているので「txt検索」が透けて見えるようになります。 選ばれているレコードでなければ、文字 "gggg" を表示します。 フォント「Webdings」の時の "g" は塗潰し文字(■の親戚?)になります。 それを表示する時の色が、詳細の色と同じであれば「txt検索」を隠せます。 やってみて隠せなかったら、フォントのサイズ、"g" の個数を変更していきます。 「txt1」にフォーカスが移ろうとした時、透けて「txt検索」が見えているはずなので 「txt検索」を入力/変更できるように「txt検索」へフォーカスを移動します。 フォーカスを得た「txt検索」は、下側に配置したにもかかわらず最前面に出てきます。 フォーカスを失うと、下側に戻っていきます。 レコードを移動した時に「txt検索」をクリアしたかったら、Form_Current で。 ただ、上記のままでは新規登録の際、表示ズレが発生します。 新規行に入力し始めると、「txt検索」が見えるのは、さらなる新規行に。 編集中の新規行では、「txt検索」は見えなくなります。 見えなくなりますが、あるべきところをクリックすると「txt検索」がでてきます。 「txt検索」は、フォーカスを失うと、また消えてしまいます。 この動きは嫌だと思います。 上記オートナンバを使った時には、以下の処理を入れることで改善されます。 Private Sub Form_Timer() Me.TimerInterval = 0 Me.txt0 = Me.an End Sub Private Sub Form_BeforeInsert(Cancel As Integer) Me.TimerInterval = 10 End Sub Private Sub Form_Undo(Cancel As Integer) If (Me.NewRecord) Then Me.txt0 = Null End Sub この所は、レコードを特定するものに何が使えるかで変わってくると思います。 それによっては、「txt検索」は隠さなくて良いや・・・とか、 ヘッダ/フッタ側に配置替えってことも・・・ いろいろと試してみてください。
お礼
回答ありがとうございます。 やってみましたが、2行目になるとやはり動きが変になってしまいました。 帳票フォームはむずかしいですね・・・。 今回は他の仕様でフォームを作ろうと思います(時間がないため) 作成が終わったら、もう一度帳票にチャレンジしようと思います。 そのときの参考にさせていただきます。 ありがとうございました。
- 30246kiku
- ベストアンサー率73% (370/504)
コンボボックスの一覧を入力時のみ制限する方法~帳票形式編~ http://www.f3.dion.ne.jp/~element/msaccess/AcTipsFrmHowToLimitComboListWhenInputOnly.html 上記を参考にしてください。 コンボボックスにコンボボックスを重ねる方法です。
お礼
回答ありがとうございます。 検索条件によりリストの前半にもってくるという考え方はスゴイと思いました(自分はまったく考えなかったため) しかし、今回はお勧めのあったポップ画面の仕様にしようと思います(時間がないため) それが終わったら、帳票仕様に再度チャレンジしようと思います。そのときはこの検索条件で並び替え仕様にしたいと思います。ありがとうございました。