Глава 19. Объекты Power Query

Рубрика: 7. Полезняшки Excel

Это продолжение перевода книги Кен Пульс и Мигель Эскобар. Язык М для Power Query. Главы не являются независимыми, поэтому рекомендую читать последовательно.

Предыдущая глава    Содержание    Следующая глава

Прежде чем мы продолжим изучение языка M, сначала подробнее рассмотрим доступные объекты и функции. Обратите внимание, что все ключевые объекты в этой главе (таблицы, списки, записи, значения, двоичные файлы и ошибки) отображаются в столбцах редактора Power Query зеленым шрифтом. Кроме того, каждый объект можно просмотреть, щелкнув пробел рядом с ним.

Ris. 19.1. Edinstvennaya tablitsa v prosmatrivaemoj knige

Рис. 19.1. Единственная таблица в просматриваемой книге

Скачать заметку в формате Word или pdf, примеры в формате архива

Таблицы

Объекты таблицы могут отображаться во многих местах в Power Query, и это весьма ценно, так как с ними очень легко работать. Выполните следующие действия, чтобы убедиться в этом. Откройте Power Query Objects.xlsx. Пройдите по меню Данные –> Получить данные –> Из других источников –> Пустой запрос. Введите в строке формул: =Excel.CurrentWorkbook(). Нажмите Enter. В книге есть одна таблица (цифра 1 на рис. 19.1). Если кликнуть в пустое место рядом со словом Table, в нижней части окна появится предварительный просмотр таблицы (2).

Давайте завершим запрос, прежде чем двигаться дальше. Переименуйте запрос – Table. Главная –> Закрыть и загрузить в… –> Только создать подключение.

Списки

В отличие от таблиц списки содержит только один столбец. Синтаксис: список можно идентифицировать по наличию фигурных скобок; элементы списка разделяются запятыми; текстовые элементы берутся в кавычки (по аналогии с использованием текстовых элементов в , формулах Excel). Пример числового списка: ={1,2,3,4,5,6,7,8,9,10}. Пример списка из текстовых элементов: ={"A","B","C","D","E","F","G","H","I","J"}. Списки могут включать элементы разных типов данных, включая другие списки: ={1,465,"M","Data Monkey",{999,234}}.

Создание списков

Создайте новую книгу Excel. Пройдите по меню Данные –> Получить данные –> Из других источников –> Пустой запрос. В строке формул введите: ={1,2,3}. Нажмите Enter.

Ris. 19.2. Sozdanie spiska s nulya

Рис. 19.2. Создание списка с нуля

Обратите внимание, появилась контекстная вкладка Средства для списков –> Преобразование. В этот момент почти все команды на других вкладках будут неактивны.

Для создания больших списков с нуля можно воспользоваться специальными символами. Например, если вам нужен список 365 дней, введите в строку формул: ={1..365}. Таким же образом можно создавать последовательные алфавитные списки при условии, что символы заключены в кавычки и используется только один символ. Например, ={"а".."J"} будет работать, но ={"AA".."ZZ"} не будет. Вы также можете использовать запятые внутри списков, при условии, что они находятся внутри кавычек. Введите в строке формул: = {"Пульс, Кен", "Эскобар, Мигель"}, и вы получаете список из двух элементов, показывающие имена авторов книги:

Ris. 19.3. Spisok iz imen avtorov knigi

Рис. 19.3. Список из имен авторов книги

Преобразование списков в таблицы

Если вы хотите разделить список на несколько столбцов, сначала преобразуйте его в таблицу. Для этого нажмите кнопку В таблицу (на рис. 19.2 слева). Появится диалог:

Ris. 19.4. Kakoj znak ispolzovat v kachestve razdelitelya

Рис. 19.4. Какой знак использовать в качестве разделителя?

Установить в качестве разделителя запятую, второй оставьте по умолчанию, нажмите Ok:

Ris. 19.5. Dannye zagruzhennye iz spiska razdelennogo zapyatymi

Рис. 19.5. Данные, загруженные из списка, разделенного запятыми

Завершить этот запрос. Измените имя запроса на List_Authors. Главная –> Закрыть и загрузить в… –> Только создать подключение.

Создание списков из столбцов таблицы

Иногда может возникнуть задача извлечь данные из одного столбца запроса в список. Давайте посмотрим, как это работает. Откройте файл Power Query Objects.xlsx. Перейдите на лист Sales. Кликните на любую ячейку Таблицы. Пройдите по меню Данные –> Из таблицы/диапазона:

