【问题标题】:More efficinet way to filter form更有效的表单过滤方式
【发布时间】:2012-09-29 08:08:07
【问题描述】:

我有以下代码:

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

此代码可以按我的意愿工作,但即使在每个表中只有几条记录的测试数据库中,“看起来”也很慢。 我相信在 cmets 之间的循环中花费了时间(我如何检查这是否属实?)。 有没有比创建记录集并像我正在做的那样循环遍历表单更基本、明显和有效的方法来过滤表单?
“图书馆”表格是一个大表格,有几个子表格,可以看到一本书的所有数据。
查询“Libri_All_Query”是数据库中几乎所有表的连接,显示的代码是从我计划添加所有可能的搜索字段的表单中执行的。

【问题讨论】:

    标签: ms-access vba ms-access-2003


    【解决方案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*")
    

    构建多个表单有优势,书籍作为主要表单,作者作为子表单,然后作者作为主要表单,书籍作为子表单。这对用户来说通常更容易。

    【讨论】:

    • 感谢您的意见。我看到了这个属性,但不明白如何使用它。我需要过滤表单“Libri”而不是“Me”(表单名称:Libreria),我还能使用 Filter 属性吗?如果是,我可以为其他表格设置条件吗?我的意思是,Form Libri 绑定到表 Libri 并包含链接表(多对多)“Autori”、“Traduttori”等的子表单。如何在 stWhereClause 中为表“Autori”的字段设置条件,“Traduttori”等?
    • 我是指代码所属的表单,即写在表单代码模块中的代码。要过滤表单以使其仅显示子表单某某的记录,您需要一个更复杂的主表单记录源。
    猜你喜欢
    • 2013-06-06
    • 2010-12-07
    • 1970-01-01
    • 1970-01-01
    • 2015-04-16
    • 1970-01-01
    • 2021-02-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多