3

私が構築しているデータベースで取るべきアプローチに関する一般的な質問。DB ビジネス ユーザーが条件を入力したり、ラジオ ボタンなどで検索を制限したり、選択内容に基づいてクエリを実行したりできるフォームをいくつか用意する予定です。

1 つまたは 2 つのフィルターがある単純なクエリの場合、クエリ デザイン ビューでデータ フィールドの条件をそれぞれのフォーム要素に関連付けるのは簡単に思えますが、ネストされたものを扱う場合、このアプローチは失敗します (また、読み取り/編集が非常に難しいようです)。 if ステートメント (例: If A の場合 x、if B の場合 y、if C の場合 z、Else q)。

onClick イベントまたは何らかのフォームベースのトリガーの後に実行される VBA で作成された、クエリ名と対応する SQL 文字列を格納する DB に別のテーブルを作成することを説明した記事に出くわしました。クエリ条件を決定するロジックはすべて VBA にあり、コードが実行されると、システムにはクリーンな SQL ステートメントが残されます。これは前述のテーブルに格納され、クエリの実行に使用されます。フォームがアクセス/変更され、クエリが要求されるたびに、テーブル内の SQL 文字列が上書きされると思います。

これは私が取り組んだ最初の本格的な DB であるため、取るべきアプローチに関するガイダンスを探しています。今説明したことは正しいですか、それとも状況を処理するためのかなり標準的/一般的な方法ですか? 大きな懸念事項はありますか?すぐに思い浮かぶのは、2 人の DB ユーザーが異なる条件で同じクエリを同時に実行しようとするとどうなるかということです。私のユーザーベースは小さいことに注意してください.おそらく5人のユーザーは、アドホックレポートなどのために、DBにアクセスするだけです.

前もって感謝します!

編集: これは、私が参照していたフォーラムの投稿です: 別のテーブルの SQL 文字列

編集 2: 一般的な例として、私の DB に次のようなテーブルがあるとします。

ID......Sale_Date......カテゴリ


1....... 2013 年 1 月 1 日.................Foo
2....... 2013 年 1 月 3 日........バー
3..... .. 2013 年 1 月 1 日.................バー
4........2013 年 1 月 7 日........バー

今私のフォームでは、ユーザーが日付範囲を指定できるテキスト ボックスがあり、これはクエリで次のようにフィルター処理されます。

[Forms]![myFrm]![FromDate] と [Forms]![myFrm]![ToDate] の間

これは問題なく動作します。

カテゴリに関しては、ユーザーが包含/除外のカテゴリを指定できるチェックボックスまたはその他のフォーム要素が必要です。ここで問題が発生しました。私は試した:

IIf([Forms]![myFrm]![Cat]=1,([tbl_data].[Category]) In ("Foo","Bar"),IIf([Forms]![myFrm]![Cat]= 2,"フー","バー"))

...Cat=1 は 'All' を表し、2 と 3 はそれぞれ Foo と Bar を表します。Access は、クエリが複雑すぎるというエラーを表示しますが、ネストされた if を削除すると (したがって、両方のカテゴリを検索するオプションを無視します)、機能します。

さて、明らかにこれは非常に単純化された例ですが、DB が成長し、より多くの定型クエリが組み込まれるにつれて、フォーム駆動型クエリを処理する方法について考えるようになりました.VBA での考えは、コードが実行され、フォームデータを作成し、次のように SQL を構築します。

SELECT...
FROM...
WHERE IN("Foo", "Bar")

うまくいけば、これが物事を少し明確にするのに役立ちます。私の無知を許してください...私は、私が進むにつれて、まだ多くのことを学んでいます。ありがとう。

4

4 に答える 4

3

あなたの質問のこの点について...

「2 人の DB ユーザーが同じクエリを異なる基準で同時に実行しようとするとどうなりますか?」

マルチユーザー Access アプリケーションでは、db をフロントエンドとバックエンドの db ファイルに分割する必要があります。BE データベースには、テーブル、インデックス、および関係が含まれている必要があります。FE データベースには、クエリ、フォーム、レポートなど (基本的に、テーブル以外のアプリケーションに必要なものすべて) と BE テーブルへのリンクが含まれている必要があります。

アプリケーションのすべてのユーザーがアクセスできるネットワーク共有に BE db ファイルを配置します。各ユーザーは、FE データベースの独自のコピーを受け取る必要があります。

その場合、各ユーザーは、他のユーザーのクエリを踏みにじることなく、独自のカスタム アドホック クエリを作成して実行できます。

クエリ条件または SQL ステートメント全体をどこかに保存する必要がある場合は、それらを FE のローカル テーブルに保存するか、共通の BE テーブルに保存しますが、フィールド (おそらくユーザー ID) を含めて、各ユーザーのクエリを個別に保存できるようにします。 .