Ris. 19.6. Ishodnaya tablitsa zaprosa

Рис. 19.6. Исходная таблица запроса; чтобы увеличить изображение кликните на нем правой кнопкой мыши и выберите Открыть картинку в новой вкладке

Если вам нужен уникальный список Inventory Item, вы можете удалить все остальные столбцы, а затем перейти на вкладку Главная –> Удалить строки –> Удалить дубликаты. Проблема в том, что объект все еще будет в форме таблицы, и вы не сможете передать его в функцию, если вам это нужно. Вы можете получить уникальные элементы в виде списка, что даст вам требуемую гибкость. Если вы экспериментировали с таблицей, удалите шаги, вернувшись к ситуации, как на рис. 19.6 – только два примененных шага. Щелкните правой кнопкой мыши столбец Inventory Item –> Детализация. Вы получите список всех запасов:

Ris. 19.7. Stolbets izvlechennyj iz tablitsy v spisok

Рис. 19.7. Столбец, извлеченный из таблицы в список

Обратите внимание на строку кода: = #»Измененный тип»[Inventory Item]. В общем виде она может быть записана так = #Источник[Столбец]. Это шаблон языка M для извлечения всех значений столбца в список без использования команд пользовательского интерфейса. Запомните на будущее.

Теперь на вкладке Средства для списков кликните Удалить дубликаты. У вас останется список уникальных элементов, которые вы можете использовать в другой функции. Переименуйте запрос – List_FromColumn. Главная –> Закрыть и загрузить в… –> Только создать подключение.

Список списков

Это может показаться странной концепцией, поэтому давайте рассмотрим пример. Предположим, что у вас есть ID менеджеров по продажам (от 1 до 4), а именно: Фреда, Джона, Джейн и Мэри. Было бы неплохо иметь возможность конвертировать эти значения в их имена, не создавая отдельную таблицу. Пройдите по меню Данные –> Получить данные –> Из других источников –> Пустой запрос. В строке формул создайте список с нуля:

= {{1, "Фред"}, {2, "Джон"}, {3, "Джейн"}, {4, "Мэри"}}

Обратите внимание, что здесь у вас есть четыре списка, которые, в свою очередь, объединены в основной список. Нажмите Enter:

Ris. 19.8. Spisok sostoyashhij iz spiskov

Рис. 19.8. Список, состоящий из списков

Предварительный просмотр первого списка показывает, что он содержит значения 1 и Fred. Нажмите кнопку В таблицу. Таблицу по-прежнему содержит списки, но появилась стрелка Развернуть:

Ris. 19.9. Spisok spiskov preobrazovannyj v tablitsu

Рис. 19.9. Список списков, преобразованный в таблицу

Нажмите на стрелку Развернуть. Вам будут предоставлены две опции:

Ris. 19.10. Mozhno razvernut v novye stroki ili izvlech znacheniya

Рис. 19.10. Можно развернуть в новые строки или извлечь значения

При извлечении значений Power Query запросит вид разделителя. Я ввел запятую:

Ris. 19.11. Rezultaty 1 razvorachivaniya v novye stroki 2 izvlecheniya znachenij

Рис. 19.11. Результаты: (1) разворачивания в новые строки, (2) извлечения значений

Переименуйте запрос List_of_Lists. Главная –> Закрыть и загрузить в… –> Только создать подключение.

При работе со списками необходимо учитывать два ключевых момента: списки могут содержать другие списки; развертывание списков списков не меняет их ориентацию.

Запись

Хотя список можно описать как один вертикальный столбец данных, на самом деле, запись является горизонтальным, многоколоночным аналогом списка. Запись может быть визуализирована как одна строка базы данных, содержащая всю соответствующую информацию, относящуюся к конкретному клиенту или транзакции. В Power Query записи могут отображаться в столбцах таблицы или в списках при получении данных. Они также могут быть созданы на лету, если это необходимо.

Синтаксис

Записи немного сложнее списков, так как они должны иметь какие-то значения, и вы должны определить имена столбцов, например:

=[Name="Ken Puls", Country="Canada", Languages Spoken=2]

Обратите внимание:

  • Каждая запись заключена в квадратные скобки;
  • Каждое поле записи (столбец) должно иметь определенное имя, за которым следует символ =.
  • Затем предоставляются данные для поля в кавычках, если это текстовые данные.
  • Пара имя поля + данные разделяются запятыми.

Имена полей (столбцов) не нуждаются в какой-либо пунктуации вокруг них, независимо от того, включают ли они пробелы или нет.

