Excel Power Pivot - Nested IF OR Formula error - excel

I have been trying to use the formula mentioned below which is not working and showing an error message stating "Power pivot expression that yield variant data-type cannot be used to define calculated columns"
IF (
OR ( Table2[TeamStatus] = "Lost", Table2[TeamStatus] = "Won't proceed" ),
"0",
IF (
OR ( Table2[TeamStatus] = "Next level", Table2[TeamStatus] = "Disqualified" ),
"0",
IF (
AND ( YEAR( Table2[Match Date] ) = YEAR( TODAY() ), [TeamStatus] <> "Won" ),
[Spent Amount],
0
)
)
)
Data types of the columns
1) [TeamStatus] = Text
2) [Match Date] = Date
3) [Spent amount] = Number
The purpose of this formula is to exclude the following rows from [TeamStatus] column (i.e. in the [TeamStatus] column is having "Lost", "Won't proceed", "Next Level", "Disqualified" texts) then the output should be zero and then calculate the spent amount for all other categories in [TeamStatus] column and another condition (i.e. if the year is current year) is met.
I have been trying from past 1 day to make this formula work and no luck. I also tried using FORMAT() function and still it is not working.
Can someone please help me?

The error is saying that your formula should either return a number or text but not sometimes a number and sometimes text.
Notice that your formula sometimes returns "0" and sometimes returns 0.
Either change the first two zeros to be numbers instead of text or else change the last zero to text and use FORMAT on [Spent Amount] to convert it to text.
As a side note, can't your formula be simplified to just?
IF (
AND ( YEAR ( Table2[Match Date] ) = YEAR ( TODAY () ), [TeamStatus] = "Won" ),
[Spent Amount],
0
)

Related

Comparing values of type Integer with values of type Text

Could someone please explain to me why I'm getting this error:
DAX comparison operations do not support comparing values of type
Integer with values of type Text. Consider using the VALUE or FORMAT
function to convert one of the values.
I'm trying to count a text value if it meets the condition stated in below script. The values I'm comparing both are of the same format(whole number). The condition is based on 2 different tables.
IF (
CALCULATE (
COUNTA ( 'tbl1'[type] ),
FILTER ( 'tbl1', 'tbl1'[Memno] = 'tbl2'[mempersonid] )
) = "",
"No engagement",
CALCULATE (
COUNTA ( 'tbl1'[type] ),
FILTER ( 'tbl1', 'tbl1'[Memno] = 'tbl2'[mempersonid] )
)
)
It's almost certain that of the two columns being compared ( 'tbl1'[Memno] and 'tbl2'[mempersonid] ), one is an Integer and one is Text.
They may LOOK the same, but check the actual data types.
If [Memno] and [mempersondid] are indeed both whole numbers, then the issue is with
CALCULATE ( COUNTA ( ... ), ... ) = ""
CALCULATE returns a number and you are trying to compare with the empty string "".
Try this instead:
VAR TypeCount =
CALCULATE (
COUNTA ( 'tbl1'[type] ),
FILTER ( 'tbl1', 'tbl1'[Memno] = 'tbl2'[mempersonid] )
)
RETURN
IF ( ISBLANK ( TypeCount ), "No engagement", TypeCount )

INDEX returns wrong value and no value

I'm trying to find matching values and sort them in a column.
Column A contains Names and Column B Training Done by person in Column A.
An example of my data can be seen here:
Having that data, I want to get a separate table with two Columns(Name and training). In Column C, I want the names and in Column D I want the training done by who is in Column C.
=IFERROR(INDEX($B$2:$B$7,SMALL(IF($C2=$A$2:$A$7,ROW($A$2:$A$7)-1,""),ROWS($D$1:D1))),"No training done")
I've tried using the above formula, but it seems to only work for the first entry in the table. I can't figure out what i should change.
This is what I get
It shows "No training done" to people who have had training and there's a "0" where it should be "No training done".
This is my expected result:
L.E : Anna did Excel. A mistake on my part in the above picture. Also, I'm only interested in the Training Column, as I already got the hang of the formula to order the names.
Thank you.
Enter this formula in D2:D7:
= IFERROR( INDEX( $A$2:$A$7,
AGGREGATE( 15, 6,
MATCH( $A$2:$A$7, $A$2:$A$7, 0 ),
ROWS( B2:B$2 ) ) ), "" )
Then enter this formula in E2:E7
= IFERROR( TRIM( SUBSTITUTE( REPT( " ", 3 ) & INDEX( $B$2:$B$7,
AGGREGATE( 15, 6,
ROW(E:E) / ( ( $A$2:$A$7 = D2 ) * 1 ),
COUNTIF( D$2:D2, D2) ) ) & REPT( " ", 3 ), REPT( " ", 6 ), "No Training done" ) ), "" )
=INDEX(Training,AGGREGATE(15,6,1/(C2=Names)*ROW(Names),COUNTIF($C$2:$C2,$C2))-1)
In this instance, I used a custom format for the result of: ;;"No Training Done";#
but, if you don't mind a longer formula, you can use an IF function to return the No Training Done statement in the event the formula returns nothing.
=IF(INDEX(Training,AGGREGATE(15,6,1/(C2=Names)*ROW(Names),COUNTIF($C$2:$C2,$C2))-1)=0,"No Training Done",INDEX(Training,AGGREGATE(15,6,1/(C2=Names)*ROW(Names),COUNTIF($C$2:$C2,$C2))-1))
Also, you can use whole-column references if you want. If you do that, remove the -1 as you won't have to adjust for the header row.
If you wanted to use Power Query aka Get&Transform, it would just be a matter of replacing the null with No Training Done and then sorting the result per your desired order. That can all be done from the PQ Editor GUI, and below is the M-code
M-Code
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Names", type text}, {"Training", type text}}),
#"Replaced Value" = Table.ReplaceValue(#"Changed Type",null,"No Training Done",Replacer.ReplaceValue,{"Training"}),
#"Sorted Rows" = Table.Sort(#"Replaced Value",{{"Names", Order.Ascending}})
in
#"Sorted Rows"
The easiest way will be:
1) Copy and paste your information to columns C:D
2) On cell A:2 place =COUNTIF($C$2:C2,C2) and drag it to your row range.
3) On cell B:2 place =C2&A2 and drag it to your row range.
4) On cell E:2 place =B2 and drag it to your row range.
5) On cell F:2 place =IF(VLOOKUP(E2,$B$2:$D$7,3,FALSE)="","",VLOOKUP(E2,$B$2:$D$7,3,FALSE))
6) Hide columns A:B
Hope it helps

