Record.FieldNames Function (Power Query M)

If you want to pull the field names out of a record, so you can count them, loop over them, or feed them into another step, the Record.FieldNames function is what you reach for. It returns those names as a list of text, in the exact order they appear in the record. Available in Excel (Power Query), Power BI Desktop, and Power BI Service.

Syntax of Record.FieldNames Function

Record.FieldNames(record as record) as list

where

  • record (required, record). The record whose field names you want to read back.

Returns: a list of text values, one per field, in the same order the fields appear in the record.

In plain terms, you hand it a record and it gives you back the names of its fields as a plain list of text.

Example 1: Get the field names from a record

Say you have a record with three fields and you want their names.

let
Source = Record.FieldNames([Name="Ava",City="Pune",Age=29])
in
Source

Result: {"Name", "City", "Age"}

You get back a list of three text values, one for each field in the record.

Example 2: Field order is preserved exactly

The names come back in the order the fields sit in the record. It does not sort or alphabetize them.

Here the same three fields are written in Age, City, Name order.

let
Source = Record.FieldNames([Age=29,City="Pune",Name="Ava"])
in
Source

Result: {"Age", "City", "Name"}

The list mirrors the record’s order, so Age comes first this time.

Example 3: Count how many fields a record has

Since the result is a list, you can wrap it in List.Count to find out how many fields the record has.

let
Source = List.Count(Record.FieldNames([Name="Ava",City="Pune",Age=29,Email="ava@mail.com"]))
in
Source

Result: 4

The record has four fields, so List.Count returns 4 instead of the list of names.

Example 4: Get the column names from a table’s first row

Every row of a table is really a record, so you can read a table’s column headers by grabbing the first row with Table.First and passing it to Record.FieldNames.

Here is the starting data:

EmpIDFullNameDepartmentSalary
101Ava SharmaFinance62000
102Ravi MehtaMarketing58000
103Leo ParkFinance71000

Pull the field names from the first row:

let
Source = Excel.CurrentWorkbook(){[Name="Employees"]}[Content],
FieldNames = Record.FieldNames(Table.First(Source))
in
FieldNames

Result: {"EmpID", "FullName", "Department", "Salary"}

Table.First returns the first row as a record, and Record.FieldNames reads its field names, which are the table’s column headers.

Example 5: For a whole table, use Table.ColumnNames

If you already have a table, you do not need the first-row trick. Table.ColumnNames reads the headers straight off the table.

Here is the starting data:

RegionQuarterRevenue
WestQ112000
EastQ19500
WestQ213400

Read the column names directly:

let
Source = Excel.CurrentWorkbook(){[Name="Sales"]}[Content],
ColNames = Table.ColumnNames(Source)
in
ColNames

Result: {"Region", "Quarter", "Revenue"}

This gives the same kind of list as Example 4, but without pulling a row out first. Reach for Record.FieldNames when you are inside a single record, and Table.ColumnNames when you have a table.

Example 6: Feed the names into Record.SelectFields

A common use is to grab the names, work with that list, then use it to drive another step. Here we take the first two field names and feed them into Record.SelectFields to keep just those fields. You could just as easily pass a name list like this to Table.SelectColumns to pick columns dynamically.

let
Person = [Name="Ava",City="Pune",Age=29,Email="ava@mail.com"],
Names = Record.FieldNames(Person),
FirstTwo = List.FirstN(Names,2),
Picked = Record.SelectFields(Person,FirstTwo),
Result = Record.FieldNames(Picked)
in
Result

Result: {"Name", "City"}

Record.FieldNames reads the four names, List.FirstN keeps the first two, and Record.SelectFields builds a smaller record from them. Reading its names back confirms only Name and City survived.

Things to keep in mind with Record.FieldNames

  • The names come back as text values. Each item in the list is a text value, so it feeds straight into text and list functions without any conversion.
  • For a whole table, use Table.ColumnNames. Record.FieldNames works on one record at a time, so on a table you would otherwise have to pull a row first (Example 4). Table.ColumnNames reads the headers in one step.
  • Record.FieldValues is the matching partner. Record.FieldNames gives you the keys, while Record.FieldValues gives the values in the same order. Pair them when you need both sides of a record. To pull a single named value out instead, use Record.Field.
  • The argument must be a record. Passing a list or a table throws Expression.Error: We cannot convert a value of type List to type Record. Convert a row to a record first with Table.First if you are starting from a table.

Common questions about Record.FieldNames

What is the difference between Record.FieldNames and Table.ColumnNames?

Record.FieldNames reads the field names of a single record, while Table.ColumnNames reads the column headers of a whole table. They return the same kind of list, so Record.FieldNames(Table.First(table)) matches Table.ColumnNames(table).

How do I get the values instead of the names?

Use Record.FieldValues. It returns the values of a record as a list in the same order that Record.FieldNames returns the names.

List of All Power Query Functions

Related Power Query Functions / Articles:

I am a huge fan of Microsoft Excel and love sharing my knowledge through articles and tutorials. I work as a business analyst and use Microsoft Excel extensively in my daily tasks. My aim is to help you unleash the full potential of Excel and become a data-slaying wizard yourself.