私は周りを検索しましたが、これはMS Accessの制限のようです。そのため、このパズルに対して他の人がどのような創造的な解決策を見つけたのか疑問に思います。
連続したフォームがあり、フィールドをその行に固有のオプションのコンボボックスにしたい場合、Accessは配信に失敗します。コンボボックスの行ソースは、フォームの先頭で1回だけ照会されるため、フォームの残りの部分で間違ったオプションが表示されます。
もちろん、私たち全員が試みる次のステップは、onCurrentイベントを使用してコンボボックスを再クエリすることです。これにより、実際にはオプションが特定の行に制限されます。ただし、この時点で、Accessは混乱し、すべての行に対してコンボボックスのすべてallを要求します。その結果、多くの場合、消えて再表示されます。現在のレコードの行ソースに有効なオプションを選択したかどうかに応じて、他の行のオプション。
私が見つけた唯一の解決策は、利用可能なすべてのオプションを常にリストすることです。そこに創造的な答えはありますか?
編集また、コンボボックスの理由は、クエリをルックアップテーブルとして使用するためであり、人間が読める形式が表示されている間、実際の値を非表示にして保存する必要があることに注意してください。コンボボックスの行ソースの複数の列。したがって、制限をリストに変更しても、現在の行のソースクエリにないIDには、一致する人間が読める部分がないため、役に立ちません。
この特定のケースでは、連続フォームは非常に理にかなっているので、間違った解決策だと言わないでください。私は創造的な答えを求めています。
私もアクセスが嫌いですが、配られたカードで遊ぶ必要があります。この例のように、一般的に見られるような複雑さに遭遇するまで、連続形式はAccessのすばらしい機能です。
この状況に直面したときに私がすることは次のとおりです(そして私は以前に同様の回避策を実装しました):
UNBOUNDコンボボックスをフォームに配置します。次に、編集するフィールドのBOUNDtextBoxを配置します。
コンボボックスがtextBoxの後ろに隠れている(見えないのではなく、隠されているだけ)ことを確認してください。
OnCurrentイベントで、listBoxに必要なデータを入力します。先に進んで、それも「リストに制限」してください。
TextBoxのOnEnterまたはOnClickイベントで、コンボボックスにフォーカスを与えます。これにより、コンボボックスが最前線になります。フォーカスがコンボボックスを離れると、もう一度非表示になります。
コンボボックスのAfterUpdateイベントで、テキストボックスの値をコンボボックスの値と同じに設定します。
状況によっては、他にも解決すべき詳細がある場合がありますが、複雑さを増すことなく、多かれ少なかれ目標を達成できるはずです。
連続形式を使用する..間違いなく。実際、連続フォーム上に構築された優れた直感的なユーザーインターフェイスを使用して、アプリケーション全体を構築できます。トーストを聴かないでください!
利用可能なすべてのオプションを一覧表示するソリューションは正しいものです。実際、他にクリーンな解決策はありません。しかし、アクセスがおかしくなると言うとき、あなたは間違っています。連続フォームでは、各行を詳細セクションのインスタンスとして表示できます。コンボボックスは、詳細セクションのすべてのインスタンスに共通のプロパティです。このプロパティはすべてのインスタンスに対して更新できますが、特定の1つのインスタンスに対して設定することはできません。これが、Accessがすべてのレコードのコンボボックスに同じデータを表示する必要がある理由です。
このコンボボックスでレコード固有の値のみを受け入れる必要がある場合は、beforeUpdateイベントを使用して制御プロシージャを追加してください。新しい値を受け入れることができない場合は、データの更新をキャンセルして、フィールドの前の値に戻すことができます。
リンクされたデータ(コントロールに格納されているデータ)が非表示になっている場合、limitToListプロパティを「No」に設定することはできません。これは論理的です。リンクされたフィールド(表示されていない)が空のままの場合、マシンはどのようにして新しいデータ行の入力を受け入れることができますか?
ギリガンよりも簡単な方法があります。大変な作業のように思えますが、実際にはそうではありません。私のソリューションでは、連続フォームをサブフォームデータシートとして使用する必要があります。私のサブフォームには、EquipmentとManufacturerと呼ばれる2つのルックアップコンボボックスがあります。どちらも、データソースに長整数キーを保持するだけです。製造業者は、機器で選択されたものでフィルタリングする必要があります。 Manufacturer.RowSourceをフィルタリングするのは、Manufacturer_GotFocusイベントだけです。
プライベートサブManufacturer_GotFocus()
If Nz(Me.Equipment, 0) > 0 Then
Me.Manufacturer.RowSource = GetMfrSQL() '- gets filtered query based on Equipment
Else
Me.Manufacturer.RowSource = "SELECT MfgrID, MfgrName FROM tblManufacturers ORDER BY MfgrName"
End If
エンドサブ
Manufacturer_LostFocusで、Manufacturer.RowSourceをすべてのManufacturersにもリセットしました。サブフォームを最初にクリックすると、実際にはフィールドを更新していなくても、製造元を含むすべてのコントロールに対してGotFocusイベントが発生するため、これを行う必要があります。
プライベートサブManufacturer_LostFocus()
Me.Manufacturer.RowSource = "SELECT MfgrID, MfgrName FROM tblManufacturers ORDER BY MfgrName"
エンドサブ
製造業者のEnterイベントで、機器にフォーカスが設定されていない場合は、機器が選択されているかどうかを確認する必要があります。
プライベートサブManufacturer_Enter()
If Nz(Me.EquipmentID, 0) = 0 Then
'-- Must select Equipment first, before selecting Manufacturer
Me.Equipment.SetFocus
End If
エンドサブ
また、Form_CurrentイベントでManufacturerコンボボックスを再クエリする必要があり(つまり、Me.Manufacturer.Requery)、このサブフォームのCycleプロパティを「CurrentRecord」に設定する必要があります。
簡単そうに見えますが、まだ終わっていません。また、ユーザーがManufacturerコンボボックスに移動したが、選択を行わずに親フォームのどこかをクリックした場合に備えて、親フォームのSubForm_ExitイベントでManufacturer.RowSourceをすべてのManufacturersにリセットする必要があります。コードサンプル(親形式):
Private Sub sFrmEquip_Exit(整数としてキャンセル)
Me.sFrmEquip.Controls("Manufacturer").RowSource = "SELECT MfgrID, MfgrName FROM tblManufacturers ORDER BY MfgrName"
エンドサブ
まだきれいではないものが1つあります。 [製造元]をクリックしてデータシートグリッドに複数の行がある場合、現在の行の製造元を変更している間、他の行の[製造元]フィールドは空白になります(コンボボックスの下のデータはそのままです)。このフィールドから移動すると、他のメーカーフィールドのテキストが再び表示されます。
コンボボックスの値を編集不可能なテキストフィールドにしてから、ポップアップ/モーダルウィンドウを起動してその値を編集することもできます。ただし、そうしていると、これらのウィンドウの1つでレコード全体を編集したくなるかもしれません。
これはうまくいくようです。 CBOsfrmTouchpoint8は、ドロップダウンの正方形に短縮されたコンボボックスです。 CBOsfrmTouchpoint14は、残りのスペースを構成するテキストボックスです。絶対とは絶対言うな:
Private Sub CBOsfrmTouchpoint8_Enter()
If Me.CBOsfrmTouchpoint8.Tag = "Yes" Then
CBOsfrmTouchpoint14.SetFocus
Me.CBOsfrmTouchpoint8.Tag = "No"
Exit Sub
End If
Me.CBOsfrmTouchpoint8.Tag = "No"
Me.CBOsfrmTouchpoint8.RowSource = "XXX"
Me.CBOsfrmTouchpoint8.Requery
Me.CBOsfrmTouchpoint8.SetFocus
End Sub
Private Sub CBOsfrmTouchpoint8_GotFocus()
Me.CBOsfrmTouchpoint14.Width = 0
Me.CBOsfrmTouchpoint8.Width = 3420
Me.CBOsfrmTouchpoint8.Left = 8580
Me.CBOsfrmTouchpoint8.Dropdown
End Sub
Private Sub CBOsfrmTouchpoint8_LostFocus()
Me.CBOsfrmTouchpoint8.RowSource = "XXX"
Me.CBOsfrmTouchpoint8.Requery
End Sub
Private Sub CBOsfrmTouchpoint8_Exit(Cancel As Integer)
Me.CBOsfrmTouchpoint14.Width = 3180
Me.CBOsfrmTouchpoint8.Width = 240
Me.CBOsfrmTouchpoint8.Left = 11760
Me.CBOsfrmTouchpoint8.Tag = "Yes"
End Sub
Accessの連続フォームはまったく非難されるべきではないと思いますが、データの編集では避けるべきだと確信しています。これらはリストに最適であり、単なるリストボックスよりも大幅に多くのフォーマット機能を提供します(もちろん、複数選択は許可されていませんが、操作もはるかに簡単です)。
編集用のレコードへのナビゲーションに連続フォームを使用する場合は、編集用の詳細データを表示するサブフォームを使用し、リンクフィールドにサブフォームのPK値を使用します。これは、連続フォームの背後にあるテーブルのPKにリンクされた、ヘッダーまたはフッターに詳細サブフォームを配置する連続フォームを使用して実行できます。
または、連続フォームを使用して子データを親フォームに表示している場合は、次のように、詳細サブフォームを連続サブフォームのPKへの参照にリンクできます。
[MySubForm].[Form]!MyID
これがリンクマスタープロパティになり、MyIDがリンク子プロパティになります。
私達はまた私達のアプリケーションでこれにたくさん遭遇します。良い解決策であることがわかったのは、コンボボックスのすべての行を表示することだけです。次に、ユーザーが特定の行にコンポボックスを入力したらすぐに、行ソースを調整します(その行のフィルターを使用)。コンボボックスがフォーカスを失った場合、すべてを表示するように行ソースをリセットできます。
より良い...
コンボボックスのコントロールソースを、コンボボックスの値が格納されるクエリの列に設定します。
OnEnter
イベントを使用してコンボボックスにデータを入力します。固定のrowsource
は使用しないでください。
[リストに制限]オプションをオフにし、更新前に検証を行って、ユーザーが入力した内容が、提示したリストの内容と一致することを確認するとどうなりますか?
私にとって最良の方法と最も簡単な方法は、すべてのバインドされたフィールドに加えて、yeas/noフィールドである追加のフィールドを持つ一時テーブルを作成することだと思います。
次に、このテーブルをの連続のデータソースとして使用します。 onLoadを使用して、一時テーブルに必要なデータを入力できます。
その後、選択肢をループするのは簡単だと思います。一時テーブルからyeas/noフィールドを読み取るための小さなループだけです。
これがお役に立てば幸いです
私はちょうど同じようなことをしました。私の解決策は、クエリにバインドされた固定行ソースを使用することでした。クエリのWHERE
句は、フォームのコントロール、つまりClient=Forms!frmMain!ClientTextBox
を参照します。これだけで、コンボボックスに最初の行のデータが入力されます。その場合の秘訣は、 'On Enter
'イベントを設定することです。 ComboBox1.Requery
、これはそのコンボボックスのみを再クエリし、そのレコード行に関連するデータのみをドラッグします。
それがあなたにも役立つことを願っています!