Улучшение кода VBA в Access, чтобы сделать что-то вроде сводной таблицы - PullRequest
0 голосов
/ 22 декабря 2011

У меня есть таблица данных в MS Access 2007. В каждой записи 6 полей, тысячи записей. Я хочу сделать своего рода сводную таблицу, как объект. То есть, если какие-либо две строки окажутся одинаковыми в первых 4 полях, они будут сгруппированы в одну строку. Заголовками столбцов в этой сводной таблице будут значения из 5-го поля, а значением в сводной таблице будет 6-е поле, сумма в долларах. Представьте себе 5-е поле как буквы A, B, C, D, E, F, G. Таким образом, в таблице, с которой я начинаю, может быть строка с A в 5-м поле и $ 3.48 в 6-м поле. Другая строка может совпадать в первых 4 полях, иметь B в 5-м поле и 8,59 $ в 6-м поле. Другой может совпадать в первых 4 полях, иметь E в 5-м поле и $ 45.20 в 6-м поле. Я хочу, чтобы все эти строки были превращены в одну строку (в новой таблице), которая начинается с первых 4 полей, в которых они совпадают, затем перечисляет $ 3,48, $ 8,59, $ 0,00, $ 0,00, $ 0,20, $ 0,00, $ 0,00, соответствующие заголовкам столбцов A, B, C, D, E, F, G (поскольку ни одна из записей не содержит C, D, F, G, их соответствующие значения равны $ 0,00), а затем заканчивается еще одним полем, которое суммирует деньги в этой строке.

В настоящее время у меня есть некоторый код VBA, который делает это, написанный кем-то еще несколько лет назад. Это очень медленно, и я надеюсь на лучший путь. Я задал предыдущий вопрос (но не очень четко, поэтому мне посоветовали создать новый вопрос), где я спрашивал, есть ли лучший способ сделать это в VBA. Мой вопрос был задан по поводу одновременного чтения и записи больших объемов данных в Access через VBA, что, как я знаю, является хорошей практикой в ​​Excel. То есть я надеялся взять свою исходную таблицу и просто присвоить все это массиву сразу (как в Excel, а не по ячейкам), затем поработать с этим массивом в VBA и создать новый массив, а затем записать весь этот массив сразу в новую таблицу (вместо записи по записи, поле за полем). Судя по ответам на этот вопрос, кажется, что это не совсем возможно в Access, но лучше всего было бы использовать какой-то запрос. Я попробовал Мастер запросов и нашел запрос кросс-таблицы, который близок к тому, что я описал выше. Но, как представляется, в заголовке строки используется максимум 3 поля, тогда как здесь у меня есть 4. И вместо того, чтобы указывать $ 0,00, когда значение не указано (как C, D, F, G в моем примере выше), это просто оставляет пустым.

Обновление (в ответ на комментарий Рему, чтобы дать пример данных): Вот некоторые примеры данных.

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

Но, когда я копирую и вставляю SQL, заданный Remou, я получаю только вывод

a   b   c   d  an  bn  cn  dn  en

1   2   3   5   5  10  15  20  25

1 Ответ

1 голос
/ 22 декабря 2011

Это, я думаю, то, что вы хотите, но было бы лучше рассмотреть дизайн базы данных, потому что это решение, похожее на электронную таблицу.

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
...