Skip to content

Instantly share code, notes, and snippets.

@halbuki
Last active May 24, 2025 16:38
Show Gist options
  • Save halbuki/e934bf72bdd7c36775a1ee65eac596b6 to your computer and use it in GitHub Desktop.
Save halbuki/e934bf72bdd7c36775a1ee65eac596b6 to your computer and use it in GitHub Desktop.
Excel Lambda functions for Power Query Record functions
/* USE NAMESPACE "Record" */
Field = LAMBDA(
// Parameter Declarations
_record,
_field,
LET(
// Help
Help, TRIM(
TEXTSPLIT(
"DESCRIPTION:->Returns the value of a field from a record
VERSION:->1.0
PARAMETERS:->_record as record, _field as text",
"->",
"
"
)
),
// Error Messages
ErrorMessages, {"_record is not a record."; "_field is not text."},
// Check Inputs
_err1, IF(OR(ROWS(_record) <> 2, NOT(COLUMNS(_record) > 0)), #VALUE!, FALSE()),
_err2, IF(NOT(ISTEXT(_field)), #VALUE!, FALSE()),
ErrorArray, VSTACK(ISERROR(_err1), ISERROR(_err2)),
Messages, FILTER(ErrorMessages, ErrorArray, ""),
// Procedure
fieldnames, Record.FieldNames(_record),
fieldcol, List.PositionOf(fieldnames, _field),
Result, INDEX(_record, 2, fieldcol),
// Handle Error
Error, IF(OR(ErrorArray), 3, IF(OR(ISERROR(Result)), 2, 1)),
// Return Result
CHOOSE(Error, Result, Help, Messages)
)
);
FieldCount = LAMBDA(
// Parameter Declarations
_record,
LET(
// Help
Help, TRIM(
TEXTSPLIT(
"DESCRIPTION:->Returns the number of fields of a record
VERSION:->1.0
PARAMETERS:->_record as record",
"->",
"
"
)
),
// Error Messages
ErrorMessages, {"_record is not a record."},
// Check Inputs
_err1, IF(OR(ROWS(_record) <> 2, NOT(COLUMNS(_record) > 0)), #VALUE!, FALSE()),
ErrorArray, VSTACK(ISERROR(_err1)),
Messages, FILTER(ErrorMessages, ErrorArray, ""),
// Procedure
Result, COLUMNS(_record),
// Handle Error
Error, IF(OR(ErrorArray), 3, IF(OR(ISERROR(Result)), 2, 1)),
// Return Result
CHOOSE(Error, Result, Help, Messages)
)
);
FieldNames = LAMBDA(
// Parameter Declarations
_record,
LET(
// Help
Help, TRIM(
TEXTSPLIT(
"DESCRIPTION:->Returns the field names of a record.
VERSION:->1.0
PARAMETERS:->_record as record",
"->",
"
"
)
),
// Error Messages
ErrorMessages, {"_record is not a record."},
// Check Inputs
_err1, IF(OR(ROWS(_record) <> 2, NOT(COLUMNS(_record) > 0)), #VALUE!, FALSE()),
ErrorArray, VSTACK(ISERROR(_err1)),
Messages, FILTER(ErrorMessages, ErrorArray, ""),
// Procedure
Result, TRANSPOSE(INDEX(_record, 1, 0)),
// Handle Error
Error, IF(OR(ErrorArray), 3, IF(OR(ISERROR(Result)), 2, 1)),
// Return Result
CHOOSE(Error, Result, Help, Messages)
)
);
HasFields = LAMBDA(
// Parameter Declarations
_record,
_fields,
LET(
// Help
Help, TRIM(
TEXTSPLIT(
"DESCRIPTION:->Returns whether the _record has specified fields in _fields.
VERSION:->1.0
PARAMETERS:->_record as record, _fields as 1-d array of texts",
"->",
"
"
)
),
// Error Messages
ErrorMessages, {"_record is not a record."; "_fields is not 1-d array of texts."},
// Check Inputs
_err1, IF(OR(ROWS(_record) <> 2, NOT(COLUMNS(_record) > 0)), #VALUE!, FALSE()),
_err2, IF(AND(ROWS(_fields) > 1, COLUMNS(_fields) > 1), #VALUE!, FALSE()),
ErrorArray, VSTACK(ISERROR(_err1), ISERROR(_err2)),
Messages, FILTER(ErrorMessages, ErrorArray, ""),
// Procedure
__fieldnames, TRANSPOSE(INDEX(_record, 1, 0)),
Result, MAKEARRAY(
COUNTA(ISERROR(_fields)),
1,
LAMBDA(ir, ic,
LET(_field, INDEX(_fields, ir), NOT(ISERROR(List.PositionOf(__fieldnames, _field))))
)
),
// Handle Error
Error, IF(OR(ErrorArray), 3, IF(OR(ISERROR(Result)), 2, 1)),
// Return Result
CHOOSE(Error, Result, Help, Messages)
)
);
SelectFields = LAMBDA(
// Parameter Declarations
_record,
_fields,
LET(
// Help
Help, TRIM(
TEXTSPLIT(
"DESCRIPTION:->Returns the _record with only selected fields in _fields.
VERSION:->1.0
PARAMETERS:->_record as record, _fields as 1-d array of texts",
"->",
"
"
)
),
// Error Messages
ErrorMessages, {"_record is not a record."; "_fields is not 1-d array of texts."},
// Check Inputs
_err1, IF(OR(ROWS(_record) <> 2, NOT(COLUMNS(_record) > 0)), #VALUE!, FALSE()),
_err2, IF(AND(ROWS(_fields) > 1, COLUMNS(_fields) > 1), #VALUE!, FALSE()),
ErrorArray, VSTACK(ISERROR(_err1), ISERROR(_err2)),
Messages, FILTER(ErrorMessages, ErrorArray, ""),
// Procedure
fieldnames, Record.FieldNames(_record),
Result, MAKEARRAY(
2,
COUNTA(ISERROR(_fields)),
LAMBDA(ir, ic,
LET(
colname, INDEX(_fields, ic),
colpos, List.PositionOf(fieldnames, colname),
CHOOSE(ir, INDEX(_fields, ic), INDEX(_record, 2, colpos))
)
)
),
// Handle Error
Error, IF(OR(ErrorArray), 3, IF(OR(ISERROR(Result)), 2, 1)),
// Return Result
CHOOSE(Error, Result, Help, Messages)
)
);
ToList = LAMBDA(_record, TRANSPOSE(INDEX(_record, 2, 0)));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment