Как ссылаться на отдельную
ячейку таблицы в Power Query?
Крис Вебб (Chris Webb) — независимый эксперт, консультант по технологиям Analysis Services, MDX, Power Pivot, DAX, Power Query и Power BI. Его блог — это кладезь информации на тему перечисленных технологий. Вот уже более 10 лет он пишет про BI-решения от Microsoft. Количество его статей перевалило за 1000! Также Крис выступает на большом количестве различных конференций вроде SQLBits, PASS Summit, PASS BA Conference, SQL Saturdays и участвует в различных сообществах.
Крис любезно разрешил нам переводить его статьи на русский язык. И мы представляем первую статью.
Данная статья относится к надстройке Power Query в Excel 2010/2013, к группе Скачать и преобразовать вкладки Данные в Excel 2016, и к экрану Get Data в Power BI Desktop. Термин «Power Query» используется в том же контексте, что и в предыдущих статьях.
Иногда, при работе с данными таблиц Power Query возникает необходимость получить значение из одной ячейки таблицы. В статье показано, как это сделать через Редактор запросов и Редактор кода. Также подробно обсуждаются дополнительные возможности, доступные в последнем. Кстати, эта тема частично раскрыта в главе М книги Power Query за авторством Криса Вебба, но к настоящему моменту она несколько устарела.
Ссылка на значение ячейки в Редакторе запросов
Предположим, что источник данных – таблица Excel, подобная такой:
Импортируем её в Power Query. Чтобы получить данные из ячейки второго столбца второй строки щелкаем по ней ПКМ и выбираем пункт Детализация углублением:
Готово, мы получили 5 в ответе:
Обратите внимание, что это значение 5 не то же самое, что и в ячейке таблицы. Запрос Power Query может вернуть любой тип данных. В данном случае будет возвращено значение целочисленного типа, а не значение типа таблица. Если вывести результаты этого запроса на лист Excel, то мы увидим отформатированную таблицу. Но если использовать результаты этого запроса в качестве входных данных для другого (например, как фильтр в SQL-запросе), то иметь данные целочисленного типа удобнее, чем таблицу из одной строки и столбца.
Ссылка на значение ячейки в Редакторе кода
Вот код для действий на скриншотах выше. Вероятно, вы догадались как он работает.
let
Источник = Excel.CurrentWorkbook(){[Name="Таблица1"]}[Content],
"Измененный тип" = Table.TransformColumnTypes(
Источник,
{{"poleA", Int64.Type},
{"poleB", Int64.Type},
{"poleC", Int64.Type}}
),
poleB = #"Измененный тип"{1}[poleB] in poleB
Рассмотрим эти три шага: – Источник – получаем данные из таблицы Excel
– «Измененный тип» – устанавливаем тип данных для трех столбцов в целочисленный
– poleB – возвращает значение ячейки из второй строки столбца В (строки начинаются с 0).
Код позволяет ссылаться на отдельные ячейки таблицы, используя систему координат из имени столбца и номера строки, еще раз повторим, что нумерация строк начинается с нуля. Поэтому выражение:
«Измененный тип»{1}[poleB]
вернёт значение ячейки из второй строки столбца poleB., т.е 5. Аналогично, выражение
«Измененный тип»{0}[poleC]
вернёт значение 3, соответствующее первой строке столбца poleC.
Отметим, что ссылки на столбец и строку могут идти в любом порядке, и выражение #»Измененный тип»{1}[poleB] вернёт то же самое, что и
«Измененный тип»[poleB]{1}
Но в некоторых случаях, как вы скоро увидите, порядок строк и столбцов может быть важен.
Ссылка на отсутствующие строку или столбец
Что произойдёт если использовать ссылку на отсутствующий столбец и/или строку? Конечно, мы получим сообщение об ошибке. Вернёмся к нашему примеру и запишем:
«Измененный тип»{4)[poleB]
и
«Измененный тип»{1)[poleD]
Оба выражения вернут ошибку, т.к. в таблице нет 5-ой строки и столбца poleD.
Однако вместо ошибки можно получить значение NULL, используя оператор «?» после ссылки. Например, выражение
«Измененный тип»{1}[poleD]?
вернёт null вместо сообщения об ошибке:
Но будьте осторожны! Выражение
«Измененный тип»{4}?[poleB]
по-прежнему возвращает ошибку, но не потому что отсутствует пятая строка, а потому что ссылка на пятую строку вернёт null, а у него нет столбца poleB.
Решением может быть изменение порядка ссылок:
«Измененный тип»[poleB]{4}?
или применение оператора «?» для обеих ссылок:
«Измененный тип»{4}?[poleB]?
К сожалению, применение оператора «?» не позволит избежать ошибок, если использовать отрицательные значения в ссылках строк.
Эффект первичного ключа
Знаете ли вы, что таблицы Power Query могут содержать первичный ключ (т. е. один или несколько столбцов, значения которых уникально идентифицируют каждую строку), определяемый самой надстройкой? Нет? Неудивительно, это вовсе не очевидно из пользовательского интерфейса. Однако, существует несколько ситуаций, когда Power Query определяет первичный ключ для таблицы, в том числе:
- Когда импортируются данные из таблицы реляционной базы данных, подобной SQL Server, и таблица уже имеет первичный ключ.
- Когда используется кнопка Удалить повторения чтобы убрать повторяющиеся значения из столбца или столбцов, скрытно вызывается функция Table.Distinct()
- Когда к таблице применяется функция Table.AddKey()
Наличие первичного ключа влияет на работу функционала пункта Детализация углублением, и даёт другой способ ссылок на отдельные ячейки.
Рассмотрим следующую таблицу Excel, в основном такую же, что приводилась выше, но с новым столбцом, который однозначно идентифицирует каждую строку.
Если вы загрузите таблицу в Power Query, щелкните ПКМ по заголовку столбца poleKey и выберете пункт Удалить повторения, то установите этот столбец первичным ключом.
(Кстати, можно использовать функцию Table.Keys(), чтобы увидеть, какие ключи определены для таблицы Power Query).
Убрав дубликаты, повторим действия с пунктом Детализация углублением. Получим следующее:
let
Источник = Excel.CurrentWorkbook(){[Name="Таблица4"]}[Content],
"Измененный тип" = Table.TransformColumnTypes(
Источник,
{{"poleA", Int64.Type},
{"poleB", Int64.Type},
{"poleC", Int64.Type}}),
"Удаленные дубликаты" = Table.Distinct(
"Измененный тип",
{"poleKey"}),
"Строка 2" = "Удаленные дубликаты"{[poleKey="Строка 2"]}[poleB]
in
"Строка 2
Обратите внимание на последний шаг, это важно! Вместо ссылки по номеру строки идёт ссылка по первичному ключу.
«Удаленные дубликаты»{[poleKey=»Строка 2»]}[poleB]
Можно продолжать использовать нотацию на основе номера строки, но если таблица имеет столбец с первичными ключами, то можно использовать нотацию с первичным ключом.
Замечания напоследок о производительности
Возможность ссылок на отдельные значения невероятно полезна в определенных типах запросов и расчётов. Однако стоит помнить, что зачастую существует несколько способов решения задачи, и не все они одинаково хороши.
Одно очевидное применение техники описанной в статье – запись предыдущих вычислений там, где необходимы ссылки на значения предыдущей строки таблицы. Но по опыту известно, что запись расчетов, использующих ссылки на строку/столбец не даёт осуществлять Query Folding («квэри фолдинг» — термин, означающий передачу тяжелых операций по обработке запросов на сторону сервера при работе с совместимой базой данных, на текущий момент это MS SQl, прим. пер.), и ведет к снижению производительности.
Возможно, альтернативные подходы (некоторые описаны в статьях Implementing Common Calculations In Power Query и Join Conditions in Power Query, Part 2: Events-In-Progress, Performance and Query Folding) будут лучшим выходом.
Нет каких-то общих правил, которые можно посоветовать, вы должны сами попробовать разные способы.
Эта статья – перевод моего первого поста в этом блоге, который был опубликован 5 ноября 2015 года на английском языке. К моему удивлению, этот пост – самый популярный, за это время он набрал почти 21000 просмотров. С небольшими стилистическими правками публикую его на русском языке. В переводе помогал мой сын Дмитрий, за что ему отдельное спасибо.
Power Query – это мощный инструмент, способный на большее, чем просто брать данные из источника и переносить их в таблицу или Power Pivot. Данные можно очищать и преобразовывать множеством способов, но есть некоторые действия, привычные для Excel, которые не так удобно делать в Power Query.
Например, что, если мне нужна относительная ссылка на конкретную ячейку в таблице Power Query – значение из определённой строки в определённом столбце? Или ссылка на значение в определённом столбце на четыре строки выше? В Excel очевидно, как это сделать: нужно просто указать на нужное значение мышкой, убедиться, что из ссылки к строке убран знак “$” (знак абсолютной ссылки), и всё. Но в Power Query я не могу так просто это сделать.
Но всё же решение, хотя и непрямое, существует.
Прежде всего давайте выясним, как можно получить доступ к конкретному значению из таблицы Power Query.
Простейший способ понять адресацию в Power Query, по-моему, анализировать код шагов.
Абсолютные ссылки на строки
Допустим, у нас есть простая таблица из двух столбцов: даты (Date) и количества (Amount). В ней пять строк, и в первом столбце стоят, как ни странно, даты, во втором – какие-то значения:
Исходные данные
Мы хотим получить значение из ячейки B4, а именно 120.
В Excel это просто: мы просто пишем ссылку вроде =B4, или =R4C2 в стиле R1C1.
Можно ли использовать этот стиль ссылок (R1C1) в Power Query? Да.
Загрузите эту таблицу в Power Query, щёлкните правой мышкой по нужному значению и выберите “drill to details”. Отлично, мы получили 120.
Теперь взглянем на код.
let Source = Excel.CurrentWorkbook(){[Name=«Tab_1»]}[Content], Amount = Source{2}[Amount] in Amount |
В третьей строке кода мы видим искомую ссылку. Заметьте, что мы ссылаемся на предыдущий шаг (как обычно), затем пишем {2} и затем название столбца [Amount].
Важно: строки и списки в Power Query нумеруются с нуля: первая позиция в списке всегда имеет номер 0, то же самое касается номеров строк в таблице. Поэтому, запрашивая в Power Query значение из третьей строки, мы должны использовать число 2 для обозначения строки.
Эта формула расшифровывается так: дай мне значение из поля [Amount] в строке с индексом 2 таблицы Source. Иными словами, формула ищет определённый номер записи в таблице и затем возвращает значение определённого поля из этой записи.
Формула, полученная нами из редактора, фактически использует два последовательных подхода: выражение:
и выражение
Name{Argument}
Record[Field].
Синтаксис
имеет несколько реализаций:
Name{Argument}
- если
– это список (list), а
Name
– число (number), выражение возвращает элемент с соответствующим номером из списка Name;
Argument - если
– это таблица (table), а
Name
– число (number), выражение возвращает строку с соответствующим номером из таблицы Name;
Argument - если
– это таблица (table), а
Name
– запись (record), выражение возвращает уникальную строку из таблицы
Argument
, в которой значения полей соответствуют значениям аналогичных полей записи
Name
.
Argument
Последний вариант даёт представить множество возможностей использования, но сейчас мы вернемся прямо к нашему вопросу: абсолютные и относительные ссылки на одиночное значение.
Выражение
Record[Field] имеет почти такой же синтаксис: оно ищет поле в записи по имени поля. Если в записи нет указанного поля, код выдаёт ошибку.
Взгляните снова на нашу формулу: сперва мы получаем строку (запись) из таблицы Source с номером 2:
Затем из этой записи мы получаем поле [Amount] (строка таблицы – это запись с именами столбцов в качестве имён полей):
Выглядит просто, да?
Но погодите, если мы запросим в Power Query одиночный столбец из таблицы, мы получим как раз нужный список:
Так что, если нам нужно конкретное значение из этого списка (см. первый пункт в описании синтаксиса
выше), мы просто добавляем в фигурных скобках номер значения после имени списка:
Name{Argument}
Эти два шага можно сократить в один:
MyValue = Source[Amount]{2} |
и получить искомое значение, 120.
Таким образом, у нас фактически есть два возможных способа обратиться к одиночному значению в таблице Power Query.
Давайте сравним два способа адресации:
- Обратиться к определённой записи в таблице и получить определённое поле из этой записи:
MyValue = Source{2}[Amount]
- Получить список из столбца таблицы и получить значение по определённому номеру в этом списке:
MyValue = Source[Amount]{2}
Они выглядят очень похоже, и может показаться, что нет разницы, в каком порядке ставить название столбца и порядковый номер. На самом деле это два разных подхода, и это нужно запомнить, чтобы использовать в будущем.
Но в любом случае оба подхода дают нам ключ к любым ссылкам на строки в таблицах Power Query.
Относительные ссылки на строки
В таблице-образце находятся данные, похожие на остатки на счёте. Предположим, нам нужно добавить столбец, вычисляющий и показывающий изменение значения на счёте. Для этого нужно получить значение из предыдущей строки и сравнить его со значением в текущей строке.
Но в предыдущих примерах мы видели, что ссылка на позицию и столбец зашиты внутрь формулы. Значит, нам нужно найти способ преобразовать номера строк в относительные ссылки.
И здесь нам (вновь) приходит на помощь Excel. Что бы мы сделали в Excel, чтобы произвести такое вычисление? В простом случае мы просто помещаем в ячейку C3 формулу
=B3—B2 и растягиваем её на столбец. Но, если мы запишем эту формулу в стиле R1C1, то получим следующее:
=RC[—1]—R[—1]C[—1]
Это значит: возьми значение из этой строки и столбца на один левее и вычти из него значение из строки на одну выше и столбца на один левее. В Power Query в большинстве случаев мы будем работать с данными из известных столбцов, так что давайте представим, что мы можем опустить часть, относящуюся к столбцу, и ссылаться только на строку, в стиле R1:
=R–R[—1]
Итак, вот оно. Нам нужно получить номер текущей строки и вычислить номер предыдущей, чтобы использовать формулу такого рода:
= Source{current_row_number}[Amount] — Source{current_row_number—1}[Amount] |
или
= Source[Amount]{current_row_number} — Source[Amount]{current_row_number—1} |
Итак, можно ли получить номер строки в Power Query? Да, с помощью специального столбца индексов Index.
Столбец индексов генерирует список целочисленных значений, начинающихся с N, с шагом S для каждой строки таблицы. Интерфейс Power Query позволяет выбрать один из двух наиболее популярных вариантов столбцов индексов: “From 0” (с нуля, по умолчанию) или “From 1” (с единицы, оба с шагом 1) – или создать собственный список со своими значениями параметров Start (начальное значение) и Step (шаг).
Давайте добавим столбец индексов, начинающихся с нуля, после шага Source в Power Query:
#»Added index» = Table.AddIndexColumn(Source, «Index», 0, 1) |
Теперь у нас есть всё, что нужно: мы знаем название столбца и можем получить из столбца индексов номер строки. Давайте переименуем предыдущий шаг в
AddInd для ускорения написания и новым шагом добавим собственный вычисляемый столбец, вводя следующую формулу в диалоговое окно:
=AddInd[Amount]{[Index]}—AddInd[Amount]{[Index]—1} |
Таким образом, полная формула этого шага выглядит так:
= Table.AddColumn(AddInd, «Custom», each AddInd[Amount]{[Index]}—AddInd[Amount]{[Index]—1}) |
Мы только что сделали следующее: в каждой строке таблицы мы ссылаемся на значение из столбца
Index как аргумент для выражения
.
Name{Argument}
В этом примере я использовал тип ссылки по положению в списке (см. п.1), а не по записи в таблице. Посмотрите на результат в окне предпросмотра Power Query:
Здесь можно увидеть, как работают относительные ссылки на строки в Power Query
У нас есть искомый список изменений значений из столбца
, но с ошибкой (error) в первой строке. Очевидно, ведь строки с номером (0-1)=-1 нет. Если бы мы использовали ссылку больше последнего номера строки, то нужно было бы использовать “?” (вопросительный знак) после ссылки на номер строки. Это называется “факультативный выбор объекта”.
Amount
Давайте посмотрим, как это работает. Вернёмся на шаг назад и добавим ещё один столбец со следующей формулой:
=AddInd[Amount]{[Index]+1}? |
Мы получим вот это:
“Факультативный выбор объекта” возвращает null, если выйти за границу количества строк
т.е. ссылка на несуществующий номер в списке была заменена значением null. Но, как я уже говорил, это работает только с номерами не меньше количества объектов в списке (или записей в таблице). Для отрицательных номеров формула выдаёт ошибку.
Теперь давайте уберём этот шаг и вернёмся к добавленному ранее столбцу с ошибкой в первой строке.
Что можно сделать с этой ошибкой? Мы можем добавить ещё один шаг с помощью UI: замену ошибок. Просто выбираем наш столбец Custom, затем на вкладке Transform выполняем Replace errors…, и вводим в диалоговое окно значение 0. Либо просто добавляем эту формулу в редактор:
RemErrs = Table.ReplaceErrorValues(AddCust1, {{«Custom», 0}}) |
Отлично, мы получили, что хотели:
Теперь мы заменили ошибки определёнными фиксированными значениями
Если мы хотим заменить ошибки не точными значениями, а другими вычислениями или функциями, лучше использовать конструкцию
, работающую как функция IFERROR (ЕСЛИОШИБКА)в Excel. Нужно просто исправить предыдущий шаг (на котором мы добавляли первый вычисляемый столбец). Щёлкните шестерёнку (“gear”) рядом с именем шага и замените формулу следующей:
try - otherwise
try AddInd[Amount]{[Index]}—AddInd[Amount]{[Index]—1} otherwise 0 |
или внесите необходимые исправления прямо в строке формул. После оператора
может идти любое выражение, например, вы можете использовать собственную функцию, ввести текст или вернуть
otherwise
.
null
Теперь мы заменили ошибки с помощью выражения “try-otherwise”
Эй, да это же всё. Поздравляю, теперь мы знаем, как создавать абсолютные и относительные ссылки в таблицах Power Query.
Этот приём полезен во многих случаях, в основном при преобразовании и очистке сырых данных.
Но ОСТОРОЖНО: использование относительных ссылок в таблицах с большим количеством данных может поглощать очень много ресурсов и увеличивать время обновления запроса.
Вы можете загрузить книгу-образец, чтобы посмотреть, как это работает, и опробовать все приёмы из этой записи.
А как насчёт относительных ссылок по столбцу? Чуть сложнее и реже встречается, но мы можем сделать и это. В следующий раз.
Если вы хотите почитать больше о продвинутых преобразованиях и моделировании данных в Power Query, я рекомендую следующие книги:
Follow me:
Share this:
Создадим лист с условием при помощи List.Transform. Найдем среднее значение в листе/списке при помощи простой функции List.Average.
В этом уроке мы изучим ссылки на Record и функции Record.
Если вы уже начали использовать в работе инструменты бесплатной надстройки Power Query в Microsoft Excel, то очень скоро столкнётесь с одной узкоспециальной, но весьма частой и надоедливой проблемой, связанной с постоянно ломающимися ссылками на исходные данные. Суть проблемы в том, что если в своём запросе вы ссылаетесь на внешние файлы или папки, то Power Query жёстко прописывает абсолютный путь к ним в тексте запроса. У вас на компьютере всё работает прекрасно, но если вы решите отправить файл с запросом своим коллегам, то их ждёт разочарование, т.к. у них на компьютере путь к исходным данным уже другой, и наш запрос работать не будет.
Что же сделать в такой ситуации? Давайте рассмотрим этот случай подробнее на следующем примере.
Постановка задачи
Предположим, что у нас в папке E:Отчеты по продажам лежит файл Топ-100 товаров.xls, представляющий собой выгрузку из нашей корпоративной базы данных или ERP-системы (1С, SAP и т.п.) Этот файл содержит информацию о наиболее популярных товарных позициях и выглядит внутри примерно так:
С ходу, наверное, понятно, что работать с ним в Excel в таком виде практически невозможно: будут мешать пустые строки через одну с данными, объединенные ячейки, лишние столбцы, многоуровневая шапка и т.д.
Поэтому рядом с этим файлом в той же папке мы создаём ещё один новый файл Обработчик.xlsx, в котором создадим запрос Power Query, который будет загружать страшненькие данные из исходного файла-выгрузки Топ-100 товаров.xls, и приводить их в порядок:
Создаем запрос к внешнему файлу
Открыв файл Обработчик.xlsx, выберем на вкладке Данные команду Получить данные — Из файла — Из книги Excel (Data — Get Data — From file — From Excel), затем укажем местоположение исходного файла и нужный нам лист. Выбранные данные загрузятся в редактор Power Query:
Приведём их в нормальный вид:
- Удалим пустые строки через Главная — Удалить строки — Удалить пустые строки (Home — Remove Rows — Remove Empty Rows).
- Удалим ненужные 4 верхних строки через Главная — Удалить строки — Удалить верхние строки (Home — Remove Rows — Remove Top Rows).
- Поднимем первую строку в шапку таблицы кнопкой Использовать первую строку в качестве заголовков на вкладке Главная (Home — Use first row as header).
- Отделим пятизначный артикул от названия товара во втором столбце, используя команду Разделить столбец на вкладке Преобразование (Transform — Split Column).
- Удалим ненужные столбцы и переименуем заголовки оставшихся для лучшей наглядности.
В итоге у нас должна получиться следующая, гораздо более приятная, картина:
Осталось эту облагороженную таблицу выгрузить обратно на лист в наш файл Обработчик.xlsx командой Закрыть и загрузить (Home — Close&Load) на вкладке Главная:
Находим путь к файлу в запросе
Теперь давайте посмотрим как выглядит наш запрос «под капотом», на встроенном в Power Query внутреннем языке с лаконичным названием «М». Для этого вернемся в наш запрос двойным щелчком по нему в правой панели Запросы и подключения и на вкладке Просмотр выберем Расширенный редактор (View — Advanced Editor):
В открывшемся окне во второй строке сразу же обнаруживается жёстко прописанный путь к нашему исходному файлу выгрузки. Если мы сможем заменить эту текстовую строку на параметр, переменную или ссылку на ячейку листа Excel, где этот путь будет заранее прописан, то мы сможем впоследствии легко его менять.
Добавляем умную таблицу с путём к файлу
Закроем пока Power Query и вернёмся в наш файл Обработчик.xlsx. Добавим новый пустой лист и сделаем на нём маленькую «умную» таблицу, в единственной ячейке которой будет записан полный путь к нашему файлу исходных данных:
Для создания «умной» таблицы из обычного диапазона можно использовать сочетание клавиш Ctrl+T или кнопку Форматировать как таблицу на вкладке Главная (Home — Format as Table). Заголовок столбца (ячейка А1) может быть совершенно любым. Также обратите внимание, что для понятности я дал таблице имя Параметры на вкладке Конструктор (Design).
Скопировать из Проводника путь или даже ввести его вручную не представляет, конечно, особой сложности, но лучше всего минимизировать человеческий фактор и определять путь, по возможности, автоматически. Это можно реализовать с помощью стандартной функции рабочего листа Excel ЯЧЕЙКА (CELL), которая умеет выдавать кучу полезной информации об указанной в качестве аргумента ячейке — в том числе и путь к текущему файлу:
Если предположить, что файл с исходными данными всегда лежит в той же папке, что и наш Обработчик, то путь, который нам нужен можно сформировать следующей формулой:
=ЛЕВСИМВ(ЯЧЕЙКА(«имяфайла»);НАЙТИ(«[«;ЯЧЕЙКА(«имяфайла»))-1)&»Топ-100 товаров.xls»
или в английской версии:
=LEFT(CELL(«filename»);FIND(«[«;CELL(«filename»))-1)&»Топ-100 товаров.xls»
… где функция ЛЕВСИМВ (LEFT) берёт из полной ссылки кусок текста до открывающей квадратной скобки (т.е. путь к текущей папке), а затем к нему приклеивается имя и расширение нашего исходного файла с данными.
Параметризуем путь в запросе
Остался последний и самый главный штрих — прописать в запросе путь к исходному файлу Топ-100 товаров.xls, сославшись на ячейку А2 нашей созданной «умной» таблицы Параметры.
Для этого вернемся в запрос Power Query и ещё раз откроем Расширенный редактор на вкладке Просмотр (View — Advanced Editor). Вместо текстовой строки-пути в кавычках «E:Отчеты по продажамТоп-100 товаров.xlsx» введём туда вот такую конструкцию:
Excel.CurrentWorkbook(){[Name=»Параметры»]}[Content]{0}[Путь к исходным данным]
Давайте разберемся из чего она состоит:
- Excel.CurrentWorkbook() — это функция языка М для обращения к содержимому текущего файла
- {[Name=»Параметры»]}[Content] — это уточняющий параметр к предыдущей функции, указывающий, что мы хотим получить содержимое «умной» таблицы Параметры
- [Путь к исходным данным] — это имя столбца в таблице Параметры, к которому мы обращаемся
- {0} — это номер строки в таблице Параметры, из которой мы хотим взять данные. Шапка — не в счет и нумерация начинается от нуля, а не от единицы.
Вот и всё, собственно.
Осталось нажать на Готово и проверить как работает наш запрос. Теперь при пересылке всей папки с обоими файлами внутри на другой ПК запрос будет сохранять работоспособность и определять путь к данным автоматически.
Ссылки по теме
- Что такое Power Query и зачем он нужен при работе в Microsoft Excel
- Как импортировать в Power Query плавающий фрагмент текста
- Редизайн двумерной кросс-таблицы в плоскую с помощью Power Query
I couldn’t get the => syntax to work so what I ended up with is as below. Here I’m using a single table to store all the values but you could also use named ranges and stick to using [content]{0}[Column1] for each one.
let
SITE_URL_VALUE = Excel.CurrentWorkbook(){[Name="SETTINGS_TABLE"]}[Content]{0}[Value],
FOLDER_PATH_VALUE = Excel.CurrentWorkbook(){[Name="SETTINGS_TABLE"]}[Content]{1}[Value],
FILENAME_VALUE = Excel.CurrentWorkbook(){[Name="SETTINGS_TABLE"]}[Content]{2}[Value],
Source = SharePoint.Files(SITE_URL_VALUE, [ApiVersion = 15]),
#"Import Filename" = Source{[Name=FILENAME_VALUE, #"Folder Path"=FOLDER_PATH_VALUE]}[Content],
#"Import Workbook" = Excel.Workbook(#"Import Filename"),
#"Import Table" = #"Import Workbook"{[Item="ACTIVITY_PLAN_TABLE",Kind="Table"]}[Data],
#"Removed Other Columns" = Table.SelectColumns(#"Import Table",{"Work Order", "MAT", "Exp Hours", "OSC", "Team", "Plant", "Area", "Hours", "Complete", "Plan Status"}),
#"Changed Type" = Table.TransformColumnTypes(#"Removed Other Columns",{{"Work Order", type text}, {"MAT", type text}})
in
#"Changed Type"
Хитрости »
30 Ноябрь 2016 47182 просмотров
В большинстве случаев создание запросов PowerQuery создается на основании файлов Excel, отличных от того файла, в котором сам запрос. Как пример — одна из статей на этом сайте: План-фактный анализ в Excel при помощи Power Query. Там идет обращение к некоторым вспомогательным файлам с данными и запрос ко всем файлам определенной папки. Т.е. мы можем знать только папку относительно файла с самим запросом и имена некоторых вспомогательных таблиц. И здесь как раз возникает нюанс: если впоследствии переместить или переслать файл с запросом (или даже полностью всю модель данных со всеми файлами) — то придется для каждого запроса к отдельному файлу менять источник. Это можно сделать либо через Параметры источника данных самого запроса:
- Для пользователей Excel 2010-2013:
Перейти на вкладку Power Query -группа Настройки(Options) —Параметры источника данных(Data Source Settings) - для пользователей 2016 и выше:
Перейти на вкладку Данные(Data) —Создать запрос(New Query) —Параметры источника данных(Data Source Settings)
либо изменив текст каждого запроса в редакторе запросов, изменив там строку источника:
И в том и в другом случае после смены каждого источника придется ждать обновления запросов. Как ни странно, но стандартно, без танцев с бубном, сделать некий относительный путь(указав лишь часть пути, как это делается в web-программировании) к источнику данных нельзя.
Как же вообще сделать возможность обновления источника данных при смене расположения файлов?
Есть два варианта:
Вариант 1
Не совсем автоматический, но способный чуть облегчить жизнь — использовать возможность создания параметров для запросов. Параметр — это некая именованная константа, которая может быть как одним значением(число, текст, дата и т.д.), так и целой таблицей(возможно впоследствии добавят возможность создания вычисляемых параметров, но на момент написания статьи это не поддерживалось). В нашем случае это будет одно значение — путь к основной папке. Чтобы создать новый параметр необходимо перейти в редактор запросов(выбрать любой запрос в книге -Правая кнопка мыши -Изменить) и на вкладке Главная выбрать Управление параметрами —Создать параметр.
В появившемся окне задаем необходимые значения:
- Обязательно — читать как Обязательный, если флажок установлен и Необязательный, если флажок снят. Отвечает за необходимость указывать значение. Если флажок установлен — то параметр не будет создан/изменен, пока мы не укажем Текущее значение. Если флажок снят — то значение параметра допускается оставить пустым.
- Имя параметра — Без комментариев, я указал здесь sPath
- по желанию добавляем описание к параметру, ровным счетом это ни на что не влияет
- Тип данных параметра — в нашем случае это Текст. Здесь лучше не рисковать, указывая Любой(Any), т.к. в этом случае можем получить ошибку запроса.
- Предлагаемые значения — выбираем Любое значение(логичнее было бы назвать этот пункт «Одно значение». Т.к. это больше подходит на мой взгляд).
- Текущее значение — это как раз то значение, которое и будет хранить наш параметр. Здесь я указываю путь к основной папке: G:Готовая модель ПланФактного анализа. Указываю со слешем на конце пути, чтобы не добавлять его в каждый источник после.
Теперь останется для каждого запроса добавить ссылку на этот параметр вместо жестко прописанного пути. Для этого в расширенном редакторе запросов(Главная -Расширенный редактор) для каждого запроса необходимо изменить переменную часть пути к файлам на наш параметр sPath:
Обращаю внимание, что после имени параметра(sPath) идет амперсанд(&). Он необходим для объединения двух текстовых строк в одну.
А теперь пара ложек дегтя для этого способа:
- Самый очевидный недостаток: при переносе файлов в любом случае необходимо будет заходить в редактор запросов (Главная —Управление параметрами —Изменить параметры) и изменять путь, указанный в параметре на новый. Так же это можно сделать напрямую из редактора запросов, раскрыв в левой части область запросов, выбрав параметр и вписав новое значение:
- И не очевидный недостаток: частенько такой подход приводит к ошибке получения данных при слиянии связанных запросов. Что делает этот способ не жизнеспособным в полной мере для большинства распространенных задач
Вариант 2
Создать еще один запрос в основной книге, на основании формул в Excel. Решение основано на возможностях встроенной функции Excel ЯЧЕЙКА(CELL). С её помощью можно получить полный путь к файлу, имя листа и книги. Чуть более подробно синтаксис этой функции и способы получения имени листа и книги я описывал в этой статье: Как получить имя листа формулой.
Итак, для начала нам необходимо на новом листе создать новую таблицу с двумя столбцами: значение и описание. В качестве значения в первой строке у нас и будет как раз формула с функцией ЯЧЕЙКА:
=ПСТР(ЯЧЕЙКА(«filename»;A1);1;ПОИСК(«[«;ЯЧЕЙКА(«filename»;A1))-1)
данная формула возвращает только путь к файлу, в котором записана. Что нам в общем-то от неё и надо.
При желании можно дописать подсказку к значению. Я это сделал для демонстрации и чтобы было понятно — что мы сможем потом дополнять эту таблицу другими переменными значениями при необходимости.
Теперь из этой таблицы необходимо сделать динамическую, или как их еще называют — умную: выделяем ячейки с данными(A1:B2) -вкладка Вставка(Insert) и выбрать Таблица(Table). Галочку «Мои данные содержат заголовки» оставляем включенной, даем понятное имя таблице — Parameters:
Далее выделяем любую ячейку внутри созданной таблицы и создаем новый запрос: вкладка Данные —Из таблицы(для пользователей PowerQuery 2013 и 2010 — вкладка PowerQuery -Из таблицы). Имя запроса у нас будет совпадать с именем таблицы — Parameters и этот запрос будет содержать как раз все значения нашей умной таблицы.
И теперь нам надо из этого запроса получить значение только одной конкретной ячейки — первой ячейки столбца «Значение»(в которой у нас формулой возвращается путь к папке). Для этого придется чуть пошаманить. Нам необходимо получить ссылку на таблицу «Parameters» и уже из неё получить значение нужной ячейки. Все это придется проделать на языке M, но звучит страшнее, чем выглядит — это всего одна строка:
Excel.CurrentWorkbook(){[Name=»Parameters»]}[Content]{0}[Значение]
Теперь разберем по шагам:
-
Excel.CurrentWorkbook() — непосредственно функция, которая получает данные обо всех умных таблицах(и именованных диапазонах) внутри книги Excel, в которой создан этот запрос (CurrentWorkbook — текущая книга).
{[Name=»Parameters»]} — так мы даем понять функции Excel.CurrentWorkbook, что нам нужны данные исключительно из объекта с именем «Parameters»(это наша умная таблица). На всякий случай уточню: получить просто ссылки на ячейки листа не получится, т.к. функция Excel.CurrentWorkbook данных о листах не получает вообще. Только именованные диапазоны и умные таблицы.
[Content] — все содержимое таблицы «Parameters»
{0} — пожалуй, самая хитрая часть для «не программистов» Это номер строки в указанной таблице(«Parameters»). При этом номера строк в запросе начинают отсчет с 0 и заголовки при этом не учитываются. Т.е. наш параметр находится физически во второй ячейке столбца «Значение» таблицы «Parameters» на листе. Но в рамках самой таблицы это первая её строка, т.к. заголовок не учитываем. Но т.к. в таблице отсчет начинается с 1, а в запросах с 0 — то и нам надо указывать, учитывая эту особенность. Если бы мы обращались ко второй строке таблицы — указать необходимо было бы 1. И да — указывать обязательно в фигурных скобках.
[Значение] — здесь в квадратных скобках указывается имя столбца(без всяких кавычек). Если бы столбец в таблице был всего один — то можно было бы его не указывать вовсе. Но т.к. у нас их больше — то указание обязательно, иначе запрос вернет всю строку — т.е. значения всех столбцов таблицы.
Т.е. строка Excel.CurrentWorkbook(){[Name=»Parameters»]}[Content]{0}[Значение] означает: из книги с запросом обратиться к таблице «Parameters»({[Name=»Parameters»]}), считать все данные([Content]) и отобрать оттуда значение первой строки({0}) столбца «Значение»([Значение])
И эта строка возвращает исключительно путь к папке — именно тот, который у нас получается в результате вычисления формулы с ЯЧЕЙКА.
Теперь, после того как разобрались что делает чудо-строка — осталось понять как это применить. Надо просто для каждого запроса перейти в редактор и в строке с источником:
Источник = Folder.Files(«C:Готовая модель ПланФактного анализаФакт»),
вместо части пути указать созданную строку запроса, добавив амперсанд(&) для объединения разных значений:
Источник = Folder.Files(Excel.CurrentWorkbook(){[Name=»Parameters»]}[Content]{0}[Значение] & «Факт»),
Все, теперь при перемещении книги с запросом или всей модели данные будут обновляться без какого-то ручного вмешательства.
В общем-то, такой подход можно использовать для задания даже имен файлов, используемых в модели. Например, можно дополнить таблицу именем файла с данными плана или путем к вспомогательным таблицам.
Скачать готовую модель план-фактного анализа с динамически изменяющимся путем к данным:
Готовая модель План-фактного анализа — относительный путь (491,0 KiB, 3 045 скачиваний)
Статья помогла? Поделись ссылкой с друзьями!
Видеоуроки
Поиск по меткам
Access
apple watch
Multex
Power Query и Power BI
VBA управление кодами
Бесплатные надстройки
Дата и время
Записки
ИП
Надстройки
Печать
Политика Конфиденциальности
Почта
Программы
Работа с приложениями
Разработка приложений
Росстат
Тренинги и вебинары
Финансовые
Форматирование
Функции Excel
акции MulTEx
ссылки
статистика
Группа: Пользователи Ранг: Прохожий Сообщений: 4
Замечаний: |
Подскажите, пожалуйста, можно ли сделать постоянную ссылку на ячейку запроса Power Query на другом листе?
При изменении данных в запросе у меня слетают формулы на обычном листе и пишет например =Share1.1!#ССЫЛКА! вместо =Share1.1!B2.
Share1.1 это и название листа с запросом, также пробовал через диспетчер имен создавать диапазон таблицы и его прописывать в формуле вместо имени листа… не работает, слетают формулы.
Сообщение отредактировал Vladimir92 — Четверг, 26.05.2022, 16:04
У меня есть несколько запросов PowerQuery, которые я хотел бы передать значение ячейки в моем файле Excel. В данном конкретном случае, полный путь к имени исходного файла.
есть ли способ, которым я могу получить это в PowerQuery?
1 ответов
Это может быть достигнуто с помощью именованного диапазона и пользовательской функции в PowerQuery:
- назовите ячейку, на которую нужно ссылаться (введите имя в файл слева от строки формул) — например
SourceFile
- вставьте новый пустой запрос PowerQuery (лента PowerQuery — > из других источников)
- в Редакторе PowerQuery перейдите в View — > Advanced Editor и вставьте следующий код;
(rangeName) => Excel.CurrentWorkbook(){[Name=rangeName]}[Content]{0}[Column1]
- назовите запрос
GetValue
(наименование свойство в панели параметров запроса справа)
теперь вы можете получить доступ к именованной ячейке в своих запросах, используя GetValue(cellName)
— например,
= Excel.Workbook(File.Contents(GetValue("SourceFile")))
Содержание
- Power query ссылка на ячейку excel
- Ссылка на значение ячейки в Редакторе запросов
- Ссылка на значение ячейки в Редакторе кода
- Ссылка на отсутствующие строку или столбец
- Эффект первичного ключа
- Power Query Продвинутый №9. Ссылки 1
- Описание
- Решение
- Power Query Продвинутый №12. Ссылки 4: Ссылка на другой шаг запроса и много практики
- Описание
- Решение
- Абсолютные и относительные ссылки в Power Query – подход в стиле Excel
- Абсолютные ссылки на строки
- Параметризация путей к данным в Power Query
- Постановка задачи
- Создаем запрос к внешнему файлу
- Находим путь к файлу в запросе
- Добавляем умную таблицу с путём к файлу
- Параметризуем путь в запросе
Power query ссылка на ячейку excel
Данная статья относится к надстройке Power Query в Excel 2010/2013, к группе Скачать и преобразовать вкладки Данные в Excel 2016, и к экрану Get Data в Power BI Desktop. Термин «Power Query» используется в том же контексте, что и в предыдущих статьях.
Иногда, при работе с данными таблиц Power Query возникает необходимость получить значение из одной ячейки таблицы. В статье показано, как это сделать через Редактор запросов и Редактор кода. Также подробно обсуждаются дополнительные возможности, доступные в последнем. Кстати, эта тема частично раскрыта в главе М книги Power Query за авторством Криса Вебба, но к настоящему моменту она несколько устарела.
Ссылка на значение ячейки в Редакторе запросов
Ссылка на значение ячейки в Редакторе кода
Рассмотрим эти три шага: – Источник – получаем данные из таблицы Excel
– «Измененный тип» – устанавливаем тип данных для трех столбцов в целочисленный
– poleB – возвращает значение ячейки из второй строки столбца В (строки начинаются с 0).
Код позволяет ссылаться на отдельные ячейки таблицы, используя систему координат из имени столбца и номера строки, еще раз повторим, что нумерация строк начинается с нуля. Поэтому выражение:
«Измененный тип»<1>[poleB]
вернёт значение ячейки из второй строки столбца poleB., т.е 5. Аналогично, выражение
«Измененный тип»<0>[poleC]
вернёт значение 3, соответствующее первой строке столбца poleC.
Отметим, что ссылки на столбец и строку могут идти в любом порядке, и выражение #»Измененный тип»<1>[poleB] вернёт то же самое, что и
«Измененный тип»[poleB]
Но в некоторых случаях, как вы скоро увидите, порядок строк и столбцов может быть важен.
Ссылка на отсутствующие строку или столбец
Что произойдёт если использовать ссылку на отсутствующий столбец и/или строку? Конечно, мы получим сообщение об ошибке. Вернёмся к нашему примеру и запишем:
Оба выражения вернут ошибку, т.к. в таблице нет 5-ой строки и столбца poleD.
Однако вместо ошибки можно получить значение NULL, используя оператор «?» после ссылки. Например, выражение
«Измененный тип»<1>[poleD]?
вернёт null вместо сообщения об ошибке:
Но будьте осторожны! Выражение
«Измененный тип»<4>?[poleB]
по-прежнему возвращает ошибку, но не потому что отсутствует пятая строка, а потому что ссылка на пятую строку вернёт null, а у него нет столбца poleB.
Решением может быть изменение порядка ссылок:
«Измененный тип»[poleB]<4>?
или применение оператора «?» для обеих ссылок:
«Измененный тип»<4>?[poleB]?
Эффект первичного ключа
Знаете ли вы, что таблицы Power Query могут содержать первичный ключ (т. е. один или несколько столбцов, значения которых уникально идентифицируют каждую строку), определяемый самой надстройкой? Нет? Неудивительно, это вовсе не очевидно из пользовательского интерфейса. Однако, существует несколько ситуаций, когда Power Query определяет первичный ключ для таблицы, в том числе:
- Когда импортируются данные из таблицы реляционной базы данных, подобной SQL Server, и таблица уже имеет первичный ключ.
- Когда используется кнопка Удалить повторения чтобы убрать повторяющиеся значения из столбца или столбцов, скрытно вызывается функция Table.Distinct()
- Когда к таблице применяется функция Table.AddKey()
Наличие первичного ключа влияет на работу функционала пункта Детализация углублением, и даёт другой способ ссылок на отдельные ячейки.
Рассмотрим следующую таблицу Excel, в основном такую же, что приводилась выше, но с новым столбцом, который однозначно идентифицирует каждую строку.
Источник
Power Query Продвинутый №9. Ссылки 1
Описание
- Как сослаться на определенный элемент листа
- Как сослаться на строку таблицы или Record
- Как сослаться на строку и получить только определенные поля записи
- Как найти строку по значению одного поля
- Как сослаться на строку, когда точно неизвестно есть ли у поля нужное значение
Решение
Создадим таблицу-пример
В этом уроке мы будем использовать простую таблицу-пример, на элементы которой и будем ссылаться.
Назовем эту таблицу sample_table.
Для создания таблицы будем использовать функцию #table.
Ссылка на элемент листа
Сначала научимся ссылаться на элемент списка.
Для ссылки на элемент списка нужно ввести название списка и в фигурных скобках указать индекс нужного элемента.
Индексация в Power Query начинается с нуля.
Сошлемся на второй элемент списка.
Ссылка на запись
Запись — это строка таблицы.
Чтобы сослаться на строку таблицы нужно ввести название этой таблицы и в фигурных скобках ввести индекс строки.
Индексация в Power Query начинается с нуля.
Сошлемся на вторую строку таблицы.
Получаем только отдельные поля записи
Чтобы получить только отдельные поля записи нужно сначала сослаться на запись, а потом в квадратных скобках перечислить нужные поля.
Название каждого поля тоже вводится в квадратных скобках.
Сошлемся на запись, указав значение поля
Мы можем ссылаясь на запись указать какое именно значение поля нас интересует.
Для этого в фигурных скобках вместо индекса нужно ввести условие. Само условие вводится в квадратных скобках.
Если нет уверенности, что значение присутствует в столбце
Если мы захотим сослаться на запись с указанием нужного значения поля, а такого значения в столбце не окажется, то Power Query вернет ошибку.
Чтобы ошибки не получилось нужно добавить к ссылке вопросительный знак.
В таком случае мы получим значение null, если значение не будет найдено.
Источник
Power Query Продвинутый №12. Ссылки 4: Ссылка на другой шаг запроса и много практики
Описание
- В этом уроке мы повторим/научимся ссылаться на ячейку, которая находится в другом шаге запроса
- При выполнении задачи мы повторим следующие формулы Power Query:
- Text.BetweenDelimiters
- Date.From
- Table.AddColumn
Решение
При открытии файла у вас уже есть 2 шага: Путь и Источник. Добавляем еще несколько шагов:
- Удаление верхних строк. Можно при помощи UI (Главная — Сократить строки — Удалить строки — Удаление верхних строк), а можно формулой =Table.Skip(Таблица,6) (здесь и далее «Таблица — это название шага, где хранится нужная таблица»)
- Используем первую строку в качестве заголовка. В UI (Главная — Преобразование — Использовать первую строку в качестве заголовков ) или при помощи формулы =Table.PromoteHeaders(Таблица)
- Удалить строку итогов в самом низу. Отфильтровать можно при помощи пользовательского интерфейса или формулой =Table.SelectRows(Таблица, each [Pos ID] <> «Итого»)
- Указать типы данных для столбцов. Здесь главное у последних двух столбцов указать тип данных числовой
Теперь мы подошли к самому главному шагу, ради которого все затевалось. Здесь и начинается практика ссылок.
Дата находится в шаге Источник в столбце Column1 в строке 4. Значит именно на этот шаг, столбец и строку нужно сослаться.
Источник
Абсолютные и относительные ссылки в Power Query – подход в стиле Excel
Эта статья – перевод моего первого поста в этом блоге, который был опубликован 5 ноября 2015 года на английском языке. К моему удивлению, этот пост – самый популярный, за это время он набрал почти 21000 просмотров. С небольшими стилистическими правками публикую его на русском языке. В переводе помогал мой сын Дмитрий, за что ему отдельное спасибо.
Power Query – это мощный инструмент, способный на большее, чем просто брать данные из источника и переносить их в таблицу или Power Pivot. Данные можно очищать и преобразовывать множеством способов, но есть некоторые действия, привычные для Excel, которые не так удобно делать в Power Query.
Например, что, если мне нужна относительная ссылка на конкретную ячейку в таблице Power Query – значение из определённой строки в определённом столбце? Или ссылка на значение в определённом столбце на четыре строки выше? В Excel очевидно, как это сделать: нужно просто указать на нужное значение мышкой, убедиться, что из ссылки к строке убран знак “$” (знак абсолютной ссылки), и всё. Но в Power Query я не могу так просто это сделать.
Но всё же решение, хотя и непрямое, существует.
Прежде всего давайте выясним, как можно получить доступ к конкретному значению из таблицы Power Query.
Простейший способ понять адресацию в Power Query, по-моему, анализировать код шагов.
Абсолютные ссылки на строки
Допустим, у нас есть простая таблица из двух столбцов: даты (Date) и количества (Amount). В ней пять строк, и в первом столбце стоят, как ни странно, даты, во втором – какие-то значения:
Мы хотим получить значение из ячейки B4, а именно 120.
В Excel это просто: мы просто пишем ссылку вроде =B4, или =R4C2 в стиле R1C1.
Можно ли использовать этот стиль ссылок (R1C1) в Power Query? Да.
Загрузите эту таблицу в Power Query, щёлкните правой мышкой по нужному значению и выберите “drill to details”. Отлично, мы получили 120.
Теперь взглянем на код.
В третьей строке кода мы видим искомую ссылку. Заметьте, что мы ссылаемся на предыдущий шаг (как обычно), затем пишем <2>и затем название столбца [Amount].
Важно: строки и списки в Power Query нумеруются с нуля: первая позиция в списке всегда имеет номер 0, то же самое касается номеров строк в таблице. Поэтому, запрашивая в Power Query значение из третьей строки, мы должны использовать число 2 для обозначения строки.
Эта формула расшифровывается так: дай мне значение из поля [Amount] в строке с индексом 2 таблицы Source. Иными словами, формула ищет определённый номер записи в таблице и затем возвращает значение определённого поля из этой записи.
Формула, полученная нами из редактора, фактически использует два последовательных подхода: выражение: Name и выражение Record[Field] .
Синтаксис Name имеет несколько реализаций:
- если Name – это список (list), а Argument – число (number), выражение возвращает элемент с соответствующим номером из списка Name;
- если Name – это таблица (table), а Argument – число (number), выражение возвращает строку с соответствующим номером из таблицы Name;
- если Name – это таблица (table), а Argument – запись (record), выражение возвращает уникальную строку из таблицы Name , в которой значения полей соответствуют значениям аналогичных полей записи Argument .
Последний вариант даёт представить множество возможностей использования, но сейчас мы вернемся прямо к нашему вопросу: абсолютные и относительные ссылки на одиночное значение.
Выражение Record[Field] имеет почти такой же синтаксис: оно ищет поле в записи по имени поля. Если в записи нет указанного поля, код выдаёт ошибку.
Взгляните снова на нашу формулу: сперва мы получаем строку (запись) из таблицы Source с номером 2:
Источник
Параметризация путей к данным в Power Query
Если вы уже начали использовать в работе инструменты бесплатной надстройки Power Query в Microsoft Excel, то очень скоро столкнётесь с одной узкоспециальной, но весьма частой и надоедливой проблемой, связанной с постоянно ломающимися ссылками на исходные данные. Суть проблемы в том, что если в своём запросе вы ссылаетесь на внешние файлы или папки, то Power Query жёстко прописывает абсолютный путь к ним в тексте запроса. У вас на компьютере всё работает прекрасно, но если вы решите отправить файл с запросом своим коллегам, то их ждёт разочарование, т.к. у них на компьютере путь к исходным данным уже другой, и наш запрос работать не будет.
Что же сделать в такой ситуации? Давайте рассмотрим этот случай подробнее на следующем примере.
Постановка задачи
Предположим, что у нас в папке E:Отчеты по продажам лежит файл Топ-100 товаров.xls, представляющий собой выгрузку из нашей корпоративной базы данных или ERP-системы (1С, SAP и т.п.) Этот файл содержит информацию о наиболее популярных товарных позициях и выглядит внутри примерно так:
С ходу, наверное, понятно, что работать с ним в Excel в таком виде практически невозможно: будут мешать пустые строки через одну с данными, объединенные ячейки, лишние столбцы, многоуровневая шапка и т.д.
Поэтому рядом с этим файлом в той же папке мы создаём ещё один новый файл Обработчик.xlsx, в котором создадим запрос Power Query, который будет загружать страшненькие данные из исходного файла-выгрузки Топ-100 товаров.xls, и приводить их в порядок:
Создаем запрос к внешнему файлу
Открыв файл Обработчик.xlsx, выберем на вкладке Данные команду Получить данные — Из файла — Из книги Excel (Data — Get Data — From file — From Excel) , затем укажем местоположение исходного файла и нужный нам лист. Выбранные данные загрузятся в редактор Power Query:
Приведём их в нормальный вид:
- Удалим пустые строки через Главная — Удалить строки — Удалить пустые строки (Home — Remove Rows — Remove Empty Rows) .
- Удалим ненужные 4 верхних строки через Главная — Удалить строки — Удалить верхние строки (Home — Remove Rows — Remove Top Rows) .
- Поднимем первую строку в шапку таблицы кнопкой Использовать первую строку в качестве заголовков на вкладке Главная (Home — Use first row as header) .
- Отделим пятизначный артикул от названия товара во втором столбце, используя команду Разделить столбец на вкладке Преобразование (Transform — Split Column) .
- Удалим ненужные столбцы и переименуем заголовки оставшихся для лучшей наглядности.
В итоге у нас должна получиться следующая, гораздо более приятная, картина:
Осталось эту облагороженную таблицу выгрузить обратно на лист в наш файл Обработчик.xlsx командой Закрыть и загрузить (Home — Close&Load) на вкладке Главная:
Находим путь к файлу в запросе
Теперь давайте посмотрим как выглядит наш запрос «под капотом», на встроенном в Power Query внутреннем языке с лаконичным названием «М». Для этого вернемся в наш запрос двойным щелчком по нему в правой панели Запросы и подключения и на вкладке Просмотр выберем Расширенный редактор (View — Advanced Editor) :
В открывшемся окне во второй строке сразу же обнаруживается жёстко прописанный путь к нашему исходному файлу выгрузки. Если мы сможем заменить эту текстовую строку на параметр, переменную или ссылку на ячейку листа Excel, где этот путь будет заранее прописан, то мы сможем впоследствии легко его менять.
Добавляем умную таблицу с путём к файлу
Закроем пока Power Query и вернёмся в наш файл Обработчик.xlsx. Добавим новый пустой лист и сделаем на нём маленькую «умную» таблицу, в единственной ячейке которой будет записан полный путь к нашему файлу исходных данных:
Для создания «умной» таблицы из обычного диапазона можно использовать сочетание клавиш Ctrl + T или кнопку Форматировать как таблицу на вкладке Главная (Home — Format as Table) . Заголовок столбца (ячейка А1) может быть совершенно любым. Также обратите внимание, что для понятности я дал таблице имя Параметры на вкладке Конструктор (Design) .
Скопировать из Проводника путь или даже ввести его вручную не представляет, конечно, особой сложности, но лучше всего минимизировать человеческий фактор и определять путь, по возможности, автоматически. Это можно реализовать с помощью стандартной функции рабочего листа Excel ЯЧЕЙКА (CELL) , которая умеет выдавать кучу полезной информации об указанной в качестве аргумента ячейке — в том числе и путь к текущему файлу:
Если предположить, что файл с исходными данными всегда лежит в той же папке, что и наш Обработчик, то путь, который нам нужен можно сформировать следующей формулой:
или в английской версии:
. где функция ЛЕВСИМВ (LEFT) берёт из полной ссылки кусок текста до открывающей квадратной скобки (т.е. путь к текущей папке), а затем к нему приклеивается имя и расширение нашего исходного файла с данными.
Параметризуем путь в запросе
Остался последний и самый главный штрих — прописать в запросе путь к исходному файлу Топ-100 товаров.xls, сославшись на ячейку А2 нашей созданной «умной» таблицы Параметры.
Для этого вернемся в запрос Power Query и ещё раз откроем Расширенный редактор на вкладке Просмотр (View — Advanced Editor) . Вместо текстовой строки-пути в кавычках «E:Отчеты по продажамТоп-100 товаров.xlsx» введём туда вот такую конструкцию:
Excel.CurrentWorkbook() <[Name=»Параметры»]>[Content] <0>[Путь к исходным данным]
Давайте разберемся из чего она состоит:
- Excel.CurrentWorkbook() — это функция языка М для обращения к содержимому текущего файла
- <[Name=»Параметры»]>[Content] — это уточняющий параметр к предыдущей функции, указывающий, что мы хотим получить содержимое «умной» таблицы Параметры
- [Путь к исходным данным] — это имя столбца в таблице Параметры, к которому мы обращаемся
- — это номер строки в таблице Параметры, из которой мы хотим взять данные. Шапка — не в счет и нумерация начинается от нуля, а не от единицы.
Вот и всё, собственно.
Осталось нажать на Готово и проверить как работает наш запрос. Теперь при пересылке всей папки с обоими файлами внутри на другой ПК запрос будет сохранять работоспособность и определять путь к данным автоматически.
Источник