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:
| EmpID | FullName | Department | Salary |
|---|---|---|---|
| 101 | Ava Sharma | Finance | 62000 |
| 102 | Ravi Mehta | Marketing | 58000 |
| 103 | Leo Park | Finance | 71000 |
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:
| Region | Quarter | Revenue |
|---|---|---|
| West | Q1 | 12000 |
| East | Q1 | 9500 |
| West | Q2 | 13400 |
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
textvalue, so it feeds straight into text and list functions without any conversion. - For a whole table, use
Table.ColumnNames.Record.FieldNamesworks on one record at a time, so on a table you would otherwise have to pull a row first (Example 4).Table.ColumnNamesreads the headers in one step. Record.FieldValuesis the matching partner.Record.FieldNamesgives you the keys, whileRecord.FieldValuesgives the values in the same order. Pair them when you need both sides of a record. To pull a single named value out instead, useRecord.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 withTable.Firstif 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: