1

We'd like to count from an Access database that has multiple tables - about 50.

We need to count from 1 column in each table that is 'QCPASS' This is a check box - if a product passed the box was checked if failed then not. We need to count both for EACH table, also allowing the user to specify a date range from a date column that exists in every table.

I've tried this with a query but I am told the query is unable to select, count and do the date range. Any VBA help would be great.

Exporting to Excel would be great, but any results would be fine. Here is the query I created that counts in a column from each table passes and failures. I can't iterate with a query either, so VBA seems the way to go:

SELECT "Table1" , Count('qcpass') AS column 
FROM 5000028 
GROUP BY [5000028].qcpass
union 
SELECT "Table2",count('qcpass')
FROM 5000029 
Group By [5000029].qcpass;
4

1 回答 1

2

您可以遍历TableDefs数据库中的完整集合,并使用 VBA 创建查询。

一个警告:TableDefs集合具有 Access 数据库系统表,因此您需要跳过此。我建议您的一种方法是检查特定的表名前缀(在下面的代码中注明)。

public sub createMyBigUnionQuery()
dim db as DAO.database(), tbl as DAO.tableDef
dim strSQL as string, i as integer
set db = currentdb()
i = 1
for each tbl in db.TableDefs
    if left(tbl.name, 1) = "5" then ' Check for a table name prefix
        if i = 1 then
            ' The final spaces are important
            strSQL = "select '" & tbl.Name & "' as table, count(qcpass) as column " & _
                     "from [" & tbl.Name & "] " & _
                     "group by qcpass "
        else
            ' The final spaces are important
            strSQL = strSQL & " union all " & _
                     "select '" & tbl.Name & "' as table, count(qcpass) as column " & _
                     "from [" & tbl.Name & "] " & _
                     "group by qcpass "
        end if
        i = i + 1
    end if
next tbl
db.createQueryDef "qryYourFinalQuery", strSQL
db.close
exit sub

请注意,您可以定义任何您想要的有效查询。以此为提示,并对其进行调整以适应您的特定需求。

希望这可以帮助你


处理@HansUp 评论,如果您需要按日期过滤数据,您有两种选择:

  1. 包括程序创建的where每个条件select
  2. 在您的查询中包含日期字段并按其分组,然后创建第二个查询以从创建的查询中过滤您需要的数据。

我个人会选择选项 1,这是一个示例代码:

public sub createMyBigUnionQueryWithDates(d0 as date, d1 as date)
dim db as DAO.database(), tbl as DAO.tableDef
dim strSQL as string, i as integer
set db = currentdb()
i = 1
for each tbl in db.TableDefs
    if left(tbl.name, 1) = "5" then ' Check for a table name prefix
        if i = 1 then
            ' The final spaces are important
            strSQL = "select '" & tbl.Name & "' as table, count(qcpass) as column " & _
                     "from [" & tbl.Name & "] " & _
                     "where rowDate between " & cDbl(d0) & " and " &cDbl(d1) & " " & _
                     "group by qcpass "
        else
            ' The final spaces are important
            strSQL = strSQL & " union all " & _
                     "select '" & tbl.Name & "' as table, count(qcpass) as column " & _
                     "from [" & tbl.Name & "] " & _
                     "where rowDate between " & cDbl(d0) & " and " &cDbl(d1) & " " & _
                     "group by qcpass "
        end if
        i = i + 1
    end if
next tbl
db.createQueryDef "qryYourOtherFinalQuery", strSQL
db.close
exit sub

我使用的原因cDbl(d0)是因为访问日期对区域设置很敏感,我在处理它时遇到了很多麻烦。Access(和许多其他 Microsoft 产品)将日期存储为浮点数(整数部分是日期,小数部分是时间)。

另一个警告:如果您的日期不包括时间,那么between条件将起作用。但如果它们确实包含时间,那么我建议您将 where 条件更改为:

"where rowDate >= " & cDbl(d0) & " and rowDate < " & cDbl(d1 + 1)" 
于 2013-07-12T21:54:59.567 回答