FE ユーザーごとにローカルに保存することにした場合、新しい FE バージョンを展開する必要があるときに、保存された設定が破棄される危険性があることに注意してください。その場合、より良いアプローチは、カスタム設定を保存できる補助データベース ファイルを各ユーザーに提供することです。そして、新しい FE バージョンをデプロイするときに、それらの設定を保持できます。

あなたの質問の「全体像」を把握するのは難しいと思いました。ただし、分割アプリケーションのコンテキストで検討する必要があると思います。

一般的な「検索フォーム」の提案については、Allen Browne の詳細な例から再利用できるものを参照してください:検索条件


簡単なアプローチを使用できるかもしれないと思います。

検索結果用に別のフォームを作成します。表示するすべてのフィールドを含むクエリに基づいて、そのフォームを作成します。そのクエリに句が必要な場合はWHERE、すべての検索バリエーションに適用する必要がある条件のみに制限します...おそらくActive = True. すべての検索に適用される条件を特定できない場合は、WHERE句を含めないでください。

次に、検索フォームで、[今すぐ検索] コマンド ボタンのクリック イベントからユーザーの検索条件を評価します。WHERE単語なしで文字列を作成し、それを のWhereConditionオプションWHEREとして使用します。DoCmd.OpenForm

If Not IsNull(Me.txtStartDate) Then
    strWhere = strWhere = " AND date_field >=" & _
        Format(Me.txtStartDate, "\#yyyy-m-d\#")
End If
If Not IsNull(Me.txtCategory) Then
    strWhere = strWhere = " AND category =" & Me.txtCategory
End If
If Len(strWhere) > 0 Then
    strWhere = Mid(strWhere, 6) ' discard leading " AND "
    DoCmd.OpenForm "frmSearchResults", WhereCondition:=strWhere
Else
    MsgBox "nothing to search for"
End If

検索基準の 1 つが一連の選択肢からの 1 つ以上の項目になる場合は、それらを複数選択リスト ボックスとして提示し、リスト ボックスの.ItemsSelectedプロパティをループして などの文字列を作成しますsome_field IN ("a", "b", "z")。その部分に問題がある場合は、新しい質問を投稿してください。解決することができます.

前にリンクした Allen Browne の例を調べてください。私が覚えているように、彼は同様のテクニックを使用していました。

于 2013-04-04T16:58:06.007 に答える
0

こんにちは、リンクテーブルを使用してデータをユーザーから分離できるので、複数の人が同時にデータベースを使用したときに何が起こるかを心配する必要はありません。

研究に関しては、私はそのようなものを使用しています。

Set MyDatabase = CurrentDb
strQuote = Chr$(34)
Set MyQuery = MyDatabase.QueryDefs("YourQuery")
I = 0

SQL_String = "SELECT T_Project.YourID, T_Project.Project_Title " & _
             "FROM (T_Project LEFT JOIN T_Groupe ON T_Project.Code_Group = T_Groupe.Code_Group) LEFT JOIN T__Contact ON T_Project.Code_Employee = T__Contact.Code_Contact "

If Not IsNull(Me.R_YourID) Then
    MyCriteria(I, 0) = " YourID "
    MyCriteria(I, 1) = Me.R_YourID
    MyCriteria(I, 2) = "="
    I = I + 1
End If

If Not IsNull(Me.R_Project_Title) Then
    MyCriteria(I, 0) = " Project_Title "
    MyCriteria(I, 1) = " " & strQuote & "*" & Me.R_Project_Title & "*" & strQuote
    MyCriteria(I, 2) = "like"
    I = I + 1
End If

If I <> 0 Then
    SQL_String = SQL_String & " Where " & MyCriteria(0, 0) & MyCriteria(0, 2) & MyCriteria(0, 1)
    j = 1
    Do While j <> I
        SQL_String = SQL_String & " and " & MyCriteria(j, 0) & MyCriteria(j, 2) & MyCriteria(j, 1)
        j = j + 1
    Loop
End If

MyQuery.SQL = SQL_String & " ORDER BY T_Project.YourID " 

Refresh
Forms![Menu_Principal]![List_Project].Requery

これがあなたを助けることを願っています

于 2013-04-04T17:08:24.147 に答える
0

これに対するマイクロソフトの公式回答があります: http://support.microsoft.com/kb/304302

基本的には、クエリの最初のフィルター条件の直前に「where」という単語だけが必要であることを認識することにかかっています。後続のフィルター条件が使用されている場合、それらはすべて「and」という単語で始まります。そこから、上記の MS KB 記事に従って、VBA を使用して SQL クエリ文字列を動的に構築できます。

于 2013-08-07T03:32:48.010 に答える