Что происходит, когда вам нужно создать несколько записей сразу? Вы создаете список из записей:

={[Name="Ken Puls", Country="Canada", Languages Spoken=2], [Name="Miguel Escobar", Country="Panama", Languages Spoken=2]}

Создание записи с нуля

Вернемся к примеру в разделе Список списков (рис. 19.11). Данные –> Получить данные –> Из других источников –> Пустой запрос. В строке формул создайте запись:

=[EmployeeID=1,EmployeeName=»Fred»]

Нажмите Enter.

Ris. 19.12. Vasha pervaya zapis

Рис. 19.12. Ваша первая запись

Как вы можете видеть, имена полей записи перечислены слева, а соответствующие данные –справа. Интересно, что данные расположены вертикально, а не горизонтально, как можно было бы ожидать. К этому нужно просто привыкнуть. Появилась контекстная вкладка Средства для записей –> Преобразовать. Правда, на ней лишь одна кнопка, а большинство кнопок на других вкладках ленты не активны.

Преобразование записи в таблицу

Поскольку очевидно, что с записью мало что можно сделать, преобразуем ее в таблицу:

Ris. 19.13. Odna zapis preobrazovannaya v tablitsu

Рис. 19.13. Одна запись, преобразованная в таблицу

Возможно, вы ожидали, что таблица будет содержать имена полей в качестве заголовков столбцов. Хотя это и не так, исправить ситуацию не сложно. Перейдите на вкладку Преобразование –> Транспонировать. Главная –> Использовать первую строку в качестве заголовков. Именно на это вы надеялись с самого начала?

Ris. 19.14. Zapis vyglyadit kak pravilnaya tablitsa

Рис. 19.14. Запись выглядит как правильная таблица

Сейчас это нормально, но что произойдет, если у вас есть множество записей, которые вы хотите преобразовать в таблицу? Завершите запрос, чтобы вы могли пойти дальше и узнать ответ на этот вопрос. Переименуйте запрос Record_Single. Главная –> Закрыть и загрузить в… –> Только создать подключение.

Создание нескольких записей с нуля

Если вам нужна таблица, которая охватывает всех сотрудников, создайте список записей. Данные –> Получить данные –> Из других источников –> Пустой запрос. В строке формул введите:

= {[EmployeeID=1,EmployeeName="Fred"], [EmployeeID=2,EmployeeName="John"], [EmployeeID=3,EmployeeName="Jane"], [EmployeeID=4,EmployeeName="Mary"]}

Обратите внимание, что вы используете синтаксис для одной записи, а записи разделили запятыми. Все записи взяли в фигурные скобки, показывая, что они элементы списка. Нажмите Enter. Формула возвращает список записей:

Ris. 19.15. Spisok zapisej s predvaritelnym prosmotrom

Рис. 19.15. Список записей с предварительным просмотром

Стрелка в правом верхнем углу (2) позволяет развернуть строку формул, чтобы показать сразу несколько строк.

Преобразование нескольких записей в таблицу

Теперь вы можете преобразовать этот список записей в таблицу. Пройдите по меню Средства для списков –> Преобразование –> В таблицу. Оставьте установки в окне В таблицу без изменений:

Ris. 19.16. Nastrojka parametrov preobrazovaniya spiska v tablitsu

Рис. 19.16. Настройка параметров преобразования списка в таблицу

Если в качестве разделите выбрать любой символ, преобразование в таблицу не удастся, и Power Query вернет ошибку:

Ris. 19.17. Oshibka preobrazovaniya v tablitsu pri popytke ukazat razdelit

Рис. 19.17. Ошибка преобразования в таблицу при попытке указать разделить

Итак, после преобразования в таблицу на основе установок, как на рис. 19.16, вы опять получаете не то, что могли бы ожидать:

Ris. 19.18. Tablitsa vklyuchaet spisok zapisej

Рис. 19.18. Таблица включает список записей

Кликните на значке Развернуть. Выберите все столбцы, снимите галочку Использовать исходное имя столбца как префикс:

Ris. 19.19. Nakonets to poluchen pravilnyj rezultat

Рис. 19.19. Наконец то получен правильный результат

Вы только что построили таблицу с нуля!

Теперь вы можете сохранить эту таблица, и даже объединить ее с другими запросами. Переименуйте запрос Table_From_Records. Главная –> Закрыть и загрузить в… –> Только создать подключение.

Создание записи из строки таблицы

