使用 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 子句的主要内容,如果未能解决你的问题,请参考以下文章
是否可以在 Access 查询中使用其模块名称来限定 VBA 函数调用?
如何在 VBA 的另一个函数中调用我在 VBA 中创建的函数?