Power bi How can i display items without data with a zero AND hide the months in the future

I'm using the following measure in order to make the charts display the periods that don't have a value. But the problem now is that it is displaying the months in the future.
x Count Tickets =
IF
(
ISBLANK
(
DISTINCTCOUNT('Tickets DB'[Número de Ticket])
)
,0,
DISTINCTCOUNT('Tickets DB'[Número de Ticket])
)
How can I avoid the months in the future from displaying?
I also tried the following measure:
x Count Tickets =
IF
(
DATEDIFF(MAX('Tickets DB'[Fecha]),TODAY(),DAY)>0,
IF
(
ISBLANK
(
DISTINCTCOUNT('Tickets DB'[Número de Ticket])
)
,0,
DISTINCTCOUNT('Tickets DB'[Número de Ticket])
)
)
But it is not displaying months without data
Thanks in advance.
1. First create a calculated column(calendar dimension table), to return if there is a record on all dates of this dimension
example of calculated column
2.
Create the measurement below (
Where you will change the context of the measurement to bring only the true fields from the column you created earlier)
Medida Stack =
CALCULATE(
DISTINCTCOUNT(
fVendas[CLIENTE/LOJA]);
CALCULATETABLE(
dCalendario;
dCalendario[Has Sales?]=TRUE()
)
)
fvendas[Cliente/loja] = 'Tickets DB'[Número de Ticket]
dCalendario = calendar dimension table
If it is always the dates in the future you want to hide, you could opt for relative date filtering on your visual. More info here
IF (
MAX ( 'DimDate'[Date] ) > TODAY (),
BLANK (),
DISTINCTCOUNT ( 'Tickets DB'[Número de Ticket] ) + 0
)
Starting from your original measure, we check whether the date in context is after today's date. In that case, we blank the measure. Otherwise we do your DISTINCTCOUNT, which may possibly return a blank value. Note that DAX blanks are not equivalent to SQL NULLs - specifically addition with a blank returns a number, unless both addends are blank; so BLANK () + 0 = 0. This neatly solves your display for months with no data. But we only execute this logic for past months.
Note, I've written this assuming that you have a date table. If you don't, you should get one. I like mine, but there are plenty of good ones out there.
Create a calendar table using something like the following:
Calendar =
VAR MinDate = MIN('Tickets DB'[Fecha])
VAR MaxDate = MAX('Tickets DB'[Fecha])
VAR BaseCalendar =
CALENDAR ( MinDate, MaxDate )
RETURN
GENERATE (
BaseCalendar,
VAR Basedate = [Date]
VAR YearDate =
YEAR ( Basedate )
VAR MonthNumber =
MONTH ( Basedate )
VAR YrMonth = 100 * YearDate + MonthNumber
VAR Qtr =
CONCATENATE ( "Q", CEILING ( MONTH ( Basedate ) / 3, 1 ) )
VAR QtrYr = YearDate & " " & Qtr
RETURN
ROW (
"Day", Basedate,
"Year", YearDate,
"Month Number", MonthNumber,
"Month", FORMAT ( Basedate, "mmmm" ),
"Year Month", FORMAT ( Basedate, "mmm yy" ),
"YrMonth", YrMonth,
"Qtr", Qtr,
"QtrYr", QtrYr
)
)
If you have dates in the future in your table, replace the MAX('Tickets DB'[Fecha]) part to NOW() then just create a relationship from your 'Tickets DB' table to this calendar table on both date fields and that should correct the issue (and allow you to use time intelligence functions). Once this is set up correctly your measure should work just fine.
Hope it helps.

