通过集合访问VBA循环,为每个项生成SQL语句

通过集合访问VBA循环,为每个项生成SQL语句,vba,ms-access,collections,Vba,Ms Access,Collections,我正在尝试编写代码,使一个associateids集合Associates是我集合的名称。在任何给定的时间都有10名员工,但该集合将根据本月谁做了什么工作而改变。因此,一旦创建了集合,我想循环遍历它,并为每个项创建一个SQL语句。类似这样的事情: For Each Item In Associates qryTopSQL = "SELECT TOP " & QA# & _ " Date, ID, [L#], Deal

我正在尝试编写代码,使一个associateids集合Associates是我集合的名称。在任何给定的时间都有10名员工,但该集合将根据本月谁做了什么工作而改变。因此,一旦创建了集合,我想循环遍历它,并为每个项创建一个SQL语句。类似这样的事情:

        For Each Item In Associates
            qryTopSQL = "SELECT TOP " & QA# & _
            " Date, ID, [L#], Deal, RndNum FROM tbl_Data WHERE Date Between #" & _
            StartDate & "# And #" & EndDate & "# AND ID = " & Associates() & _
            " ORDER BY RndNum"
        Next Item
所以我最终得到了很多SQL字符串,但我遇到了以下问题:

我是否正确地编写了ID=&Associates&part? 它将如何命名这些不同的字符串,以便我以后可以访问它们? 一旦完成这些操作,我想对所有SQL字符串执行UNIONALL查询。我该怎么做? 如果可以的话请帮忙,非常感谢。我对集合和数组不熟悉,我不了解我在网上发现的一些东西

编辑以进行更新: 我试过这个:

j = 1
k = 1
For Each Item In Associates
    If j = 1 And k = 1 Then
        qryTopString1 = "SELECT * FROM qryTopSQL_" & k
    Else
        qryTopString2 = " UNION ALL SELECT * FROM qryTopSQL_" & k
    End If
j = j + 1
k = k + 1
Next Item

'
Set qryTopUnionqdef = CurrentDb.CreateQueryDef("qryTopSQLUnion", qryTopString1 & qryTopString2)

但所得到的查询是第一个和最后一个TopQSL之间的结合,中间没有。显然,此时的循环解决了问题,但我目前还不知道该怎么做。

在Access中,有两种方法可以创建查询对象:在代码中使用VBA查询或使用功能区、向导或导航栏存储查询

基本上,你想两者兼而有之。因此,为了将VBA SQL字符串迁移到实际存储的查询对象中,必须使用。下面是如何迭代以动态创建10个Associates查询和一个union查询

Dim qryTopqdef As QueryDef, qryTopUnionqdef As QueryDef, findqdf As QueryDef
Dim i as Integer, j as Integer

' DELETE QUERIES IF EXIST
For each findqdf in CurrentDb.Querydefs
    If Instr(findqdf.Name, "qryTopSQL") > 0 Then
        db.QueryDefs.delete(findqdf.Name)
    End if
Next findqdf

' INDIVIDUAL 10 QUERIES
i = 1
For Each Item In Associates

    qryTopSQL = "SELECT TOP " & QA# & _
            " Date, ID, [L#], Deal, RndNum FROM tbl_Data WHERE Date Between #" & _
            StartDate & "# And #" & EndDate & "# AND ID = " & Item & _
            " ORDER BY RndNum"

    ' QUERY NAMES ARE SUFFIXED BY THE ITERATOR COUNT
    Set qryTopqdef = CurrentDb.CreateQueryDef("qryTopSQL_" & i, qryTopSQL)
    i = i + 1
Next Item


' UNION QUERY
j = 1
For Each Item In Associates
    If j = 1 Then
        qryTopSQL = "SELECT TOP " & QA# & _
                " Date, ID, [L#], Deal, RndNum FROM tbl_Data WHERE Date Between #" & _
                StartDate & "# And #" & EndDate & "# AND ID = " & Item & _
                " ORDER BY RndNum"
    Else
        ' UNIONS ARE SIMPLY STACKS OF SELECT STATEMENTS OF SAME COLUMN NUMBER AND DATA TYPE
        ' TOGETHER JOINED BY THE UNION OR UNION ALL CLAUSE
        qryTopSQL = qryTopSQL & " UNION SELECT TOP " & QA# & _
                " Date, ID, [L#], Deal, RndNum FROM tbl_Data WHERE Date Between #" & _
                StartDate & "# And #" & EndDate & "# AND ID = " & Item & _
                " ORDER BY RndNum"
    End if
    j = j + 1
Next Item

Set qryTopUnionqdef = CurrentDb.CreateQueryDef("qryTopSQLUnion", qryTopSQL)


' UNINTIALIZE OBJECTS
Set qryTopqdef = nothing
Set qryTopUnionqdef = nothing

另外-请参见集合与数组的对比

如果数组更适合我的需要,请告诉我QA、StartDate和EndDate在所有10条SELECT语句中是否相同?正如HansUp所提到的,如果所有其他变量都保持不变,唯一改变的是关联ID,您可以循环使用正确标量类型的集合或数组,只需为SQLIN运算符形成适当的输入,然后将其放入WHERE子句中。一般来说,如果采用更清洁的解决方案,性能会更好。另外,我认为您应该在代码中引用Item,而不是Associates,因为Item是集合中当前Item的表示形式。@HansUp,是的,QA、StartDate和EndDate对于所有10个都是相同的。非常感谢,我理解其中的大部分内容,但是我在qryTopSQL语句中遇到了一个错误:SELECT语句包含一个拼写错误或缺少的保留字或参数名称,或者标点符号不正确。哪个qryTopSQL语句?这可能与您的参数或集合项有关。执行此操作:1注释掉设置的qryTopqdef。。。并设置qryTopUnionqdef…,2临时添加MsgBox qryTopSQL,3重新运行函数或例程。查看消息框弹出窗口中的10条select语句中是否有任何错误。在单个10个查询中,如果我注释掉Set qryTopqdef并将msgbox放入,我得到了一个正确的msgbox,10个查询没有错误。当我将Set qryTopqdef放回代码中,并将Msgbox qryTopSQL放在代码的后面时,我得到了相同的错误。它发生在那里。MsgBox是一种调试实践,而不是对代码的修复!我需要您阅读消息框的SELECT语句,看看它们是否可以创建正确的查询。您的参数值QA、StartDate、EndDate等是否正确对齐?我知道我刚刚告诉您发生了什么。StartDate和EndDate是正确的,但QA是0而不是15。Item表示的ID正常