3

关于我正在构建的数据库采用的方法的一般问题。我计划使用一些表单,允许 DB 业务用户输入条件,通过单选按钮等限制他们的搜索,然后根据他们的选择运行查询。

对于有一个或两个过滤器的简单查询,在查询设计视图中将数据字段的条件与相应的表单元素相关联似乎很容易,但是在处理嵌套时这种方法会失败(并且似乎很难阅读/编辑) if 语句(例如,如果 A 则为 x,如果 B 则为 y,如果 C 则为 z,否则为 q)。

我遇到了一篇文章,该文章描述了在数据库中创建一个单独的表,其中将存储查询名称和相应的 SQL 字符串,它们是在 VBA 中创建的,在 onClick 事件或某些基于表单的触发器之后运行。确定查询条件的逻辑都在VBA中,一旦代码执行,系统就会留下一条干净的SQL语句,存储在上述表中,然后用于执行查询。我相信每次访问/修改表单并请求查询时,表中的 SQL 字符串都会被覆盖。

由于这是我从事的第一个严肃的数据库,我正在寻找有关采取方法的一些指导。我刚才描述的是正确的还是处理这种情况的相当标准/常见的方法?有什么大问题吗?立即想到的一个问题是,如果两个数据库用户同时尝试使用不同的条件运行相同的查询,会发生什么?应该注意的是,我的用户群很小——可能只有 5 个用户会顺便访问数据库,用于临时报告等。

提前致谢!

编辑:这是我所指的论坛帖子:单独表中的 SQL 字符串

编辑2:作为一个一般示例,假设我的数据库有一个如下表:

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,"Foo","酒吧"))

... Cat=1 代表“全部”,2 和 3 分别代表 Foo 和 Bar。Access 给我一个错误,即查询太复杂,但如果我去掉嵌套的 if(因此忽略搜索这两个类别的选项),它就可以工作。

现在,显然这是一个大大简化的示例,但它让我开始思考如何处理表单驱动的查询,因为数据库的增长和更多的固定查询被加入。VBA 的想法是代码将运行,评估形成数据,然后将 SQL 构造为

选择...
从...
在哪里(“Foo”,“Bar”)

希望这有助于澄清一些事情。请原谅我的无知...随着我的发展,我仍在学习很多东西。谢谢。

4

4 回答 4

3

关于你问题中的这一点......

“如果两个数据库用户同时尝试使用不同的标准运行相同的查询会发生什么?”

在多用户 Access 应用程序中,您应该将 db 拆分为前端和后端 db 文件。BE db 应该包含表、索引和关系。FE db 应该包括您的查询、表单、报告等(基本上是您的应用程序需要的除了表之外的所有内容)和到 BE 表的链接。

将 BE db 文件放在所有应用程序用户都可以访问的网络共享上。每个用户都应该收到自己的 FE 数据库副本。

在这种情况下,每个用户都可以创建和运行他们自己的自定义即席查询,而不会影响其他用户的查询。

如果需要将查询条件或整个 SQL 语句存储在某处,可以将它们存储在 FE 中的本地表中,也可以将它们存储在普通 BE 表中但包含一个字段,可能是用户 ID,以便每个用户的查询可以单独存储.

请注意,如果您决定为每个 FE 用户在本地存储,当您需要部署新的 FE 版本时,他们保存的设置可能会被丢弃。在这种情况下,更好的方法是为每个用户提供一个辅助数据库文件,他们可以在其中存储他们的自定义设置。然后,您可以在部署新的 FE 版本时保留它们的设置。

我发现很难掌握您问题的“大局”。但我认为您应该在拆分应用程序的上下文中考虑它。

对于一般的“搜索表单”建议,请参阅 Allen Browne 的详细示例中可以重复使用的内容:搜索条件


在我看来,您也许可以使用一种简单的方法。

为搜索结果创建一个单独的表单。基于包含您要显示的所有字段的查询的表单。如果您需要WHERE该查询中的子句,请将其限制为仅适用于所有搜索变体的条件......也许Active = True。如果您无法确定适用于所有搜索的任何条件,请不要包含WHERE子句。

然后在您的搜索表单中,根据“立即搜索”命令按钮的单击事件评估用户的搜索条件。建立一个WHERE没有单词的字符串WHERE并将其用作WhereCondition选项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

如果其中一个搜索条件是一组选项中的一个或多个项目,则将它们显示为多选列表框并循环遍历列表框的.ItemsSelected属性以构建一个字符串,例如some_field IN ("a", "b", "z"). 如果您对那篇文章有疑问,请发布一个新问题,我们可以解决它。

检查我之前链接的 Allen Browne 的示例。我记得,他使用了类似的技术。

于 2013-04-04T16:58:06.007 回答
0

请记住,Access 已经是并且已经这样做了:如果您选择“按表单过滤”,它会弹出一个表单来帮助您为查询或表单构建过滤器,并帮助您自动构建报告。

因此,您需要确定您正在构建的内容与Access 提供的内容不同更好。

通常,这意味着您将过滤报告,并且您将通过仅提供有限的选项来简化过滤。

您确实需要考虑第一个标准。鉴于您过滤查询和表单,并且您可以自动构建报告,也许您的用户只需要指向 MS Access 中已经存在的功能。

由于过滤报告是常见的请求,您可以使用现有代码:OpenGate是商业报告生成器的一个示例:谷歌搜索并查看其他内容,包括您可以找到的免费和演示软件。

如果您确实想制作自己的过滤器构建器,这里有一些提示:

1)不要使用表单引用。如果我麻烦使用特殊的过滤器构建器,我会将实际数据值构建到 sql 中,从而避免您遇到的问题。当您不想要特殊的过滤器构建器表单的复杂性时,您可以使用对表单上的字段的引用。

2)您可以使用表格作为报告。只需将背景设置为白色,并使布局看起来像报告。这会给你一个可过滤的报告。它与报告的工作方式并不完全相同:有时这是一个优势。

3)大多数人不想玩他们的过滤器。他们想要一个特定的查询/报告设置并保存,然后他们每天/每周/每月/每年运行它。

4)如果用户想要提取一个特定的数据点,他们可能不需要让它看起来与更大报告中的单行完全一样。不要看中配置上的单选按钮:只需拉出不同版本的表单/查询/报告。

于 2013-08-07T04:35:19.840 回答
0

对此有微软官方的回答:http: //support.microsoft.com/kb/304302

基本上,它取决于您是否需要在查询中的第一个过滤条件之前只需要“where”这个词。后面的过滤条件,如果使用的话,都以单词“and”开头。从那里,您可以根据上面的 MS 知识库文章,使用 VBA 动态构建 SQL 查询字符串。

于 2013-08-07T03:32:48.010 回答
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 回答