how to apply Calculate function with two filters in DAX to get the Running Sum

I would like to get the running sum of [Days Past Due] Column grouped by project number and for each project number, get the value for each phase/end date.
IN SQL I would do:
SELECT Project_number
,phase
,Sum(Days Past Due) RunningTotal
FROM Table
GROUP BY Project_number
,phase
ORDER BY Project_number
,phase
I would do something similar in DAX please.
I try that:
CALCULATE (
SUM ( DataSource[Days Past Due] ),
ALLEXCEPT ( DataSource, DataSource[Project Number] )
)
It gives me the total for each project number repeated in the 4 rows. That's not what I want exactly. I need to apply a second filter on that.
Please look at the attachment, it has the last column with the desired output.
Thank you in advance for your suggestions.
You can adjust your attempt like this:
Cumulative Days Past Due =
CALCULATE(
SUM( DataSource[Days Past Due] ),
FILTER(
ALLEXCEPT( DataSource, DataSource[Project Number] ),
DataSource[End Date] <= MAX( DataSource[End Date] )
)
)
Note that you can include more filtering conditions in the FILTER function by joining more conditions with &&. You can add more filter conditions inside CALCULATE as well. Here's an example:
Cumulative Days Past Due =
CALCULATE(
SUM( DataSource[Days Past Due] ),
FILTER(
ALLEXCEPT( DataSource, DataSource[Project Number] ),
DataSource[End Date] <= MAX( DataSource[End Date] )
&& DataSource[Start Date] > DATE( 2018, 12, 31 )
),
DataSource[Phase] = "Scope"
)
The documentation for CALCULATE and FILTER might be useful for further clarification:
https://dax.guide/calculate/
https://learn.microsoft.com/en-us/dax/calculate-function-dax
https://dax.guide/filter/
https://learn.microsoft.com/en-us/dax/filter-function-dax
If you are trying to write this formula in a calculated column, it will not work as expected and you will need to use EARLIER instead of MAX:
Cumulative Days Past Due =
CALCULATE(
SUM( DataSource[Days Past Due] ),
FILTER(
ALLEXCEPT( DataSource, DataSource[Project Number] ),
DataSource[End Date] <= EARLIER( DataSource[End Date] )
)
)
The reason for this is that in a measure MAX is calculated within its local filter context but in a calculated column the context is different and you use EARLIER to refer to the earlier row context, that is, the End Date in the current row of the larger table (rather than the smaller FILTER table).
If you want something that works either as a measure or a calculated column, then #RADO's solution is pretty close and you can write this:
Cumulative Days Past Due =
VAR CurrDate =
CALCULATE( MAX( DataSource[Start Date] ) )
RETURN
CALCULATE(
SUM( DataSource[Days Past Due] ),
ALLEXCEPT( DataSource, DataSource[Project Number] ),
DataSource[End Date] <= CurrDate
)
In this version, the MAX works just as it did before in the first version above and it should also work in a calculated measure because wrapping the MAX in a CALCULATE performs a context transition that transforms the row context into a filter context corresponding to that single row.
You can drop the CALCULATE wrapper for just a measure and drop both the CALCULATE and MAX functions for a simpler calculated column. In either of these cases, this variable version is likely the more performant one since the ALLEXCEPT function is optimized to work efficiently within CALCULATE rather than having to instantiate a new table when using FILTER.
For further details on cumulative totals, I recommend DAX Patterns as a resource:
https://www.daxpatterns.com/cumulative-total/

Searching for DAX formula - equivalent to Excel SUMIF

I am searching for a DAX formula.
Specifically:
If SOLD (1st column) = count volume (second column), if not SOLD = 0
I need to reflect the volume of SOLD in a new column. UNSOLD Volumes should be 0.
I attach the reduced data set.
If I understand, you want to only perform aggregation when the SOLD_UNSOLD column is equal to "SOLD", otherwise return 0? If so, the following formula will do this, you'll just need to update the column names accordingly. The outer IF prevents problems resulting from further evaluation (i.e. grand totals) and it's necessary to wrap the column in the VALUES function as this will turn the column into a table of the unique values of it.
'YourTable'[CountOfSold] =
IF (
COUNTROWS ( VALUES ( YourTable[SOLD_UNSOLD] ) ) = 1,
IF (
VALUES ( YourTable[SOLD_UNSOLD] ) = "SOLD",
COUNT ( YourTable[ColumnToAggregate] ),
0
),
0
)
The Excel SUMIF is closest to the DAX SUMX.
I'm not positive I'm understanding what you are asking for, but I think you'd want something like this:
SOLD_VOLUME = SUMX(Table1,
IF(Table1[SOLD_UNSOLD] = "SOLD",
Table1[DAILY_VOLUME],
0
)
)
You could also do this with a filter:
SOLD_VOLUME = SUMX(
FILTER(
Table1,
Table1[SOLD_UNSOLD] = "SOLD"
),
Table1[DAILY_VOLUME]
)

Resources