Изменение формы таблицы Excel PowerQuery - PullRequest
1 голос
/ 12 марта 2019

У меня есть большая таблица в Excel, которая представляет собой вывод инструмента для сбора данных, который выглядит примерно так:

  DateA    |  ValueA  |   DateB    |  ValueB  | ... |    DateZ   | ValueZ
---------------------------------------------------------------------------
2019-01-01 |    3     | 2019-01-01 |    6     | ... | 2019-01-04 |   7
2019-01-02 |    1     | 2019-01-04 |    2     | ... | 2019-01-05 |   3

И я бы хотел обработать это так, как это:

  Date     |  Value  | Type
-----------------------------
2019-01-01 |   3     |   A
2019-01-02 |   1     |   A
2019-01-01 |   6     |   B
2019-01-04 |   2     |   B
            ...
2019-01-04 |   7     |   Z
2019-01-05 |   3     |   Z

Потому что это формат, который используется в нашей базе данных sql. Как сделать это наименее утомительным способом, желательно с помощью PowerQuery? Я бы хотел избежать грубого копирования и вставки с помощью vba loop. Количество столбцов является фиксированным, но было бы неплохо иметь возможность добавить еще один столбец позже, однако количество строк будет варьироваться в зависимости от некоторого значения (например, 20, 21, 20, 22, 19, 20) изо дня в день. день

1 Ответ

1 голос
/ 12 марта 2019

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

ColumnsToRows =
    Table.FromColumns(
        {
         Table.ToColumns(Source),
         Table.ColumnNames(Source)
        },
        {"ColumnValues","ColumnName"}
    )

Это должно дать вам следующую таблицу, где каждый список состоит из значений всоответствующий столбец.Например, верхний список - {1/1/2019,1/2/2019}.(Часть из столбцов from должна добавить столбец ColumnName.)

| ColumnValues | ColumnName |
|--------------|------------|
| [List]       | DateA      |
| [List]       | ValueA     |
| [List]       | DateB      |
| [List]       | ValueB     |
| [List]       | DateZ      |
| [List]       | ValueZ     |

Затем мы можем отфильтровать это по типу данных в каждом списке.Чтобы получить строки с датами, вы можете написать:

DataRows =
    Table.SelectRows(
        ColumnsToRows,
        each Value.Type(List.First([ColumnValues])) = type date
    )

, что даст вам следующую отфильтрованную таблицу:

| ColumnValues | ColumnName |
|--------------|------------|
| [List]       | DateA      |
| [List]       | DateB      |
| [List]       | DateZ      |

Если развернуть первый столбец с помощью Table.ExpandListColumn(DataRows, "ColumnValues"), вы получите

| ColumnValues | ColumnName |
|--------------|------------|
| 1/1/2019     | DateA      |
| 1/2/2019     | DateA      |
| 1/1/2019     | DateB      |
| 1/4/2019     | DateB      |
| 1/4/2019     | DateZ      |
| 1/5/2019     | DateZ      |

Логика аналогична фильтрации и расширению строк значений.

ValueRows =
    Table.ExpandListColumn(
        Table.SelectRows(
            ColumnsToRows,
            each Value.Type(List.First([ColumnValues])) = type number
        ),
        "ColumnValues"
    )

Что дает вам похожую таблицу:

| ColumnValues | ColumnName |
|--------------|------------|
| 3            | ValueA     |
| 1            | ValueA     |
| 6            | ValueB     |
| 2            | ValueB     |
| 7            | ValueZ     |
| 3            | ValueZ     |

Теперь нам просто нужночтобы объединить нужные столбцы в одну таблицу:

Combine Columns =
    Table.FromColumns(
        {
         DateRows[ColumnValues],
         ValueRows[ColumnValues],
         ValueRows[ColumnName]
        },
        {"Date", "Value", "Type"}
    )

, а затем извлечь текст, следующий за Value в именах столбцов.

ExtractType =
    Table.TransformColumns(
        CombineColumnns,
        {{"Type", each Text.AfterDelimiter(_, "Value"), type text}}
    )

Окончательная таблица должна быть простокак указано:

| Date     | Value | Type |
|----------|-------|------|
| 1/1/2019 | 3     | A    |
| 1/2/2019 | 1     | A    |
| 1/1/2019 | 6     | B    |
| 1/4/2019 | 2     | B    |
| 1/4/2019 | 7     | Z    |
| 1/5/2019 | 3     | Z    |

Все в одном запросе, M-код выглядит так:

let
    Source = <Source Goes Here>,
    ColumnsToRows = Table.FromColumns({Table.ToColumns(Source), Table.ColumnNames(Source)}, {"ColumnValues","ColumnName"}),
    DateRows = Table.ExpandListColumn(Table.SelectRows(ColumnsToRows, each Value.Type(List.First([ColumnValues])) = type date), "ColumnValues"),
    ValueRows = Table.ExpandListColumn(Table.SelectRows(ColumnsToRows, each Value.Type(List.First([ColumnValues])) = type number), "ColumnValues"),
    CombineColumnns = Table.FromColumns({DateRows[ColumnValues], ValueRows[ColumnValues], ValueRows[ColumnName]},{"Date", "Value", "Type"}),
    ExtractType = Table.TransformColumns(CombineColumnns, {{"Type", each Text.AfterDelimiter(_, "Value"), type text}})
in
    ExtractType
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...