【问题标题】:CrossTab with multiple column headings in Access VBAAccess VBA中具有多个列标题的交叉表
【发布时间】:2014-09-25 07:12:20
【问题描述】:

我有一个具有这种结构的表(“Spot”是存储项目的位置,“N”是该位置的项目数)。

Id | Spot1 | N1 | Spot2 | N2 | Spot3 | N3 |
1  |   A   | 2  |   B   | 2  |   C   | 1  |
2  |   B   | 2  |   C   | 1  |   D   | 2  |
3  |   A   | 2  |   C   | 1  |   D   | 5  |

我想对该表运行查询并创建如下表:

ID | A | B | C | D |
1  | 2 | 2 | 1 | _ |
2  | _ | 2 | 1 | 2 |
3  | 2 | _ | 1 | 5 |

在决定构建此查询的最佳策略时,我需要一些帮助。

我正在考虑创建几个具有不同列标题的交叉表查询,并以某种方式将这些交叉表合并在一起。

这是一个好方法还是有更有效的方法。我的示例只有 4 个不同的项目,但我的实际表有大约 20 个项目,因此最终表将有 20 列和超过 200 条记录。

【问题讨论】:

  • 如您所说,您可以制作 20 个交叉表,但是您必须通过丑陋的 FROM 子句或使用一组凌乱的查找或在 VBA 中手动逐步执行每个查询将所有这些交叉表拼接在一起。颠倒这些步骤并制作3列(ID,Spot,N)的表或查询似乎不是更好吗?到达那里的多种方式。然后你可以交叉表。
  • 这是一个想法,但我会在该表中为一个 ID 设置多行。
  • 不是在交叉表之后。中间查询中的 ID 列不必是唯一的。如果您愿意,将其从 ID 重命名为 OrigID 或其他名称。查询中的 ID 字段只是一个普通的整数字段。中间查询的独特之处在于 ID 和 Spot 的组合。但两者都不必是独立的(也不应该是)。表有自动编号而不是查询。我将该 ID 提取到查询中,以便您可以在交叉表的 GROUP BY 中使用它。

标签: sql vba ms-access crosstab


【解决方案1】:

我建议先拼接,然后交叉制表。我们可以使用包含您的源 ID、Spot 和 Amount 的中间三列表来执行此操作。以下代码是一种通用方法,它不假设源表中有多少列。它也不假设存在多少个点。它确实假设表 tmpTbl 已经存在。

Sub largeCrossTab()
    Dim rst As DAO.Recordset, rst2 As DAO.Recordset
    Set rst = CurrentDb.OpenRecordset("Table1")
    Dim fld As DAO.Field
    CurrentDb.Execute "DELETE FROM tmpTbl"
    For Each fld In rst.Fields
        If InStr(fld.Name, "Spot") > 0 Then
            CurrentDb.Execute "INSERT INTO tmpTbl(OrigID, Spot, Amount) " _
                & "SELECT ID, " & fld.Name & ", N" & Right(fld.Name, Len(fld.Name) - 4) _
                & " FROM Table1"
        End If
    Next
    Set rst2 = CurrentDb.OpenRecordset("TRANSFORM Nz(Sum(Amount), '_') " _
        & "SELECT OrigID " _
        & "FROM tmpTbl " _
        & "GROUP BY OrigID " _
        & "PIVOT Spot")

    ''' Do something with rst2 '''

    Set rst = Nothing
    Set rst2 = Nothing
    Set fld = Nothing
End Sub

【讨论】:

  • 当我在 table1 中有数千个条目时会看到它有多慢(现在一个 400 行的 table1 生成一个 2000 原始 tmptbl)。但现在它可以工作了,谢谢!
  • @user3638420 如果数据变得如此之大以至于您担心性能,您可能希望一次交叉制表更少的数据。在这种情况下,您可以重新散列逻辑以确定将存在哪些列,从而在开始时创建输出表结构。然后,您可以对输出表执行 INSERT 语句,其中 TRANSFORM 仅为 Spot1/N1,然后 TRANSFORM 仅为 Spot2/N2,依此类推。
猜你喜欢
  • 1970-01-01
  • 2015-12-28
  • 1970-01-01
  • 2021-08-01
  • 1970-01-01
  • 2012-03-09
  • 1970-01-01
  • 2015-07-13
  • 2019-04-11
相关资源
最近更新 更多