Excel PQ - transform manually created dashboard to suitable for analysis form

Excel PQ - transform manually created dashboard to suitable for analysis form

I believe many of you have seen such kind of manually created dashboard, usually even more complex

No alt text provided for this image

But what can we do with it except showing to stakeholders? If we'd like to make more deep analysis (Month over Month rate, country to country, etc., etc.) and have no access to source data that's only way to create another bunch of rows and columns.

No alt text provided for this image

Or transform it for more friendly for data analysis form. That what Power Query is for. Let try to transform into such form.


First, name dashboard area as "range" and query it. Do nothing with it and reference as Blocks query

No alt text provided for this image

Just remember that columns are by default named as Column1, Column2, etc.

No alt text provided for this image

Keep only first row in this table, transpose it, rename as Country and Fill Down.




Next replace null on "Header" and Add Index column starting from 1, when group by Country column without aggregation

No alt text provided for this image
No alt text provided for this image

We don't need entire table here, only Index which is actually column numbers for each block. Modify in formula bar as


No alt text provided for this image

To have actual column names let add another custom column:


Remove Count column and add customer column with =range formula

No alt text provided for this image

We don't need first row here, skip it

No alt text provided for this image

and select only related to block columns using Columns

No alt text provided for this image

Finally promote headers and add Index column to each table

No alt text provided for this image

This query code

let
? ? Source = range,
? ? #"Kept First Rows" = Table.FirstN(Source,1),
? ? #"Transposed Table" = Table.Transpose(#"Kept First Rows"),
? ? #"Renamed Columns" = Table.RenameColumns(
? ? ? ? #"Transposed Table",
? ? ? ? {{"Column1", "Country"}}
? ? ),
? ? #"Filled Down" = Table.FillDown(
? ? ? ? #"Renamed Columns",
? ? ? ? {"Country"}
? ? ),
? ? #"Name for Null" = Table.ReplaceValue(
? ? ? ? #"Filled Down",
? ? ? ? null,"Header",
? ? ? ? Replacer.ReplaceValue,{"Country"}
? ? ),
? ? #"Added Index" = Table.AddIndexColumn(
? ? ? ? #"Name for Null",
? ? ? ? "Index", 1, 1, Int64.Type
? ? ),
? ? #"Grouped Rows" = Table.Group(
? ? ? ? #"Added Index",
? ? ? ? {"Country"}, {{"Count", each _[Index]}}
? ? ),
? ? #"Added Custom" = Table.AddColumn(
? ? ? ? #"Grouped Rows",
? ? ? ? "Columns",
? ? ? ? each List.Transform([Count], each "Column" & Text.From(_))
? ? ),
? ? #"Removed Columns" = Table.RemoveColumns(
? ? ? ? #"Added Custom",
? ? ? ? {"Count"}
? ? ),
? ? #"Added Custom1" = Table.AddColumn(
? ? ? ? #"Removed Columns",
? ? ? ? "range",
? ? ? ? each
? ? ? ? ? ? Table.AddIndexColumn (
? ? ? ? ? ? ? ? Table.PromoteHeaders (
? ? ? ? ? ? ? ? ? ? Table.SelectColumns (
? ? ? ? ? ? ? ? ? ? ? ? Table.Skip (range),
? ? ? ? ? ? ? ? ? ? ? ? [Columns]
? ? ? ? ? ? ? ? ? ? )
? ? ? ? ? ? ? ? ),
? ? ? ? ? ? ? ? "Index",1,1,Int64.Type
? ? ? ? ? ? )
? ? ),
? ? #"Remove Lists" = Table.RemoveColumns(
? ? ? ? #"Added Custom1",{"Columns"}
? ? )
in
? ? #"Remove Lists"        
? ??        
No alt text provided for this image

Reference above query as FirstBlock, filter on "Headers" value and expand range column:

No alt text provided for this image

Reference again Blocks query as Combined, unselect "Headers" in Country column and Add Custom column with FirstBlock table.

Now we need to join first block with each country table in "ranges" column. Use not very well known Table.Join() function which is missed in user interface:

No alt text provided for this image

Keep only Country and Data columns, expand the latest, remove Index column and unpivot all columns with Models

No alt text provided for this image

Now is only to pivot on types not to keep units and money in one column and apply proper data types

