Знакомство
Обзор
Microsoft Power Query предоставляет мощный интерфейс получения данных, охватывающий множество функций. Основная мощность Power Query заключается в фильтрации и объединении, то есть в "объединении" данных из одного или нескольких разнообразных поддерживаемых источников данных. Любые такие комбинации данных выражаются с помощью языка формул Power Query (неофициально известного как "M"). Power Query внедряет документы M в широкий спектр продуктов Майкрософт, в том числе Excel, Power BI, Analysis Services и Dataverse, для создания повторяемых смешиваний данных.
Этот документ содержит спецификацию для M. После краткого введения, направленного на создание первой интуиции и знакомство с языком, документ охватывает язык точно в нескольких прогрессивных шагах:
лексическая структура определяет набор текстов, которые лексически допустимы.
Значения, выражения, среды и переменные, идентификаторы и модель оценки формируют основные понятия языка базовые понятия.
Подробная спецификация значений , как примитивных, так и структурированных, определяет целевой домен языка.
Значения содержат типы, которые сами по себе являются особым видом значений, характеризуют фундаментальные типы значений и несут дополнительные метаданные, относящиеся к структуре структурированных значений.
Набор операторов в M определяет, какие виды выражений можно сформировать.
Функции, другой вид специальных значений, предоставляют основу для богатой стандартной библиотеки для M и позволяют добавлять новые абстракции.
ошибки могут возникать при применении операторов или функций во время вычисления выражений. Хотя ошибки не являются значениями, существуют способы обрабатывать ошибки, которые сопоставляют ошибки обратно со значениями.
Пусть выражения позволяют вводить вспомогательные определения, используемые для создания сложных выражений в небольших шагах.
Если выражения поддерживают условную оценку.
разделы обеспечивают простой механизм модульности. (Разделы еще не задействованы в Power Query.)
Наконец, консолидированная грамматика собирает фрагменты грамматики из всех остальных разделов этого документа в единое полное определение.
Для теоретиков языка компьютеров: язык формул, указанный в этом документе, является в основном чистым, более высоким, динамически типизированным, частично отложенным функциональным языком.
Выражения и значения
Центральная конструкция в M — это выражение . Выражение можно оценивать (вычислять), возвращая одно значение .
Хотя многие значения могут быть записаны буквально как выражение, значение не является выражением. Например, выражение 1
оценивает значение 1; выражения 1+1
вычисляют значение 2. Это различие тонко, но важно. Выражения — это рецепты для оценки; значения — это результаты оценки.
В следующих примерах показаны различные типы значений, доступных в M. По соглашению, значение записывается в литеральной форме, в которой оно будет представлено в выражении, оценивающем только это значение. (Обратите внимание, что //
указывает начало комментария, который продолжается до конца строки.)
примитивным значением является одноэлементное значение, например число, логическое значение, текст или null. Значение NULL можно использовать для указания отсутствия любых данных.
123 // A number true // A logical "abc" // A text null // null value
Значение списка
является упорядоченной последовательностью значений. M поддерживает бесконечные списки, но если список задан как литерал, он будет иметь фиксированную длину. Фигурные скобки {
и}
обозначают начало и конец списка.{123, true, "A"} // list containing a number, a logical, and // a text {1, 2, 3} // list of three numbers
Запись — это набор полей . Поле — это пара "имя-значение", где имя является текстовым значением, уникальным в записи поля. Синтаксис литерала для значений записей позволяет записывать имена без кавычек, такую форму также называют идентификаторами. Ниже показана запись, содержащая три поля с именем "
A
", "B
" и "C
", которые имеют значения1
,2
и3
.[ A = 1, B = 2, C = 3 ]
Таблица — это набор значений, организованных по столбцам (которые определяются по имени) и строкам. Нет литерального синтаксиса для создания таблицы, но существует несколько стандартных функций, которые можно использовать для создания таблиц из списков или записей.
Например:
#table( {"A", "B"}, { {1, 2}, {3, 4} } )
При этом создается таблица следующей фигуры:
функция — это величина, которая при вызове с аргументами создает новое значение. Функция записывается путем перечисления параметров функции, в скобках, а затем символов
=>
и выражения, определяющего функцию. Это выражение обычно относится к параметрам (по имени).(x, y) => (x + y) / 2`
Оценка
Модель оценки языка M моделиируется после того, как модель оценки обычно найдена в электронных таблицах, где порядок вычисления можно определить на основе зависимостей между формулами в ячейках.
Если вы написали формулы в электронной таблице, например Excel, вы можете узнать, что формулы слева при вычислении дают результат в виде значений справа.
В M части выражения могут ссылаться на другие части выражения по имени, а процесс оценки автоматически определяет порядок вычисления ссылочных выражений.
Запись можно использовать для создания выражения, эквивалентного предыдущему примеру электронной таблицы. При инициализации значения поля можно ссылаться на другие поля в записи, используя имя поля следующим образом:
[
A1 = A2 * 2,
A2 = A3 + 1,
A3 = 1
]
Приведенное выше выражение эквивалентно следующему (в том, что оба оцениваются равными значениями):
[
A1 = 4,
A2 = 2,
A3 = 1
]
Записи могут содержаться внутри других записей или быть вложеннымив другие записи. Вы можете использовать оператор ([]
) для доступа к полям записи по имени. Например, следующая запись содержит поле с именем Sales
, содержащее запись, и поле с именем Total
, которое обращается к полям FirstHalf
и SecondHalf
записи Sales
:
[
Sales = [ FirstHalf = 1000, SecondHalf = 1100 ],
Total = Sales[FirstHalf] + Sales[SecondHalf]
]
Выражение выше эквивалентно следующему во время вычисления:
[
Sales = [ FirstHalf = 1000, SecondHalf = 1100 ],
Total = 2100
]
Записи также могут содержаться в списках. Оператор позиционного индекса ({}
) можно использовать для доступа к элементу в списке по его числовому индексу. Значения в списке обращаются по индексу, который начинается с нуля. Например, индексы 0
и 1
используются для ссылки на первые и второй элементы в списке ниже:
[
Sales =
{
[
Year = 2007,
FirstHalf = 1000,
SecondHalf = 1100,
Total = FirstHalf + SecondHalf // 2100
],
[
Year = 2008,
FirstHalf = 1200,
SecondHalf = 1300,
Total = FirstHalf + SecondHalf // 2500
]
},
TotalSales = Sales{0}[Total] + Sales{1}[Total] // 4600
]
Выражения списка и записи элементов (а также позволяют выражениям) оцениваться с помощью отложенной оценки, что означает, что они оцениваются только по мере необходимости. Все остальные выражения оцениваются с помощью жадной оценки, что означает, что они вычисляются немедленно при обнаружении во время процесса оценки. Хороший способ думать об этом заключается в том, чтобы помнить, что оценка списка или выражения записи возвращает значение списка или записи, которое само по себе запоминает, как его элементы списка или поля записи должны быть вычисляться при запросе (по запросу или операторам индекса).
Функции
В M функция — это сопоставление набора входных значений с одним выходным значением. Функция записывается путем первого именования необходимого набора входных значений (параметров функции) и последующего предоставления выражения, вычисляющего результат функции с помощью этих входных значений (текст функции) после символа переходов (=>
) . Например:
(x) => x + 1 // function that adds one to a value
(x, y) => x + y // function that adds two values
Функция — это значение так же, как число или текстовое значение. В следующем примере показана функция, которая является значением поля Add, которое затем вызываетсяили выполняется из нескольких других полей. При вызове функции указывается набор значений, которые логически заменяются необходимым набором входных значений в выражении тела функции.
[
Add = (x, y) => x + y,
OnePlusOne = Add(1, 1), // 2
OnePlusTwo = Add(1, 2) // 3
]
Библиотека
M включает универсальный набор определений, доступных для использования в выражении, называемом стандартная библиотека , или просто библиотека . Эти определения состоят из набора именованных значений. Имена значений, предоставляемых библиотекой, доступны для использования в выражении без явного определения выражением. Например:
Number.E // Euler's number e (2.7182...)
Text.PositionOf("Hello", "ll") // 2
Операторы
M включает набор операторов, которые можно использовать в выражениях.
операторы применяются к операндам, чтобы сформировать символьные выражения. Например, в выражении 1 + 2
числа 1
и 2
являются операнды, а оператором является оператор сложения (+
).
Значение оператора может отличаться в зависимости от типа значений операндов. Например, оператор "плюс" можно использовать с другими типами значений помимо чисел:
1 + 2 // numeric addition: 3
#time(12,23,0) + #duration(0,0,2,0)
// time arithmetic: #time(12,25,0)
Другим примером оператора, значение которого зависит от операндов, является оператор сочетания (&
):
"A" & "BC" // text concatenation: "ABC"
{1} & {2, 3} // list concatenation: {1, 2, 3}
[ a = 1 ] & [ b = 2 ] // record merge: [ a = 1, b = 2 ]
Обратите внимание, что некоторые операторы не поддерживают все сочетания значений. Например:
1 + "2" // error: adding number and text isn't supported
Выражения, которые при вычислении сталкиваются с неопределёнными условиями операторов, приводят к ошибкам .
Метаданные
Метаданные — это информация о значении, ассоциированном с другим значением. Метаданные представлены в виде значения записи, называемого записью метаданных . Поля записи метаданных можно использовать для хранения информации о значении.
Каждое значение имеет запись метаданных. Если значение записи метаданных не указано, запись метаданных пуста (не имеет полей).
Записи метаданных предоставляют способ связывания дополнительных сведений с любым типом значения ненавязчивым способом. Связывание записи метаданных со значением не изменяет значение или его поведение.
Значение записи метаданных y
связано с существующим значением x
с помощью синтаксиса x meta y
. Например, следующий код связывает запись метаданных с полями Rating
и Tags
с текстовым значением "Mozart"
:
"Mozart" meta [ Rating = 5, Tags = {"Classical"} ]
Для значений, которые уже содержат непустую запись метаданных, результатом применения мета является вычисление слияния записей существующей и новой записи метаданных. Например, следующие два выражения эквивалентны друг другу и предыдущему выражению:
("Mozart" meta [ Rating = 5 ]) meta [ Tags = {"Classical"} ]
"Mozart" meta ([ Rating = 5 ] & [ Tags = {"Classical"} ])
Доступ к записи метаданных можно получить для заданного значения с помощью функции Value.Metadata. В следующем примере выражение в поле ComposerRating
получает доступ к метаданным значения в поле Composer
, а затем к полю Rating
этих метаданных.
[
Composer = "Mozart" meta [ Rating = 5, Tags = {"Classical"} ],
ComposerRating = Value.Metadata(Composer)[Rating] // 5
]
Выражение Let
Многие примеры, показанные до сих пор, включали все литеральные значения выражения в результате выражения. Выражение let
позволяет вычислять набор значений, назначать имена, а затем использовать в последующем выражении, которое следует in
. Например, в нашем примере данных о продажах можно сделать следующее:
let
Sales2007 =
[
Year = 2007,
FirstHalf = 1000,
SecondHalf = 1100,
Total = FirstHalf + SecondHalf // 2100
],
Sales2008 =
[
Year = 2008,
FirstHalf = 1200,
SecondHalf = 1300,
Total = FirstHalf + SecondHalf // 2500
]
in Sales2007[Total] + Sales2008[Total] // 4600
Результатом приведенного выше выражения является числовое значение (4600
), вычисленное из значений, привязанных к именам Sales2007
и Sales2008
.
Если выражение
Выражение if
выбирает между двумя выражениями на основе логического условия. Например:
if 2 > 1 then
2 + 2
else
1 + 1
Первое выражение (2 + 2
) выбрано, если логическое выражение (2 > 1
) имеет значение true, а второй выражение (1 + 1
) выбрано, если это значение false. Выбранное выражение (в данном случае 2 + 2
) вычисляется и становится результатом выражения if
(4
).
Ошибки
Ошибка является признаком того, что процесс оценки выражения не мог создать значение.
Ошибки вызываются операторами и функциями при возникновении ошибочных ситуаций или с помощью выражения ошибки. Ошибки обрабатываются с помощью выражения try
. При возникновении ошибки указывается значение, которое можно использовать для указания причины возникновения ошибки.
let Sales =
[
Revenue = 2000,
Units = 1000,
UnitPrice = if Units = 0 then error "No Units"
else Revenue / Units
],
UnitPrice = try Number.ToText(Sales[UnitPrice])
in "Unit Price: " &
(if UnitPrice[HasError] then UnitPrice[Error][Message]
else UnitPrice[Value])
Приведенный выше пример обращается к полю Sales[UnitPrice]
и форматирует значение, которое приводит к результату:
"Unit Price: 2"
Если поле Units
было нулевым, то поле UnitPrice
вызвало бы ошибку, которая была бы обработана try
. После этого результирующее значение было бы следующим:
"No Units"
Выражение try
преобразует правильные значения и ошибки в значение записи, указывающее, обрабатывает ли выражение try
ошибку или нет, а также правильное значение или запись об ошибке, извлеченную при обработке ошибки. Например, рассмотрим следующее выражение, которое вызывает ошибку, а затем обрабатывает его сразу:
try error "negative unit count"
Это выражение вычисляет следующее вложенное значение записи, объясняя [HasError]
, [Error]
и [Message]
поля поиска в предыдущем примере цены на единицу.
[
HasError = true,
Error =
[
Reason = "Expression.Error",
Message = "negative unit count",
Detail = null
]
]
Распространенным случаем является замена ошибок значениями по умолчанию. Выражение try
можно использовать с необязательным предложением otherwise
для достижения этого в компактной форме.
try error "negative unit count" otherwise 42
// 42