【问题标题】:Query based on a form with multiple criteria in one text field基于在一个文本字段中具有多个条件的表单进行查询
【发布时间】:2019-07-01 14:35:37
【问题描述】:

我是个新手,我正在开发一个数据库来管理多个产品的物料清单 (BOM)。我想创建一个表单,用户可以在其中输入组件名称列表,以查看这些组件的使用位置。

基于一个词运行查询很简单,但我正在努力将其扩展到多个词。 我希望用户输入由新行分隔的组件,如下所示:

Item1
Item2
Item3
...

如果我按原样使用文本字段,则查询将找不到任何内容,因为它将文本字段作为一个整体而不是逐行。

我尝试将文本字段处理为 ListBox,因为我认为它会像数组一样处理,但它没有 <value>,因此它不会返回任何搜索结果。

我的下一个尝试是使用第二个文本字段,我可以在其中将信息格式化为"Item1";"Item2";"Item3" 格式,以便我可以在in 语句中使用它。

如果我直接放:

in ("Item1";"Item2";"Item3")

在查询条件中,它将按预期运行,但是如果我尝试像这样引用HelpText(其中包含:"Item1";"Item2";"Item3"):

In ([Forms]![Search_mult_component]![HelpText])

然后我没有得到任何结果。我也尝试过格式化文本以包含括号,如("Item1";"Item2";"Item3")

正如我提到的,我刚刚开始了解 Access,因此我不确定这是否是一种好的做法,或者我是否试图强制一些可以通过稍微不同的方法以简单的方式完成的事情。

提前感谢您的支持!

【问题讨论】:

    标签: ms-access


    【解决方案1】:

    你不能。就像表名和字段名一样,IN 语句的值字符串必须在查询运行之前存在。

    您唯一的选择是动态编写 SQL 字符串,例如,创建一个将 SQL 传递到的临时查询。

    【讨论】:

    • 感谢您的回复!这可能是吹毛求疵,但 in 语句将在查询运行之前完成,因为文本字段在查询重新运行之前完成。还是必须在“设计”期间完成?我应该如何处理 SQL?我是否需要先将字符串预处理为“类似数组”的格式,或者我可以在 SQL 中完成所有这些操作?
    • 换一种说法:IN 语句必须是文字才能有效。如果您愿意,也可以“准备使用”。
    【解决方案2】:

    使用列表框来表示选择标准是一种很好的方法,因为它允许用户选择和操作多个项目作为不同的元素,而不必担心分隔符等。

    但是,我建议不要尝试访问列表框的 ,而是使用列表框填充基础表,然后您可以将其加入查询中的相关字段,无需where 子句即可自动过滤结果。

    【讨论】:

    • 感谢您的评论!您能否详细说明“填充基础表,然后您可以将其加入查询中的相关字段”这听起来像是一个可能的解决方案,但我不太清楚如何去做。您会使用子查询来根据用户输入填充列的内容吗?你有什么例子吗?谢谢!
    【解决方案3】:

    在@Lee Mac 提供火花后,我设法解决了它! 我创建了一个表TempTable 来存储输入值,稍后我可以在查询中使用这个表。不过,仍然需要一些代码才能到达那里!
    在表单中,我使用了一个文本框,其中包含问题中定义的多行数据和一个运行查询的按钮。因此,文本框本身和按钮之间的步骤有些分离。
    文本框的AfterUpdate 事件代码如下:

    Private Sub search_text_AfterUpdate()
    Dim TempTable As DAO.Recordset
    Dim i As Integer
    Dim allNums() As String
    
    ' ======= Open table =======
    Set TempTable = CurrentDb.OpenRecordset("SELECT * FROM [TempTable]")
    
    ' ======= Clear table =======
    DoCmd.SetWarnings False                 'Disable warnings. If not disabled the user will be prompted to confirm the delete
    DoCmd.RunSQL "DELETE * FROM TempTable"  'SQL statement used to delete all entries from a table
    DoCmd.SetWarnings True                  'Enable warnings
    
    ' ======= Process multiline text =======
    allNums = Split(search_text.Value, vbNewLine)                       'Split the multiline text
    
    For i = LBound(allNums) To UBound(allNums)                          'process line by line
          If (StrComp(Trim(allNums(i)), "", vbTextCompare) > 0) Then    'Check if current text is empty string
              TempTable.AddNew                                          'Add new Record to table
              TempTable![ToSearch] = (Trim(allNums(i)))                 'Fill in the text, trim whitespaces
              TempTable.Update                                          'Update Table. Seems to be necessary for changes to take effect
          End If
    Next i
    
    ' ======= Clean up and close table =======
    TempTable.Close                                                     'Close the table
    
    Set TempTable = Nothing                                             'No idea why this is needed :D
    
    ' ======= Refresh table =======
    'DoCmd.SelectObject acTable, "TempTable"
    'DoCmd.Requery
    'DoCmd.GoToRecord acDataTable, "TempTable", acLast
    
    End Sub
    

    这段代码负责清除表TempTable并用新输入填充它。 TempTable 有两列 IDToSearch,其中 ID 是表的主键,ToSearch 将填充来自文本框的输入。我在测试过程中看到,当表中的条目被删除时,新项目在添加时仍会收到新的密钥,这让我很担心,因为密钥可能会在某个时候用完。这是未来的问题,但如果您对此有任何建议(例如从表中删除密钥或其他东西),请告诉我。
    代码在用户在文本字段上输入后运行,但需要表格的Requery 才能生效!这包含在 Button 宏中:
    首先选择表对象并运行重新查询。在此之后,我关闭表并打开实际的查询,也需要重新查询以显示正确的更新值。
    有了这个解决方案,我就可以做我想做的事情,而不必深入研究 SQL。
    一如既往,我很感谢你的 cmets!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多