18 September 2023
t M language is Microsoft's proprietary programming language for Power BI. As adoption of Power BI grows, learning M language is becoming an increasingly valuable skill for data analysts and BI professionals. This guide provides an introduction to M language training, including an overview of the language, how to set up the development environment, basic syntax and concepts, and resources for further learning. Read on to get started with unlocking the full potential of Power BI through M language. This resource is a support tool to be used in conjunction with our Power BI Courses the perfect opportunity to start your teams training in Power BI. To find out more visit our Power BI training course page.
M language, originally known as Power Query M Formula Language, is the underlying programming language used in Power BI for data transformations and shaping. Introduced in 2013, M provides users with more advanced functionality compared to Power Query alone.
With M language, analysts can cleanse, transform, integrate, and model data to optimize it for building reports and visualizations in Power BI. Key capabilities offered by M include:
Learning M unlocks the full flexibility of Power BI. Analysts can implement complex data handling logic and optimizations that go beyond the standard graphical interface. Fluent M programmers can build custom visuals, integrate external languages like R and Python, and create enterprise-grade BI solutions.
Example of M language code for transforming and shaping data in Power BI
To start working with M language, you will need to install Power BI Desktop from Microsoft. This free desktop application includes an integrated M language editor for authoring scripts.
Download and install the latest version of Power BI Desktop for your operating system from here.
Once setup is complete, you can enable M language scripting in Power BI Desktop by following these steps:
This will open the M language editor window docked within Power BI Desktop.
Enabling the M language editor in Power BI Desktop
You can also install a dedicated M language IDE like Visual Studio Code for advanced authoring features like debugging and Git integration. Popular lightweight text editors like Atom or Sublime Text also work well.
With the development environment setup, you can start writing your first lines of M code. Let's go through a simple script that prints the text "Hello World!" to the console output:
// Print hello world "Hello World!"
Breaking this down:
//
denotes a code comment in M"Hello World!"
is a string literal, delimited with double quotesLet's enhance this script to use variables and take input:
// Store input in a variable name = "Susan"; // Print output using the variable "Hello" & " " & name & "!"
New concepts used:
name
is a variable storing the input name&
concatenates strings togethername
are automatically printedWith just these basic concepts, you can start building real programs in M language for Power BI.
Being designed for data transformation, M language contains extensive capabilities for loading, shaping, and cleansing datasets in Power BI.
For example, we can import data from a local CSV file:
// Load data from CSV salesData = Csv.Document(File.Contents("sales.csv"),[Delimiter=",", Encoding=1252, QuoteStyle=QuoteStyle.None]); // View the first 3 rows salesData{0..2}
Key operations demonstrated:
Csv.Document
loads from a CSV documentFile.Contents
imports the file contentssalesData{0..2}
prints the first 3 rowsWe can query, filter, and aggregate this data using M language:
// Group by country and sum the sales salesByCountry = Table.Group(salesData, {"Country"}, {{"Sales", each List.Sum([Sales]), type number}}) // Filter for countries with sales over 200,000 largeCountries = Table.SelectRows(salesByCountry, each [Sales] > 200000)
This illustrates:
Table.Group
to group and aggregateList.Sum
to sum a columnTable.SelectRows
to filter rowsM has over 500 data transformation functions for shaping, splitting, combining, and cleaning data.
You can create Power BI visuals directly using M language through the JavaScript API.
First, ensure you enable the API in File > Options and Settings > Options > Preview Features
.
Then you can create a bar chart with random data as follows:
// Generate random data data = Table.FromColumns({List.Random(50, type number)}, {"Sales"}); // Create bar chart visual visual = visuals.create("barChart") visual.dataBind(data) visual.title("Sales by Product", visuals.TitleCategory.TitleOnly) visual.axisXTitle("Product") visual.axisYTitle("Sales ($)")
The key steps are:
visuals.create
instantiates a visual typevisual.dataBind
connects datavisual
methods customize propertiesThis allows complete customization and creation of any visual type with M programming.
Bar chart generated through M language visual creation
A key part of mastering M language is learning how to author reusable, parameterized functions.
Here is an example function to filter datatable rows by a condition:
FilterRows = (data as table, condition as function) as table => Table.SelectRows(data, condition)
Breakdown of the syntax:
FilterRows
is the function nameas
clausesdata
and condition
as table
defines return typeWe can call FilterRows like so:
// Filter for sales over 200 result = FilterRows(salesData, each [Sales] > 200)
Parameterized functions abstract away logic into reusable packages. They form the building blocks of robust M programs.
Using the JavaScript API, custom visuals can be developed from scratch with M language.
For example, a scatter plot visual that accepts category and value columns as inputs:
// Function to create scatter visual ScatterPlot = (data as table, category as text, value as number) as any => let // Extract category and value columns source = Table.SelectColumns(data, {category, value}), // Create scatter chart visualization vis = visuals.create("scatterChart") vis.dataBind(source) vis.category(category) vis.value(value) vis.title("Scatter Plot") in vis
Call the function by passing data and field names:
// Generate sample data table = #table({"Product", "Sales"}, {{"Bike", 100}, {"Car", 250}, {"Train", 75}}) // Create scatter plot ScatterPlot(table, "Product", "Sales")
This approach can build entire libraries of reusable, parameterized visuals.
M language can generate entire reports and dashboards in code.
For example, we can programmatically build a sales KPI dashboard:
let // Import sales data source = Csv.Document(File.Contents("sales.csv")), // Format as table salesTable = Table.FromColumns(source, Table.ColumnNames(source)), // Build KPI visuals revenue = visuals.create("kpi") .dataBind(salesTable), .valueName("Revenue") .value(List.Sum([Sales])), profit = visuals.create("kpi") .dataBind(salesTable), .valueName("Profit") .value(List.Sum([Profit])), // Build dashboard container dashboard = visuals.create("dashboard") .addPage(revenue, "Revenue KPI") .addPage(profit, "Profit KPI") in dashboard
Through a series of M language transformations, visualizations, and containers, full-fledged reports can be generated.
M language scripts, functions, and visuals can be packaged and shared for collaboration.
For example, custom visuals can be distributed and imported:
// Load visual from PBIVIZ file MyVisual = Visual.Import("MyCustomVisual.pbiviz");
Reusable M functions can be saved as *.m
files and referenced:
// Load M code module MyFunctions = Module.FromFile("MyFunctions.m"); // Call function in module Table.AddColumn(MyData, "Tax", each MyFunctions.CalculateTax([Price], 0.2))
Analysts can build up repositories of reusable M artifacts to share across teams and projects.
M language has security capabilities like row-level security (RLS) to restrict data access.
For example, we can define an RLS rule that filters sales data by regional sales manager:
// Function for RLS role filter SalesFilter = (userInfo as table) => let managerRegion = userInfo{0}[ManagerRegion], filteredTable = Table.SelectRows(salesData, each [Region] = managerRegion) in filteredTable // Configure RLS on the Sales table Table.ConfigureRoleRules(salesData, "Sales Manager", SalesFilter)
Now filters will apply automatically when content is accessed by different user roles.
Dynamic data masking can also be implemented to obfuscate sensitive fields like credit card numbers.
With M code powering key artifacts in production environments, monitoring its usage and performance is critical.
The following snippet logs query events and times to a table:
// Setup query log table logTable = #table({"Query", "Duration"}, {{"Sales Query", 0.25}}), // Register query event handler QueryEvents.QueryCompleted = (queryInfo) => logTable = Table.AddRow(logTable, {queryInfo[Query], queryInfo[Duration]})
We can then visualize log data to analyze bottlenecks and optimize slow M scripts.
Advanced profiling of M code can be done using third-party tools like Colectica's M Query Profiler.
M integrates seamlessly with other Microsoft cloud services like Power Automate and Azure tools.
For example, Power Automate flows can be triggered on Power BI dataset refreshes through M:
// API endpoint for flow apiUrl = "https://prod-xyz.eastus.logic.azure.com:443/...", // Post event on dataset refresh OnPostRefresh = (dataSetName as text) => Web.Contents(apiUrl, [Content=Text.ToBinary(dataSetName)])
This allows refreshing flows and downstream processes automatically after upstream M data transforms.
M can also connect to Azure services using built-in connectors. The Azure Data Lake connector, for instance, enables querying and importing Azure Data Lake Store files.
To further build M language skills, Microsoft Learn provides various free training modules including introductory, intermediate, and advanced content.
The official M language reference documentation covers syntax, functions, and operators in detail.
For community support, the dedicated M language forum on Power BI is quite active. The Microsoft tech community also provides help threads.
Numerous M language code samples are available in GitHub repositories like Microsoft's M Samples.
By leveraging these resources, Power BI users can gain expertise in M language to fully harness its capabilities.
This guide provided an overview of how to get started with M language training by:
To take your skills to an advanced level, some recommended next steps are:
CONTACT
+44 (0)20 8446 7555
Copyright © 2023 JBI Training. All Rights Reserved.
JB International Training Ltd - Company Registration Number: 08458005
Registered Address: Wohl Enterprise Hub, 2B Redbourne Avenue, London, N3 2BS
Modern Slavery Statement & Corporate Policies | Terms & Conditions | Contact Us