Skip to content

Instantly share code, notes, and snippets.

View m-dekorte's full-sized avatar

Melissa de Korte m-dekorte

View GitHub Profile
@m-dekorte
m-dekorte / findMinMaxDates.pq
Last active June 16, 2025 05:45
findMinMaxDates M function | Find the Min and Max dates across multiple queries and/ or columns, for example to set up a dynamic date table. This method leverages the Table.Profile function and handles known limitations such as null and/ or inconsistent/ missing column types.
let
fxFindMinMaxDates = (tableNames as list, optional dateColsID as text, optional excludeDateColNames as list) as record =>
let
selectedTables = Record.SelectFields(
#sections[Section1],
tableNames,
MissingField.Ignore
),
rawData = Table.RemoveColumns(
Table.Combine(Record.ToList(selectedTables)),
@m-dekorte
m-dekorte / extractEightDigitSequence.pq
Last active June 11, 2025 12:52
extractEightDigitSequence M function | Extract only 8 digit sequences such as a date tag from a string.
let
fxExtractEightDigitSequence = let
extractEightDigitSequence = (txt as nullable text, optional Occurrence as number) =>
let
input = txt ?? "",
parts = Text.SplitAny(input, Text.Remove(input, {"0" .. "9"})),
digits = List.Select(parts, each Text.Length(_) = 8)
in
{List.First(digits), List.Last(digits), digits}{(Occurrence ?? 0)},
extractEightDigitSequenceType = type function (
@m-dekorte
m-dekorte / extractCharactersByCase.pq
Created April 20, 2025 12:32
extractCharactersByCase M function | Extract only letters of a specified case. Non‑letter characters (digits, punctuation, whitespace) are dropped.
let
extractCharactersByCase = (input as nullable text, optional caseType as text) as text =>
Text.Combine(
List.Select(
Text.ToList(input ?? ""),
(s) =>
if Text.Proper(caseType ?? "Upper") = "Upper"
then not (Text.Lower(s) = s)
else not (Text.Upper(s) = s)
)
@m-dekorte
m-dekorte / extendedDateTable.cs
Created March 11, 2025 11:34
Extended Date table C# script | Compatible with Tabular Editor versions TE2 and TE3
var dateTableName = "Dates"; // Name of your date table
var dateKeyColName = "Date"; // Name of the date key column in the table
var colOperations = new List<Tuple<string, string, bool>>(){
Tuple.Create("Quarter & Year", "QuarternYear", true),
Tuple.Create("Month & Year", "MonthnYear", true),
Tuple.Create("Month Name", "MonthOfYear", true),
Tuple.Create("Month Short", "MonthOfYear", true),
Tuple.Create("Month Initial", "MonthOfYear", true),
Tuple.Create("Week & Year", "WeeknYear", true),
Tuple.Create("Day of Week Name", "DayOfWeek", true),
@m-dekorte
m-dekorte / extendedDateTable.pq
Last active June 11, 2025 10:01
Extended Date table M function | Creates an ISO-8601 type calendar
let
fnDateTable = ( StartDate as date, EndDate as date, optional FYStartMonthNum as number, optional Holidays as list, optional WDStartNum as number, optional AddRelativeNetWorkdays as logical ) as table =>
let
FYStartMonth = List.Select({1..12}, each _ = FYStartMonthNum){0}? ?? 1,
WDStart = List.Select({0..1}, each _ = WDStartNum){0}? ?? 0,
CurrentDate = Date.From(DateTimeZone.FixedUtcNow()),
DayCount = Duration.Days(Duration.From(EndDate - StartDate)) + 1,
weekStart = Day.Monday,
HolidaysProvided = Holidays <> null,
@m-dekorte
m-dekorte / convertDateTo.pq
Last active June 11, 2025 10:01
convertDateTo* M function | Convert an input value like a date, datetime, datetimezone or text to a target type.
let
/* Function to convert an input value like a date, datetime, datetimezone, or text to a target type */
convertDateTo = let
fxConvertDateTo = (Value as any, ReturnType as text, optional Culture as any, optional formatString as text) as any =>
let
Separators = Text.Combine(List.Select(
Text.ToList(Text.Remove(Text.From(Value) ?? "", {"0" .. "9"})),
each Text.Lower(_) = Text.Upper(_) )
),
c = Culture ?? Culture.Current,
@m-dekorte
m-dekorte / colRenamesAndTypes.pq
Created February 28, 2025 14:28
colRenamesAndTypes Example | manage renaming columns and setting column data types
let
colTypes = [
#"any" = Any.Type,
#"date" = Date.Type,
#"time" = Time.Type,
#"datetime" = DateTime.Type,
#"logical" = Logical.Type,
#"number" = Number.Type,
#"currency" = Currency.Type,
#"integer" = Int64.Type,
@m-dekorte
m-dekorte / getAllSubstrings.pq
Last active June 11, 2025 10:01
getAllSubstrings M function | Generate all possible contiguous substring combinations from a string.
let
/* This was an exercise just for fun. Who knows, it might have a real-world application... */
/* Generate every possible substring combination from a string */
getAllSubstrings = (s as text, optional makeDistinct as logical, optional ignoreCase as logical) as list =>
let
c = if ignoreCase ?? false then Comparer.OrdinalIgnoreCase else Comparer.Ordinal,
n = Text.Length(s),
sub = List.TransformMany(
{0..n-1},
each {_+1..n},
@m-dekorte
m-dekorte / errorReport.pq
Created January 26, 2025 11:24
errorReport M function | Creates a record with overall error count and detailed error reporting table.
let
fxErrorReport = (myTable as table, optional keyCols as list, optional scanCols as list ) as record =>
let
colNames = Table.ColumnNames( myTable ),
validKeys = List.Intersect( { colNames, keyCols ?? {} } ),
hasKeys = List.Count( validKeys ) >0,
selCols = List.Intersect( { colNames, scanCols ?? {} } ),
nTable = Table.SelectColumns( myTable, if List.Count( selCols ) >0 then validKeys & selCols else colNames ),
reservedNames = { "Name", "Errors", "Reason", "Message", "Detail", "rowIndex", "nCol" },
nameViolations = List.Intersect( { colNames, reservedNames } ),
@m-dekorte
m-dekorte / profileWithErrorCount.pq
Created January 26, 2025 11:18
profileWithErrorCount M function | Creates a table profile with statistics, including an error count for all columns.
(t as table) as table =>
Table.Profile(t,
{{
"ErrorCount",
each true,
each Table.RowCount(Table.SelectRowsWithErrors(Table.FromColumns({_})))
}}
)