4

注意:请多多包涵,因为我对 Access 还比较陌生……我所学到的一切都是通过必要的 Google 搜索获得的。

所以我正在创建一个表单,其唯一目的是搜索数据库。在一个用例中,用户可以选择多个选项来过滤搜索,出于隐私原因,我们可以说“蓝色、绿色、红色、棕色”。用户可以选择这些颜色的任意组合,包括全部或无。在数据库表中,有一个主键(在我们的例子中是一个 ItemID)。表中的其他列是上面的颜色(蓝色、绿色、红色、棕色)。由于这些数据的结构(注意:由于多种原因我无法更改它),我必须在 VBA 中创建这个 SQL 查询,而不是使用 Access 提供的。

这是我在按下“搜索”按钮时用来创建和运行查询的代码:

Set qdf = Nothing

*Logic to create SQL query... variable to hold query is called sqlStr*

Set qdf = CurrentDb.CreateQueryDef("TemporaryQuery", sqlStr)
DoCmd.OpenQuery qdf.Name

经过大量搜索,这是我发现的唯一方法,除了使用 ADO 之外,我可以在 VBA 中创建 SQL 查询,然后在 VBA 中运行它。这种方法虽然有效,但它的缺点是它会创建一个查询,必须先关闭并删除该查询,然后才能再次运行该查询。对于将要使用它的用户来说,这是不可接受的。

我发现的所有示例(请耐心等待)都使用 ADO,但我无法开始工作。我有两个数据库,一个用于查询和表单,一个用于数据本身。包含数据的数据库的表通过查询和表单链接到数据库。我不确定 ADO 是否可以在该设置中工作,但如果可以,我无法弄清楚。

来自使用 Access 的 Java/Webdev 背景对我来说有点令人沮丧,因为它似乎使事情变得更加复杂(在我看来)它应该是。谁能帮我让它正常工作?

感谢您的宝贵时间...非常感谢!

4

1 回答 1

5

我对这些说法感到困惑...

“虽然这种方法有效,但它的缺点是它创建了一个查询,必须关闭并删除该查询才能再次运行查询。这对于将使用它的用户来说是不可接受的。”

我不明白为什么这会引起用户的关注。他们不必手动删除查询 --- 您可以使用 VBA 为他们执行此操作,使用DoCmd.DeleteObject. 实际上,听起来您可能只需要修改查询。如果是这样,您不需要先删除旧版本,然后再创建新查询。您可以简单地更改查询的.SQL属性。

如果用户的问题是他们甚至不想在 Navigation 面板中看到TemporaryQuery(太杂乱了?),请将其名称更改为USysTemporaryQuery。这样,他们只有在将面板属性设置为显示系统对象时才能看到它。

我将提供一个代码示例,它可能仍然不是您想要的。但也许其他人会发现它很有用。

Const cstrQueryName As String = "TemporaryQuery"
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim sqlStr As String

'*Logic to create SQL query... variable to hold query is called sqlStr*
' Apparently you have that piece worked out.  I'll use a simple query ...
sqlStr = "SELECT * FROM Dual;"

Set db = CurrentDb
If Not QueryExists(cstrQueryName) Then
    Set qdf = db.CreateQueryDef(cstrQueryName)
Else
    Set qdf = db.QueryDefs(cstrQueryName)
End If
qdf.sql = sqlStr
Set qdf = Nothing
Set db = Nothing
DoCmd.OpenQuery cstrQueryName

如果您以后仍想丢弃已保存的查询,请执行此操作...

If QueryExists(cstrQueryName) Then
    DoCmd.DeleteObject acQuery, cstrQueryName
End If

这是上述代码的辅助函数...

Public Function QueryExists(ByVal pName As String) As Boolean
    Dim db As DAO.Database
    Dim qdf As DAO.QueryDef
    Dim blnReturn As Boolean
    Dim strMsg As String

On Error GoTo ErrorHandler

    blnReturn = False ' make it explicit
    Set db = CurrentDb
    Set qdf = db.QueryDefs(pName)
    blnReturn = True

ExitHere:
    Set qdf = Nothing
    Set db = Nothing
    QueryExists = blnReturn
    Exit Function

ErrorHandler:
    Select Case Err.Number
    Case 3265 ' Item not found in this collection.
    Case Else
        strMsg = "Error " & Err.Number & " (" & Err.Description _
            & ") in procedure QueryExists"
        MsgBox strMsg
    End Select
    GoTo ExitHere

End Function
于 2013-06-27T20:10:44.320 回答