Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ms access Access中VBA代码的改进,以实现类似透视表的功能_Ms Access_Vba - Fatal编程技术网

Ms access Access中VBA代码的改进,以实现类似透视表的功能

Ms access Access中VBA代码的改进,以实现类似透视表的功能,ms-access,vba,Ms Access,Vba,我在MS Access 2007中有一个数据表。每个记录有6个字段,数千条记录。我想制作一种类似透视表的对象。也就是说,如果前4个字段中的任意两行恰好相同,那么它们最终将分组到一行中。此透视表中的列标题将是第5个字段中的值,透视表中的值将是第6个字段,即美元金额。将第5个字段想象为字母A、B、C、D、E、F、G。因此,我开始的表格可能有一行,第5个字段中有A,第6个字段中有3.48美元。另一行可能在前4个字段中匹配,第5个字段中有B,第6个字段中有8.59美元。另一个可能在前4个字段匹配,第5个

我在MS Access 2007中有一个数据表。每个记录有6个字段,数千条记录。我想制作一种类似透视表的对象。也就是说,如果前4个字段中的任意两行恰好相同,那么它们最终将分组到一行中。此透视表中的列标题将是第5个字段中的值,透视表中的值将是第6个字段,即美元金额。将第5个字段想象为字母A、B、C、D、E、F、G。因此,我开始的表格可能有一行,第5个字段中有A,第6个字段中有3.48美元。另一行可能在前4个字段中匹配,第5个字段中有B,第6个字段中有8.59美元。另一个可能在前4个字段匹配,第5个字段为E,第6个字段为45.20美元。我希望将所有这些行转换为一行(在新表中),从它们匹配的前4个字段开始,然后列出$3.48、$8.59、$0.00、$0.00、$45.20、$0.00、$0.00,对应于列标题a、B、C、D、E、F、G(因为没有包含C、D、F、G的记录,它们对应的值是$0.00),然后以另一个字段结束,该字段合计该行的金额

目前,我有一些VBA代码可以做到这一点,是几年前由其他人编写的。这是非常缓慢,我希望有一个更好的方式。我问了以前的一个问题(但不是很清楚,所以有人建议我创建一个新问题),我在问是否有更好的方法在VBA中实现这一点。我的问题是关于通过VBA在Access中一次读取和写入大量数据,我知道这是Excel中的一个很好的做法。也就是说,我希望获得我的原始表,然后一次将整个内容分配给一个数组(在Excel中,而不是一个单元格一个单元格),然后在VBA中使用该数组并创建一些新数组,然后将整个数组一次写入一个新表(而不是逐个记录,逐个字段)。从这个问题的答案来看,在Access中似乎不太可能,但我的最佳选择可能是使用某种查询。我尝试了查询向导,发现交叉表查询与我上面描述的非常接近。但是,行标题中最多使用3个字段,而这里我有4个字段。并且,当没有指定值时(如上面示例中的C、D、F、G),它只留下一个空白,而不是将$0.00放入

更新(回应Remou提供样本数据的评论):以下是一些样本数据

ID   a   b   c   d   e   f
 7   1   2   3   5   A   5
 8   1   2   3   5   B  10
 9   1   2   3   5   C  15
10   1   2   3   5   D  20
11   1   2   3   5   E  25
12   1   2   4   4   A  16
13   1   2   4   4   B  26
14   1   3   3   7   D  11
15   1   3   3   7   B  11
结果应该是:

a   b   c   d  an  bn  cn  dn  en   Total

1   2   3   5   5  10  15  20  25      75
1   2   4   4  16  26   0   0   0      42
1   3   3   7   0  11   0  11   0      22
但是,当我复制并粘贴Remou提供的SQL时,我得到的唯一输出是

a   b   c   d  an  bn  cn  dn  en

1   2   3   5   5  10  15  20  25

这是我想要的,但是最好考虑数据库设计,因为这是一个电子表格解决方案。

SELECT t0.a,
       t0.b,
       t0.c,
       t0.d,
       Iif(Isnull([a1]), 0, [a1]) AS an,
       Iif(Isnull([b1]), 0, [b1]) AS bn,
       Iif(Isnull([c1]), 0, [c1]) AS cn,
       Iif(Isnull([d1]), 0, [d1]) AS dn,
       Iif(Isnull([e1]), 0, [e1]) AS en