No alt text provided for this image

This query code

let
? ? Source = Blocks,
? ? #"Filtered Rows" = Table.SelectRows(
? ? ? ? Source,
? ? ? ? each ([Country] <> "Header")
? ? ),
? ? #"Added Custom" = Table.AddColumn(
? ? ? ? #"Filtered Rows",
? ? ? ? "FirstBlock",
? ? ? ? each FirstBlock
? ? ),
? ? #"Join with FirstBlock" = Table.AddColumn(
? ? ? ? #"Added Custom",
? ? ? ? "Data",
? ? ? ? each Table.Join([FirstBlock], "Index", [range], "Index")
? ? ),
? ? #"Removed Other Columns" = Table.SelectColumns(
? ? ? ? #"Join with FirstBlock",
? ? ? ? {"Country", "Data"}
? ? ),
? ? #"Expanded Data" = Table.ExpandTableColumn(
? ? ? ? #"Removed Other Columns",
? ? ? ? "Data",
? ? ? ? {"Month", "Type", "Index", "Model 1", "Model 2", "Model 3"}
? ? ),
? ? #"Remove Index" = Table.RemoveColumns(
? ? ? ? #"Expanded Data",
? ? ? ? {"Index"}
? ? ),
? ? #"Unpivot Models" = Table.UnpivotOtherColumns(
? ? ? ? #"Remove Index",
? ? ? ? {"Country", "Month", "Type"},
? ? ? ? "Model", "Value"
? ? ),
? ? #"Pivot Types" = Table.Pivot(
? ? ? ? #"Unpivot Models",
? ? ? ? List.Distinct(#"Unpivot Models"[Type]),
? ? ? ? "Type", "Value"
? ? ),
? ? #"Changed Type" = Table.TransformColumnTypes(
? ? ? ? #"Pivot Types",
? ? ? ? {
? ? ? ? ? ? {"Units", Int64.Type},
? ? ? ? ? ? {"Sales", Currency.Type},
? ? ? ? ? ? {"Country", type text},
? ? ? ? ? ? {"Model", type text},
? ? ? ? ? ? {"Month", type text}
? ? ? ? }
? ? )
in        
? 
? #"Changed Type"        
No alt text provided for this image

One more cosmetic thing is not to keep months as texts but transform to dates using end of each month dates for month indication.

Several ways to do that, we may use query as


let
? ? year = Date.Year(DateTime.LocalNow()),
? ? Source = List.Dates(#date(year, 1, 1), 12, #duration(32,0,0,0)),
? ? #"Converted to Table" = Table.FromList(
? ? ? ? Source,
? ? ? ? Splitter.SplitByNothing()
? ? ),
? ? #"Renamed Columns" = Table.RenameColumns(
? ? ? ? #"Converted to Table",
? ? ? ? {{"Column1", "Month"}}
? ? ),
? ? #"Calculated End of Month" = Table.TransformColumns(
? ? ? ? #"Renamed Columns",
? ? ? ? {{"Month", Date.EndOfMonth, type date}}
? ? ),
? ? #"Inserted Month Name" = Table.AddColumn(
? ? ? ? #"Calculated End of Month",
? ? ? ? "Month Name",
? ? ? ? each Date.MonthName([Month]),
? ? ? ? type text
? ? ),
? ? #"Extracted First Characters" = Table.TransformColumns(
? ? ? ? #"Inserted Month Name",
? ? ? ? {{"Month Name", each Text.Start(_, 3), type text}}
? ? )
in        
? 
? #"Extracted First Characters"        

Finally merge Combined query with MonthNames to extract dates and remove texts with month names

No alt text provided for this image
No alt text provided for this image

Now we are prepared for more deep analysis of our data. We may land above table to the grid, click on Analyze Data icon, ask to aggregate our data in such way or another


No alt text provided for this image

and immediately receive the result as this PivotTable or PivotChart.

Or use data model for more advance analysis, perhaps combining with other data we have.


Sample file is here

Cassandra O.

Principal Finance Officer East Sussex County Council Children's Services 2024 & Adult Social Care & Health 2023

3 年

Another nice piece of data analysis. Would I be correct in saying you used Power Query to unpivot the original data

要查看或添加评论,请登录

Sergei Baklan的更多文章

社区洞察

其他会员也浏览了