Когда вы работали со списками, вы видели, как можно преобразовать столбец в список. Вы также можете преобразовать строку в запись. Для этого можно начать с нового запроса. В файле Excel перейдите на лист Sales и выберите любую ячейку в Таблице. Пройдите по меню Данные –> Из таблицы/диапазона. Чтобы извлечь первую запись, необходимо создать пустой шаг запроса. В области ПРИМЕНЕННЫЕ ШАГИ нажмите на первый шаг Источник (цифра 1 на рис. 19.20). Нажмите кнопку fx слева от строки формул (2):

Ris. 19.20. Sozdanie pustogo shaga zaprosa

Рис. 19.20. Создание пустого шага запроса

Появится окно предупреждения о вставке шага. Подтвердите. В строке формул появится заготовка:

=Источник

Измените эту формулу на =Источник{0}

Ris. 19.21. Iz tablitsy vydelena pervaya zapis

Рис.19.21. Из таблицы выделена первая запись

При первоначальном импорте Таблицы Excel исходный шаг возвращает список записей. Поскольку для Power Query базовым значением является ноль, формула =Источник{0} возвращает первое значение в списке.

Вы можете извлечь только одно поле первой записи, например, цену. Измените этот шаг запроса на: =Источник{0}[Price]

Ris. 19.22. Izvlechenie tseny iz pervoj zapisi

Рис. 19.22. Извлечение цены из первой записи

Это очень важно, и пригодится во многих ситуациях, например, при управлении фильтрами (подробнее см. главу 20).

Завершите запрос. Переименуйте его Record_From_Table. Главная –> Закрыть и загрузить в… –> Только создать подключение.

Создание записей из каждой строки таблицы

Чтобы преобразовать все строки таблицы запроса в записи, вам нужно использовать небольшой трюк. В файле Excel перейдите на лист Sales и выберите любую ячейку в Таблице. Пройдите по меню Данные –> Из таблицы/диапазона. Таблица целиком загрузится в Power Query. Для создания записей вам нужен индекс каждой строки. Перейдите на вкладку Добавление столбца –> Столбец индекса. Переименуйте этот шаг (а не столбец) в области ПРИМЕНЕННЫЕ ШАГИ – AddedIndex (без пробела):

Ris. 19.23. Dobavlen stolbets indeksa i pereimenovan shag

Рис. 19.23. Добавлен столбец индекса и переименован шаг

Теперь вы можете создать пользовательский столбец для преобразования строк в записи. Хитрость заключается в создании формулы, использующей индекс. столбца индекса, так как теперь у вас есть значение, необходимое для извлечения записей. Зачем тебе этот трюк? Вы не собираетесь работать на текущей строке, а скорее на выходе шага AddedIndex. Таким образом, вместо получения определенного значения (например, первой строки), вы можете динамически подавать его в запрос, чтобы получить каждую строку. Выполнить следующие действия:

Перейдите на вкладку Добавление столбца –> Настраиваемый столбец. Назовите его Records. Используйте формулу: =AddedIndex{[Индекс]}.

Ris. 19.24. Stolbets zapisej

Рис. 19.24. Столбец записей

Строго говоря, переименовывать шаг, на котором был добавлен столбец индекса, было необязательным. Просто отсутствие пробела в имени шага упрощает синтаксис формулы. Удалите все остальные столбцы, оставив только столбец записей. Переименовать запрос Records_From_Table. Главная –> Закрыть и загрузить в… –> Только создать подключение.

Значение (Value)

При работе с базами данных иногда отображаются столбцы, содержащие Значение:

Ris. 19.25. Neulovimyj obekt Znachenie

Рис. 19.25. Неуловимый объект Значение

Чтобы обнаружить этот объект, необходимо работать с базой данных, в которой между таблицами установлены связи. Значение – это способ, которым база данных возвращает связанную запись. Т.е., запись хранящуюся в другой таблице, а не в той, с которой вы сейчас работаете. Таблица на рис. 19.25 расположена в базе данных Adventureworks2012, к которой вы подключились в главе 8. Направление связи определяет, что возвращается в связанный столбец при работе с базой данных. Если вы находитесь в таблице фактов, и ссылка идет в таблицу измерений, вы получите значение (запись). Если вы находитесь в таблице измерений и ссылка идет в таблицу фактов, вы получите таблицу (подробнее см. Power Pivot. Мышление в нескольких таблицах).

Двоичные данные

