使用 VBA 函数调用在 QueryEditor 中创建查询以指定 WHERE IN 子句

Posted

技术标签:

【中文标题】使用 VBA 函数调用在 QueryEditor 中创建查询以指定 WHERE IN 子句【英文标题】:Create query in QueryEditor with VBA function call for specifying the WHERE IN clause 【发布时间】:2015-06-01 06:51:59 【问题描述】:

我编写了几个 VBA 函数,它们最终返回一个整数集合:

Public Function ValidIDs() As Collection

现在我想在 QueryEditor 中运行创建一个查询,条件如下:WHERE TableID IN ValidIDs()。这是行不通的,因为由于某种原因访问甚至找不到我的函数,只要它返回一个集合。因此我在它周围写了一个包装器,它加入了集合:

Public Function joinCollectionForIn(Coll As Collection) As String

现在调用ValidIDs() 的第三个函数将结果传递给joinCollectionForIn 并返回该结果。让我们称之为GetIDCollectionAsString()

因此,我现在可以将查询更改为 WHERE TableID IN (GetIDCollectionAsString())。请注意添加的括号,因为IN 在任何情况下都需要它们,它们不能只是在GetID... 返回的字符串的末尾和开头。

但运行该查询会导致

条件表达式中的数据类型不匹配。

我猜这是因为我返回了一个字符串,因此访问会自动将该字符串包装在' 中以用于 SQL,IN 子句不再有效,因为我会检查一个数字是否为 IN 1 个字符串的集合。

所以我的问题是:

有没有办法阻止访问为 SQL 包装返回的字符串

或者(会好很多):

是否存在将集合或数组传递给WHERE IN-clause 的现有方法?

P.S.:我目前正在使用一种解决方法,方法是在 IN 后面的括号中写一个占位符(例如 IN (1,2,3,4,5))并将 Form_Load 中的占位符替换为 GetIDCollectionAsString() 的结果 -这行得通,但它并不漂亮......

编辑:最终查询应该类似于SELECT * FROM TestTable t WHERE t.ID IN (1,2,3,4,5,6,7)。这实际上可以使用上述方法,但不是很好。

【问题讨论】:

你能举个例子说明你从函数GetIDCollectionAsString.. 中得到什么吗?还要注意字符串的IN 子句需要这种输入IN ('Id01','Id02'.....) 它返回类似 "1, 2, 3, 4, 5" 的东西,这正是我想要的。它们不应该被包裹在' 中,因为它们应该是整数。 据我记忆,Access 不支持这个。有一个 IN 子句会生成 RUN TIME。但是,您可以使用 VBA。 @PaulFrancis “你可以使用 VBA”是指我的 P.S.?使用 vba 创建或更改查询,而不是完全在查询编辑器中构建它!? 是的,没有真正理解writing a placeholder 的意思,现在它更有意义了。不幸的是,AFAIK - 这是要走的路。 【参考方案1】:

这需要比看起来更多的工作......我找不到直接的解决方案,所以这里有一个解决方法

Public Function ListforIn(inputString As String) As String
    Dim qdf As QueryDef
    Dim valCriteria As String
    Dim strsql As String
    Dim splitcounter As Byte
    Dim valcounter As Byte

    Set qdf = CurrentDb.QueryDefs(**TheNameOfQueryYouWantToModify**)

    strsql = qdf.sql
    strsql = Replace(strsql, ";", "") 'To get rid of ";"
    splitcounter = Len(inputString) - Len(Replace(inputString, ",", ""))

    For valcounter = 0 To splitcounter
        valCriteria = valCriteria & ValParseText(inputString, valcounter, ",")
    Next

    strsql = strsql & " WHERE TableId IN (" & Left(valCriteria, Len(valCriteria) - 1) & ")"
    qdf.sql = strsql
End Function


Public Function ValParseText(TextIn As String, X As Byte, Optional MyDelim As String) As Variant
    On Error Resume Next
    If Len(MyDelim) > 0 Then
        ValParseText = "Val(" & (Split(TextIn, MyDelim)(X)) & "),"
    Else
        ValParseText = Split(TextIn, " ")(X)
    End If
End Function

【讨论】:

这只会检索我所有返回号码的第一个号码,因为它stops reading the string at the first character it can't recognize as part of a number 如果你得到一个像"1,2,3,4,5" 这样的字符串并且你输入了 val 然后它就可以工作了......我错过了什么? ....IN(val("1,2,3,4,5")) IN(val("1,2,3,4,5")) 将变为 IN(1) - 这不是我想要的 我刚看到...你是对的...我会努力寻找解决方案 谢谢,我也想出一个 ;)

以上是关于使用 VBA 函数调用在 QueryEditor 中创建查询以指定 WHERE IN 子句的主要内容,如果未能解决你的问题,请参考以下文章

从 Java 调用 Access 中的 VBA 函数

是否可以在 Access 查询中使用其模块名称来限定 VBA 函数调用?

从 vba 代码调用 Excel 的工作表函数

如何在 VBA 的另一个函数中调用我在 VBA 中创建的函数?

如何在 VBA 中使用另一个宏/函数(UDF)调用对象/宏/用户窗体?

VBA (Ms-Access) 从宏调用成员函数