Hi @corkemp,
Paste this M code into a new blank query.
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("vVZLb9swDP4rhoEBG5aDHlaS5bj0sUMLBMthh6IHFzFaD4lTuMk27NdPsiyalGQn8YYVaix/oviJFB9+eEjTSbrLJwlnyfe80i92bEoNcQL93GtIUCkDSQL9qDWUEei3Ua8I1DDOQsZ5yPgJQY+T5rzc/IsFY+aZLbhqMaH/JZoPrV0+N+TXv/KdfvlSwhmv27MtX/TPVaF/PpcObsRudrlbXoHMrflZv4KWm9psfHMyq2u3vHx1W5z9q/y1qJMq3xnQvnDQY8e6rJ63RUIWCSZ6pUXP9saa55eiXiR35duhqLRMklebpC7yjZ4HUt/q8gB4jDwqiOy8Otb5odwbPzJz1/a67aAA44tM2adD9ZS3T6XoBg3J9imY2w1L/tMtARMPZZ0atMQVZeJITXOJ2+NbItQ7ezTpG4cA/cY7fYhCzFrtYiFk64BupzFcAH3m0D5lMO0EwGIpwb1oR4bc2QmgKaJ3qLN+fcjrQ3IomxDm/uVSoJm2qY4uEaEZHCsucFJDXCA4zL9R2VQRnTfO+swnJACKQC5pdLfotJtmWAAFgmCggUR6MEUC7WEkjfeYylgUdfRIwLc+ef9RZ8AHe3LpOyGeApTPpYB2gpzbEEM74ylgwmUwBZAAOGE4BahAJAWQADjBNpKmvH9dp21HSLtWkraNxI6rOsU9xCF+B0Hra9Bsx31+bvdY7ndPZVVsaAPwUDGwQ/QqMefcH6tNU9hPdRIsSZpE/Ci94sjruKeQFCFPSD3OgqnbiVCUjXRVME8fTWyknXQSCHqN+r2ChHQkeEGjS43gLdACfcTfFEme7uwKW0L3RTIETLIuH+oBeJr5djHiQvJGgd76e2atHyLr5/Vru8RlEGhVeFvcCwxvGQUq7xT6QQcLNO4QdYwsUtRRAPpWoZotcXmD4qn8j5kxoWhsiIaiaVC+cX8fim0t1uPOfKrfH0HszHFb9y4GNXfcGPpYHihy7opdiFxKG1SWqHldfQq87i7uUlbcLuOspH6kw3XjzBEUhBgvyu/Uz+tsFKs8w8dh/tGd+guIzUa42vsy6SGH/FhuLyVI/0d2nGr9PqWXIWzIAf2DNvQ+62hysIWa4m/Li9hOh8lAUlw6xiSDGJcBxrqJyvjU/M3OIqR5IMZ7daKUYHOp//p5H/8A", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Column1 = _t, Column2 = _t, Column3 = _t, Column4 = _t, Column5 = _t, Column6 = _t, Column7 = _t, Column8 = _t, Column9 = _t, Column10 = _t, Column11 = _t, Column12 = _t, Column13 = _t, Column14 = _t, Column15 = _t, Column16 = _t, Column17 = _t, Column18 = _t, Column19 = _t, Column20 = _t, Column21 = _t, Column22 = _t, Column23 = _t, Column24 = _t, Column25 = _t, Column26 = _t, Column27 = _t, Column28 = _t]),
TransposeTable = Table.Transpose(Source),
ReplaceBlanksWithNull = Table.ReplaceValue(TransposeTable,"",null,Replacer.ReplaceValue,{"Column1"}),
FillDown = Table.FillDown(ReplaceBlanksWithNull,{"Column1"}),
PromoteHeaders = Table.PromoteHeaders(FillDown, [PromoteAllScalars=true]),
GetValues = Table.AddColumn(PromoteHeaders, "Custom", each
List.Zip(
{
List.ReplaceMatchingItems( Record.ToList( Record.SelectFields(_, List.Select( Table.ColumnNames(PromoteHeaders), each Text.StartsWith( _, "Exam", Comparer.OrdinalIgnoreCase )))), {{null, ""}}),
List.ReplaceMatchingItems( Record.ToList( Record.SelectFields(_, List.Select( Table.ColumnNames(PromoteHeaders), each Text.StartsWith( _, "Paper", Comparer.OrdinalIgnoreCase )))), {{null, ""}}),
List.ReplaceMatchingItems( Record.ToList( Record.SelectFields(_, List.Select( Table.ColumnNames(PromoteHeaders), each Text.StartsWith( _, "Start", Comparer.OrdinalIgnoreCase )))), {{null, ""}}),
List.ReplaceMatchingItems( Record.ToList( Record.SelectFields(_, List.Difference( List.Select( Table.ColumnNames(PromoteHeaders), each Text.StartsWith( _, "End Time", Comparer.OrdinalIgnoreCase )), List.Select( Table.ColumnNames(PromoteHeaders), each Text.StartsWith( _, "End time ", Comparer.OrdinalIgnoreCase ))))), {{null, ""}}),
List.ReplaceMatchingItems( Record.ToList( Record.SelectFields(_, List.Select( Table.ColumnNames(PromoteHeaders), each Text.StartsWith( _, "End time ", Comparer.OrdinalIgnoreCase )))), {{null, ""}})
}
)
)[[Column1], [Custom]],
ExpandValues = Table.ExpandListColumn(GetValues, "Custom"),
ExtractValues = Table.TransformColumns(ExpandValues, {"Custom", each Text.Combine(List.Transform(_, Text.From), ";"), type text}),
SelectRows = Table.SelectRows( ExtractValues, each Text.Length( [Custom] ) <>4 ),
SplitColumn = Table.SplitColumn(SelectRows, "Custom", Splitter.SplitTextByDelimiter(";", QuoteStyle.Csv), {"Custom.1", "Custom.2", "Custom.3", "Custom.4", "Custom.5"}),
RenameCols = Table.RenameColumns(SplitColumn,{{"Column1", "Date"}, {"Custom.1", "Subject"}, {"Custom.2", "Paper name"}, {"Custom.3", "Start time"}, {"Custom.4", "End time"}, {"Custom.5", "End time (+25%)"}})
in
RenameCols
.
Snip of the result
I hope this is helpful