Двоичные данные являются файлами. Некоторые из них можно объединять и читать с помощью функции Csv.Document(). В тоже время двоичные книги Excel нельзя объединять, а для чтения данных используется функция Excel.Workbook(). Процесс извлечения данных подробно рассмотрен ранее в главе 3 и главе 4. Мы упоминаем их здесь, поскольку они являются объектом Power Query.

Ошибки

Существует два типа сообщений об ошибках: ошибки уровня шага и ошибки уровня строки.

Ошибки на уровне строк обычно возникают при попытке преобразовать данные в неверный тип или при попытке оперировать данными до их преобразования в правильный тип. Вы уже видели несколько примеров таких ошибок ранее:

Ris. 19.26. Oshibka urovnya stroki vyzvannaya popytkoj preobrazovat strany v tip dannyh daty

Рис. 19.26. Ошибка уровня строки, вызванная попыткой преобразовать страны в тип данных даты

Эти ошибки, как правило, не являются блокирующими, и они даже могут быть полезны при очистке данных, так как их можно обрабатывать двумя способами:

  • Использовать в качестве фильтров для хранения / удаления строк
  • Заменить другими данными, используя, например, команду Преобразование –> Замена значений –> Заменить ошибки.

Несмотря на то, что в Power Query нет механизма отладки, эти ошибки, как правило, идентифицируются и часто (хотя и не всегда) связаны с неверными типами данных.

Ошибки уровня шага

Эти ошибки серьезнее. Такие сообщения блокируют запрос, и в окне вывода ничего не отображается, кроме ошибки:

Ris. 19.27. Sintaksicheskaya oshibka vyzvannaya otsutstviem zakryvayushhej skobki v kontse formuly

Рис. 19.27. Синтаксическая ошибка, вызванная отсутствием закрывающей скобки в конце формулы

Ris. 19.28. Vyzyvaetsya funktsiya SQL.Database pravilno Sql.Database

Рис. 19.28. Вызывается функция SQL.Database; правильно Sql.Database

К сожалению, средства отладки Power Query особенно слабы в следующей ситуации:

Ris. 19.29. Sintaksicheskaya oshibka vyzvannaya otsutstviem no soobshhayushhaya ob ozhidanii zapyatoj

Рис. 19.29. Синтаксическая ошибка, вызванная отсутствием }, но сообщающая об ожидании запятой

В самом конце строки находится полезный символ ^, который указывает, где Power Query считает, что нужна запятая. Однако, проблема в том, что не хватает фигурной скобки для закрытия списка "YTD Sales" в месте, на которое указывает красная стрелка. Жаль, что в редакторе нет встроенной подсветки ошибок. Но Power Query часто обновляется, и мы надеемся увидеть прогресс в этой области в будущем. Сейчас же, отладка заключается в просмотре строки, открывающих и закрывающих символов, запятых и т.п.

Функции

Функции используются в двух местах:

  • Они могут находиться внутри базы данных, где они указывают на хранимую процедуру.
  • Они могут быть возвращены в списке Power Query.

Об использовании и вызове функций мы расскажем позже. Сейчас же покажем один трюк, который покажет, как функции проявляются, а также откроет список функций Power Query. Данные –> Получить данные –> Из других источников –> Пустой запрос. В строке формул введите: =#shared. Появится список записей. Перейдите на вкладку Средства для записей –> Преобразовать –> В таблицу. Power Query генерирует таблицу всех элементов Power Query в текущей книге, а также список всех функций, включенных в продукт.

Ris. 19.30. Tablitsa funktsij

Рис. 19.30. Таблица функций

Вы можете получить доступ к документации для любой функции из этого списка, если кликните на слово Function, например:

Ris. 19.31. Sintaksis funktsii Table.Last

Рис. 19.31. Синтаксис функции Table.Last

Более того, на переднем плане появится диалоговое окно вызова функции:

Ris. 19.32. Dialogovoe okno funktsii Table.Last

Рис. 19.32. Диалоговое окно функции Table.Last

Здесь можно протестировать функцию, а при нажатии кнопки Отмена окно исчезает.

Вам не обязательно создавать пустой запрос для вызова описания функции Power Query. Вы также можете в любой момент, когда вам это потребуется, кликнуть на fx слева от строки формул, чтобы добавить новый шаг. Замените код в новом шаге на =#shared. Нажмите Enter. Преобразуйте записи в таблицу. Можете использовать фильтр, чтобы найти функцию по имени. Кликните на слово Function напротив той функции, которую хотите изучить. Затем вы можете вернуться к другим шагам и продолжить формирование запроса. После того, как информация об этой или иной функции более не требуется, можете удалить шаги =#shared.


Прокомментировать