FROM   (((((SELECT DISTINCT t.a,
                           t.b,
                           t.c,
                           t.d
           FROM   table3 t) AS t0
           LEFT JOIN (SELECT t.a,
                              t.b,
                              t.c,
                              t.d,
                              t.f AS a1
                       FROM   table3 t
                       WHERE  t.e = "A") AS a0
             ON ( t0.d = a0.d )
                AND ( t0.c = a0.c )
                AND ( t0.b = a0.b )
                AND ( t0.a = a0.a ))
          LEFT JOIN (SELECT t.a,
                             t.b,
                             t.c,
                             t.d,
                             t.f AS b1
                      FROM   table3 t
                      WHERE  t.e = "B") AS b0
            ON ( t0.d = b0.d )
               AND ( t0.c = b0.c )
               AND ( t0.b = b0.b )
               AND ( t0.a = b0.a ))
         LEFT JOIN (SELECT t.a,
                            t.b,
                            t.c,
                            t.d,
                            t.f AS c1
                     FROM   table3 t
                     WHERE  t.e = "C") AS c0
           ON ( t0.d = c0.d )
              AND ( t0.c = c0.c )
              AND ( t0.b = c0.b )
              AND ( t0.a = c0.a ))
        LEFT JOIN (SELECT t.a,
                           t.b,
                           t.c,
                           t.d,
                           t.f AS d1
                    FROM   table3 t
                    WHERE  t.e = "D") AS d0
          ON ( t0.d = d0.d )
             AND ( t0.c = d0.c )
             AND ( t0.b = d0.b )
             AND ( t0.a = d0.a ))
       LEFT JOIN (SELECT t.a,
                          t.b,
                          t.c,
                          t.d,
                          t.f AS e1
                   FROM   table3 t
                   WHERE  t.e = "E") AS e0
         ON ( t0.d = e0.d )
            AND ( t0.c = e0.c )
            AND ( t0.b = e0.b )
            AND ( t0.a = e0.a ); 
表3

ID  a   b   c   d   e   f
1   1   2   3   4   a   €10.00
2   1   2   3   4   b   €10.00
3   1   2   3   4   c   €10.00
4   1   2   3   4   d   €10.00
5   1   2   3   4   e   €10.00
6   1   2   3   5   a   €10.00
7   1   2   3   5   b   
8   1   2   3   5   c   €10.00
9   1   2   3   5   d   €10.00
10  1   2   3   5   e   €10.00
结果

有两行,因为前四列中只有两个不同的集合

a   b   c   d   an      bn      cn      dn      en
1   2   3   4   €10.00  €10.00  €10.00  €10.00  €10.00
1   2   3   5   €10.00  €0.00   €10.00  €10.00  €10.00
上述sql的工作方式是,它从表中选择四个定义列和货币列中的每一个,其中排序列具有特定的排序字母,并用排序字母标记货币列,然后组装这些子查询中的每一个,但是,您可以进行子查询并查看结果。最后一个是括号之间的部分:

INNER JOIN (SELECT t.a,
                          t.b,
                          t.c,
                          t.d,
                          t.f AS e1
                   FROM   table3 t
                   WHERE  t.e = "E") AS e0

所以,你是说我需要学习SQL。嗯,我想我今天会读到它。@Graphth SQL是让数据库上瘾的原因:)顺便说一句,上面的方法很有效,如果你想提供一些真实的字段名和示例数据,你可以得到一个剪切粘贴解决方案。我复制并粘贴了这段代码到一个数据库中,在那里我遵循了上面给出的规则。我用数据“table3”调用该表,并将字段标记为“a”、“b”、“c”、“d”、“e”和“f”。我运行了查询,它只给出了一行,尽管根据我的数据应该有15行。然而,正如我所描述的,它确实正确地收集了表3中的各种记录,并将它们放在这一行中。这是SQL中的一个小错误还是您认为我做错了什么?您只需要将内部连接更改为左连接。