【问题标题】:VBA Access - Multiple Tables count by dateVBA 访问 - 多个表按日期计数
【发布时间】:2017-01-25 02:21:03
【问题描述】:

我们想从具有多个表的 Access 数据库中计数 - 大约 50 个。

我们需要从每个表中的 1 列开始计数,即 'QCPASS' 这是一个复选框 - 如果产品通过了该框,则选中该框,如果失败则不选中。我们需要为每个表计算两者,还允许用户从每个表中存在的日期列中指定日期范围。

我已经通过查询尝试过此操作,但我被告知查询无法选择、计算和执行日期范围。任何 VBA 帮助都会很棒。

导出到 Excel 会很好,但任何结果都可以。这是我创建的查询,它计算每个表通过和失败的列。我也不能用查询进行迭代,所以 VBA 似乎是要走的路:

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

【问题讨论】:

    标签: ms-access vba


    【解决方案1】:

    您可以遍历数据库中的完整 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. 在过程创建的每个 select 上包含 where 条件
    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)" 
    

    【讨论】:

    • 这个答案忽略了问题的“按日期计数”部分。
    • @HansUp 在查询中编写相应的字段、where 条件和group by 条件应该不难,你不觉得吗?
    • 不是真的,但在之前的问题中,OP 说他不想为他正在联合的 50 个SELECTs 中的每一个写一个WHERE
    • @HansUp 我已编辑问题以解决您的评论。而且我认为每个选择中的where 条件是最简单的方法(this 帖子没有说明每次选择都不需要wheres)。无论如何,这只是一种方法,它确实有效。
    • @HansUp 我已经阅读了 OP 的上一个问题......我认为他不想在每个选择上“手动”写一个 where 条件。通过使用 VBA 代码,工作量很小。
    猜你喜欢
    • 2015-06-11
    • 2018-02-27
    • 1970-01-01
    • 2018-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多