I have a Google Sheets spreadsheet with a query formula and I'm trying to recreate this in Excel. I thought Power Query would be the right place, but it doesn't seem to be available in 365 online.
I tried building a pivot table and got some what close, but it's missing months that have no data.
This is my Google Sheets formula
where F != 0
group by E
order by sum(F) desc
label sum(F) ''",0)
The formula spits out something like this:
(I included the headers in my screenshot, but they are not part of the query formula)
In my pivot table, this is the output
I have a helper table of all the months in the time period selected (they're dynamic based on the starting month the user selects), but I don't see a way of referencing that in my sheet.
Before I go buy a subscription to get the desktop version of Excel to work with Power Query, is there something I can do here to get the pivot table to do what I want?
Any help is appreciated.
Interesting approach... see if this is what you are looking for:
Assume you are given data set like this:
Formula:
=LAMBDA(RANGE,
LAMBDA(REVENUE,DATE,VALUE,
LAMBDA(UREVENUE,UDATE,VALUE,
LAMBDA(PIVOT,
HSTACK(
VSTACK("REVENUE",UREVENUE),
BYROW(PIVOT,LAMBDA(ROW,IF(NOT(ISNUMBER(INDEX(ROW,1))),"TOTAL",SUM(ROW)))),
PIVOT
)
)(
MAKEARRAY(COUNTA(UREVENUE)+1,COUNTA(UDATE),LAMBDA(ROW,COL,
IFS(
ROW=1,INDEX(UDATE,COL),
TRUE,SUM(FILTER(VALUE,(REVENUE=INDEX(UREVENUE,ROW-1))*(DATE=INDEX(UDATE,COL)),0))
)
))
)
)(UNIQUE(REVENUE),UNIQUE(DATE),IF(VALUE="",0,VALUE))
)(INDEX(RANGE,,1),INDEX(RANGE,,2),INDEX(RANGE,,3))
)($A$2:$C$19)
This formula mainly uses MAKEARRAY() with INDEX() to recreate the output of google QUERY().
name $A$2:$C$19 as RANGE with LAMBDA(),
name Col1,Col2,Col3 of RANGE as REVENUE,DATE,VALUE with LAMBDA(),
get unique values of REVENUE and DATE with UNIQUE(),
fill in 0 for empty values in VALUE with IF(),
name the unique values as UREVENUE and UDATE, and update the values of VALUE with LAMBDA(),
get pivot sum of REVENUE and DATE with MAKEARRAY(), which COUNTA(UREVENUE)+1 as number of ROW, and COUNTA(UDATE) as number of COL,
the reason why we need to +1 in ROW count, is because that we have to add a header row for the pivoted data,
inside MAKEARRAY(), fill in every CELL with IFS() according to some conditions,
when ROW index is 1, it should be the header row, so return the value of UDATE as header, INDEX() here determines which value of UDATE should be shown according to the COL index,
when ROW index is not 1, FILTER() the data of VALUE according to UREVENUE and UDATE, same as step 9, we use INDEX() to determines which value of the given data sets are we referencing, SUM() the result of FILTER() to form a single value for each CELL,
name the result of MAKEARRAY() as PIVOT with LAMBDA(),
get SUM() of each ROW in PIVOT with BYROW(),
stack the outputs with VSTACK() and HSTACK() to form the result.
Just noticed that you have mentioned about there is another table to select the data you would like to display according to months, so I updated the formula, and also separated the header part from MAKEARRAY() so the whole thing may hopefully looks logically easier to understand:
=LAMBDA(DATARANGE,SELECTED,HEADERS,
LAMBDA(REVENUE,DATE,VALUE,SELECTED,
LAMBDA(UREVENUE,VALUE,
LAMBDA(PIVOT,HEADERS,
LAMBDA(TOTAL,
VSTACK(HEADERS,HSTACK(UREVENUE,TOTAL,PIVOT))
)(BYROW(PIVOT,LAMBDA(ROW,SUM(ROW))))
)(
MAKEARRAY(COUNTA(UREVENUE),COUNTA(SELECTED),LAMBDA(ROW,COL,
SUM(FILTER(VALUE,(REVENUE=INDEX(UREVENUE,ROW))*(DATE=INDEX(SELECTED,COL)),0))
)),
HSTACK(HEADERS,TRANSPOSE(SELECTED))
)
)(UNIQUE(REVENUE),IF(VALUE="",0,VALUE))
)(INDEX(DATARANGE,,1),INDEX(DATARANGE,,2),INDEX(DATARANGE,,3),TRIM(TEXTSPLIT(SELECTED,,",")))
)($A$2:$C$19,$F$1,HSTACK("REVENUE","TOTAL"))
name $A$2:$C$19 as DATARANGE, $F$1 as SELECTED, HSTACK("REVENUE","TOTAL") as HEADERS with LAMBDA(), which the two texts inside HEADERS would be the titles of output column 1 and 2,
name Col1,Col2,Col3 of DATARANGE as REVENUE,DATE,VALUE, and TEXTSPLIT() SELECTED into an ARRAY, apply TRIM() on the ARRAY to get rid of extra spacing if there is any, and update it as values of SELECTED with LAMBDA(),
get unique values of REVENUE with UNIQUE(), and fill in 0 for empty values in VALUE with IF(),
name the unique values as UREVENUE, and update the values of VALUE with LAMBDA(),
update values of HEADERS, HSTACK() it with TRANSPOSE(SELECTED) to form the complete HEADERS,
get pivot sum of REVENUE and DATE with MAKEARRAY(), which COUNTA(UREVENUE) as number of ROW, and COUNTA(SELECTED) as number of COL,
inside MAKEARRAY(), fill in every CELL with FILTER(), filter the data of VALUE according to UREVENUE and SELECTED, uses INDEX() to determines which value of the given data are we referencing as criteria, SUM() the result of FILTER() to form a single value for each CELL, name the result of MAKEARRAY() as PIVOT with LAMBDA(),
get SUM() of each ROW in PIVOT with BYROW(), name the result of BYROW() as TOTAL with LAMBDA(),
stack the outputs with VSTACK() and HSTACK() to form the final result.
Some SORT() is added to help rearrange the output data if needed, controlled by the value of SORTREVENUE,SORTTOTAL,SORTPIVOT.
In the 1st LAMBDA(), pass ASC or DESC to activate related SORT(), or leave it blank to turn that SORT() off.
Be noticed, sort result of SORTTOTAL will overwrite sort result of SORTREVENUE.
=LAMBDA(DATARANGE,SELECTED,HEADERS,SORTREVENUE,SORTTOTAL,SORTPIVOT,
LAMBDA(REVENUE,DATE,VALUE,SELECTED,MONTHS,
LAMBDA(UREVENUE,SELECTED,
LAMBDA(PIVOT,HEADERS,
LAMBDA(TOTAL,
VSTACK(
HEADERS,
LAMBDA(OUTPUT,ASC,DESC,
IF(OR(ASC,DESC),SORT(OUTPUT,2,IF(DESC,-1,ASC)),OUTPUT)
)(HSTACK(UREVENUE,TOTAL,PIVOT),SORTTOTAL="ASC",SORTTOTAL="DESC")
)
)(BYROW(PIVOT,LAMBDA(ROW,SUM(ROW))))
)(
MAKEARRAY(COUNTA(UREVENUE),COUNTA(SELECTED),LAMBDA(ROW,COL,
SUM(FILTER(VALUE,(REVENUE=INDEX(UREVENUE,ROW))*(DATE=INDEX(SELECTED,COL)),0))
)),
HSTACK(HEADERS,TRANSPOSE(SELECTED))
)
)(
LAMBDA(REVENUE,ASC,DESC,
IF(OR(ASC,DESC),SORT(REVENUE,,IF(DESC,-1,ASC)),REVENUE)
)(UNIQUE(REVENUE),SORTREVENUE="ASC",SORTREVENUE="DESC"),
LAMBDA(TEXT,NUM,ASC,DESC,
IF(OR(ASC,DESC),
XLOOKUP(SORT(XLOOKUP(SELECTED,TEXT,NUM),,IF(DESC,-1,ASC)),NUM,TEXT),
SELECTED
)
)(INDEX(MONTHS,,1),INDEX(MONTHS,,2),SORTPIVOT="ASC",SORTPIVOT="DESC")
)
)(
INDEX(DATARANGE,,1),
INDEX(DATARANGE,,2),
INDEX(DATARANGE,,3),
TRIM(TEXTSPLIT(UPPER($F$1),,",")),
HSTACK({"JAN";"FEB";"MAR";"APR";"MAY";"JUN";"JUL";"AUG";"SEP";"OCT";"NOV";"DEC"},SEQUENCE(12))
)
)($A$2:$C$19,$F$1,HSTACK("REVENUE","TOTAL"),"DESC","DESC","DESC")