0

次のコードがあります。

Public Function BuildSQL(stQueryName As String, stWhereClause As String) As String
    On Error GoTo Err_BuildSQL

    Dim SQLcmd  As String
    Dim intPos  As Integer
    Dim db      As Database
    Dim qryOrig As QueryDef

    Set db = CurrentDb()
    Set qryOrig = db.QueryDefs(stQueryName)

    SQLcmd = qryOrig.SQL

    intPos = InStr(SQLcmd, "WHERE")
    If intPos > 0 Then
        SQLcmd = Left(SQLcmd, intPos - 1)
    End If

    intPos = InStr(SQLcmd, ";")
    If intPos > 0 Then
        SQLcmd = Left(SQLcmd, intPos - 1)
    End If

    If Not (stWhereClause = "") Then
        SQLcmd = Trim(SQLcmd) & " WHERE " & stWhereClause & ";"
    Else
        SQLcmd = Trim(SQLcmd) & ";"
    End If

    BuildSQL = SQLcmd

Exit_BuildSQL:
    Set qryOrig = Nothing
    Set db = Nothing
    Exit Function

Err_BuildSQL:
    MsgBox Err.Description
    Resume Exit_BuildSQL

End Function

Private Sub SandBox_Click()
    On Error GoTo Err_SandBox_Click

    Dim db         As Database
    Dim rs         As Recordset
    Dim stSQL      As String
    Dim stFrmName  As String
    Dim stQryName  As String
    Dim stSQLWhere As String
    Dim stIDList   As String

    stFrmName = "Libri"
    stQryName = "Libri_All_Query"

    'Define WHERE clause
    stSQLWhere = ""
    If Not (IsNull([Forms]![Libreria]![Editore]) Or [Forms]![Libreria]![Editore] = "") Then
        stSQLWhere = stSQLWhere & "Libri_Editori.Editore = '" & [Forms]![Libreria]![Editore] & "'"
    End If
    If Not (IsNull([Forms]![Libreria]![CognomeAutore]) Or [Forms]![Libreria]![CognomeAutore] = "") Then
        If (stSQLWhere = "") Then
            stSQLWhere = stSQLWhere & "Autori.Cognome = '" & [Forms]![Libreria]![CognomeAutore] & "'"
        Else
            stSQLWhere = stSQLWhere & " AND Autori.Cognome = '" & [Forms]![Libreria]![CognomeAutore] & "'"
        End If
    End If

    'Here several more fields of the search form will be checked and added

    stSQL = BuildSQL(stQryName, stSQLWhere)

    '*** Code in question!
    Set db = CurrentDb()
    Set rs = db.OpenRecordset(stSQL)
    If Not (rs.EOF And rs.BOF) Then
        stIDList = "("
        rs.MoveFirst
        Do Until rs.EOF = True
            If (stIDList = "(") Then
                stIDList = stIDList & rs.Fields(0)
            Else
                stIDList = stIDList & ", " & rs.Fields(0)
            End If
            rs.MoveNext
        Loop
        stIDList = stIDList & ")"
    Else
        Err.Description = "Errore! Recordset vuoto."
        Resume Err_SandBox_Click
    End If
    DoCmd.OpenForm stFrmName, , , , acFormReadOnly
    Access.Forms(stFrmName).RecordSource = "SELECT * FROM Libri WHERE Libri.ID IN " & stIDList
    '**** End code in question

Exit_SandBox_Click:
    Set db = Nothing
    Set rs = Nothing
    Exit Sub

Err_SandBox_Click:
    MsgBox Err.Description
    Resume Exit_SandBox_Click
End Sub

このコードは私が望むように機能しますが、各テーブルに少数のレコードしかないテスト DB でも「見た目」が遅くなります。コメント間のループで時間が費やされていると思います(これが本当かどうかを確認するにはどうすればよいですか?)。私がやっているように、レコードセットを作成してループするよりも、フォームをフィルタリングするためのより基本的で明白で効率的な方法はありますか?
フォーム「Libri」は、Book のすべてのデータを表示できる複数のサブフォームを備えた大きなフォームです。
クエリ「Libri_All_Query」は、DB 内のほぼすべてのテーブルの結合であり、表示されているコードは、可能なすべての検索フィールドを追加する予定のフォームから実行されます。

4

1 に答える 1

1

フォームにはフィルター プロパティがあります。

stWhereClause = "Title Like '" & Me.txtSearch & "*'"
Me.Filter = stWhereClause 
Me.FilterOn = True

フィルターは、WHERE ステートメントと同様の方法で構築する必要があります。Where と比較していくつかの制限があります。レコードが返されることを DCount で確認することをお勧めします。

編集

サブフォームに特定のレコードのみが含まれる一連のレコードが必要な場合は、次の行に何かが必要です。

SELECT b.Title
FROM Books b 
WHERE b.ID IN (
   SELECT j.BookID FROM BooksAuthorJunction j 
   INNER JOIN  Authors a ON j.AuthorID = a.ID
   WHERE a.Author Like "Arn*")

複数のフォームを作成することには利点があります。書籍をメイン フォームとして作成者をサブフォームとして作成し、次に作成者をメイン フォームとして作成し、書籍をサブフォームとして作成します。多くの場合、ユーザーにとってより簡単です。

于 2012-09-29T08:56:34.583 に答える