Power BI: How to dynamically change currency - powerbi

We have requirement to allow user to choose which currency he wants to see in the dashboard, like below example:
By default, it's GBP, if user changes to USD, we need to show the spend by USD. Under the hood we already have table InvoiceDetail which contains columns doing currency conversion beforehand:
SpendInGBP
SpendInUSD
SpendInEUR
I am not sure how I can map when user chooses different currency using ChicletSlicer to different Columns.

If you have a table containing all formats available to apply this can be achieved.
I've created these tables as example:
MyTable
CurrencyFormat
In the MyTable table I've created two measures called Format and Total Sales.
Format = LASTNONBLANK ( CurrencyFormat[Format], 1 )
Total Sales = Total Sales = FORMAT(SUM(MyTable[Sales]),[Format])
Note Total Sales measures uses the [Format] measure to get the selected format from the slicer.
Adding the ChicletSlicer and setting FormatName column from CurrencyFormat table in Category pane, you should get the expected result.
Also note the formats I've used can vary from what you need, so you have to add some changes to the format strings, do a quick read of the documentation about it.
Format Region
$#,##0;($#,##0) SpendInUSD
£#,##0;(£#,##0) SpendInGBP
€#,##0;(€#,##0) SpendInEUR
UPDATE: OP wants to get the sum of the right column based on the slicer.
Fortunately your table has a column for every currency, as you found with my proposal to map the slicer value to your measure, this is the final expression:
Spend =
IF (
LASTNONBLANK ( 'Currency'[Code], 1 ) = "GBP",
SUM ( Invoice[SpendGBP] ),
IF (
LASTNONBLANK ( 'Currency'[Code], 1 ) = "USD",
SUM ( Invoice[SpendUSD] ),
SUM ( Invoice[SpendEUR] )
)
)
Let me know if you need further help.

Related

Calculate date diff between column date for each row and min slicer date

I think that the following formula summarize pretty well what I want to achieve:
date diff =
ABS (
DATEDIFF (
data_table[login_date],
SELECTEDVALUE ( 'Date'[Date] ),
DAY
)
)
but it returns me the following error
A single value for column 'login_date' in table 'data_table' cannot be determined. This can happen when a measure formula refers to a column that contains many values without specifying an aggregation such as min, max, count, or sum to get a single result.
In other word I want have a column in my data_table with date diff calculated dynamically based on min slicer date selection.
My final goal is to filter out dynamically users that has not been logged for the last 3 months based on the slicer date range.
Here is the dataset
user_id, login_date
111, 01/02/2021
222, 02/15/2021
444, 03/15/2021
555, 01/15/2021
I want user ID to be filtered out when the number of days between the max date of the date range and the day of the last connection is higher than 90 days.
Edit
I'm adding a different formula I'm working on but having few issues to make it work
active users = CALCULATE( DISTINCTCOUNT(data_table[id]), ( FILTER ( VALUES ( data_table[id] ), DATEDIFF(IF( ISBLANK(SELECTEDVALUE(data_table[login_date])),[Min range date],SELECTEDVALUE(data_table[login_date])),[Max range date],DAY) < 90 ) ))
You can't have a dynamically calculated column, but you can use a measure to do this. The issue that you have with your calculation is that it needed to do a row by row evaluation, rather than over a column. That is why you get an 'A single value for column 'login_date' in table 'data_table' cannot be determined' error.
In this case you can use SUMX, as this is a iterator and it will do row by row. So using the following measures:
Selected Date = SELECTEDVALUE('Calendar'[Date])
This reads the date selected. You can wrap it with a MIN/MAX if needed depending on how your slicer is set up. You can change the slicer to single select, it you just want one value.
Date Calc = SUMX('Table', DATEDIFF('Table'[Login_date], [Selected Date], DAY))
This uses SUMX to calculate on a row by row level.
You can then use this measure to drive your visual. In this example I've filtered out those over 30 days since the login
If you choose a new date, it will recalculate straight away. This should set you on the right path for your use case.

How to produce a snapshot table using Power BI measure

My intention is to populate days of the month to simulate a data warehouse periodic snapshot table using DAX measures. My goal is to show non-additive values for the quantity.
Consider the following transactions:
The granularity of my snapshot table is day. So it should show the following:
Take note that a day may have multiple entries but I am only interested in the latest entry for the day. If I am looking at the figures using a week period it should show the latest entry for the week. It all depends on the context fixter.
However after applying the measure I end up with:
There are three transactions. Two on day 2 and the other on day 4. Instead of calculating a running total I want to show the latest Qty for the days which have no transactions without running accumulating totals. So, day 4 should show 4 instead of summing up day 3 and day 4 which gives me 10. I've been experimenting with LASTNONBLANK without much success.
This is the measure I'm using:
Snapshot =
CALCULATE(
SUM('Inventory'[Quantity]),
FILTER(
ALL ( 'Date'[Date] ),
'Date'[Date] <= MAX( 'Date'[Date] )
)
)
There are two tables involved:
Table # 1: Inventory table containing the transactions. It includes the product id, the date/time the transaction was recorded and the quantity.
Table # 2: A date table 'Date' which has been marked as a date table in Power BI. There is a relationship between the Inventory and the Date table based on a date key. So, in the measure, 'Date'[Date] refers to the Date column in the Date table.
You can use the LASTNONBLANKVALUE function, that returns the last value of the expression specified as second parameter sorted by the column specified as first parameter.
Since LASTNONBLANKVALUE implicitly wraps the second parameter into a CALCULATE, a context transition happens and therefore the row context is transformed into the corresponding filter context. So we also need to use VALUES to apply the filter context to the T[Qty] column. The returned table is a single row column and DAX can automatically convert a single column, single row table to a scalar value.
Then, since we don't have a dimension table we have to get rid of cross-filtering, therefore we must use REMOVEFILTERS over the whole table.
the filter expression T[Day] < MaxDay is needed because LASTNONBLANKVALUE must be called in a filter context containing all the rows preceding and including the current one.
So, assuming that the table name is T with fields Day and Qty like in your sample data, this code should work
Edit: changed in order to support multiple rows with same day, assuming the desired result is the sum of the last day quantities
Measure =
VAR MaxDay =
MAX ( T[Day] )
RETURN
CALCULATE (
LASTNONBLANKVALUE (
T[Day],
SUM ( T[Qty] )
),
T[Day] <= MaxDay,
REMOVEFILTERS ( T )
) + 0
Edit: after reading the comments, this might work on your model (untested)
Measure =
VAR MaxDay =
MAX ( 'Date'[Date] )
RETURN
CALCULATE (
LASTNONBLANKVALUE (
Inventory[RecordedDate],
SUM ( Inventory[Quantity] )
),
'Date'[Date] <= MaxDay
) + 0

How do I manipulate measure values based on 2 other dimension tables

Power BI newbie here and I'm trying to figure how to craft my DAX to manipulate my measure values based on certain criteria in the other two tables.
Currently I have 2 separate tables which are joined by a One to Many relationship and a separate Measures table. (Total Sales Price is computed as sum of Sales Price)
My aim is to create a new measure where Total Sales Price is multiplied by 1.5x when DIM_Product_Type[Product Category] = "High".
New Measure =
CALCULATE (
SUM ( FACT_PriceDetails[Sales Price] ),
FILTER ( DIM_Product_Type, DIM_Product_Type[Product Category] = "High" )
) * 1.5
However this returns no values in my visual and I'm trying to discern if its a matter of the table joins or the DAX expressions.
Thank you for your time!
Your measure seems good.
It will select only those products with a Product Category of "High" and multiply them by 1.5 to give you result. i.e. Give me the sum of all "High" Product category Price details multiplied by 1.5.
What you need to check is:
Product Serial Numbers match across the two tables
Your Product Category does indeed contain the category "High"
You have entries in FACT_PriceDetails that link to a DIM_Product_Type that has a category of "High"
Check you have not set any filters that could be hijacking your results (e.g. excluding the "High" product category product type or the realated fact/s)
Option-1
You can do some Transformation in Power Query Editor to create a new column new sales price with applying conditions as stated below-
First, Merge you Dim and Fact table and bring the Product Category value to your Fact table as below-
You have Product Category value in each row after expanding the Table after merge. Now create a custom column as shown below-
Finally, you can go to your report and create your Total Sales measure using the new column new sales price
Option-2
You can also archive the same using DAX as stated below-
First, create a Custom Column as below-
sales amount new =
if(
RELATED(dim_product_type[product category]) = "High",
fact_pricedetails[sales price] * 1.5,
fact_pricedetails[sales price]
)
Now create your Total Sales Amount measure as below-
total_sales_amount = SUM(fact_pricedetails[sales amount new])
For both above case, you will get the same output.

Power BI Rank within Matrix Visual

I've spent many weeks trying to get this to work including a posting at another site. No luck. Not sure what I'm missing.
The following code gets me the table of data that I need. However, I want just the "rank" value and I want it for each row within a matrix visual.
First some background, the PowerBI page has slicers on dates and "base" product. Any given product may be sold in multiple countries. All carry the same base product suffix with a country-specific prefix.
The matrix in question displays several aspects of all the product variants for the selected base product. I want to show where each variant ranks (unit sales) within its country.
VAR tblCountrySales =
SUMMARIZE (
FILTER(
tblSalesUnits,
RELATED(tblProducts[Country])="US"
),
tblProducts[ProdID],
"Total Sales", SUM ( tblSalesUnits[Units] )
)
RETURN
ADDCOLUMNS (
tblCountrySales,
"ProductRank", RANKX ( tblCountrySales, [Total Sales] )
)
Is there a way to either pull just the rank for a single product from the above code, or, better yet, a DAX pattern that will get me the rank by unit sales of each product variant within its respective country?
I've use these statements to successfully get the product ID and country for each row within the visual.
VAR ProdSales = SUM(tblSales[Units])
VAR ProdCountry = SELECTEDVALUE(tblProducts[Country])
Any help is greatly appreciated. I assume I'm missing something with row context within the visual as a simple COUNTROWS on the table expressions above always returns "1". Being new to PowerBI and DAX I'm still trying to grasp the nuances of filter and row contexts.
The products table contains data like...
ProdID.....BaseID....Name...Country
7190...........7190.....xxxx.....US
150207190......7190.....XXXX....Panama
241807190......7190.....xxxx.....Spain
The sales table contains data like...
ProdID......SalesMonth......Units.....USD
7190........July 2010.......4563....$23491.00
150207190...July 2010.......2543....$16235.00
241807190...July 2010.......1263....$8125.00
There is a dates table as well that links the SalesMonth to the usual selection of date display formats. The two tables above are linked via ProdID, though the visuals are sliced by the BaseID. I'd attach a picture, but don't have permissions to do so.
With some more tinkering I found this solution.
Country Rank =
VAR ProdSales = SUM(tblSales[Units])
VAR ProdCountry = SELECTEDVALUE(tblProducts[Country])
VAR tblCountrySales =
SUMMARIZE (
FILTER(
ALLEXCEPT(tblProducts,tblProducts[BaseID]),
tblProducts[Country]=ProdCountry
),
tblProducts[ProdID],
"Total Sales", SUM ( tblSales[Units] )
)
RETURN
IF(ProdSales>0,COUNTROWS(FILTER(tblCountrySales,[Total Sales]>ProdSales))+1,BLANK())

Combine real and planned data in PowerBI KPI visualizations

I've got two primary datasets:
Real data with all sales transactions.
For example RealData:
Date;Sales
16-01-2017;1200
20-01-2017;1500
05-02-2017;800
08-02-2017;1100
13-02-2017;300
Etc.
A plan with total sales I want to achieve, with totals at the last day of each month.
For example EndOfMonthTargets:
Date;Sales
31-01-2017;3000
28-02-2017;2500
Etc.
In my real data I (a) also have data from the years before 2017, and obviously I have the targets for each month in 2017. The RealData is always live / up to date.
What I'm trying to do is show KPI visualizations: how is the real data vs the plan doing. However, I can't figure out how to relate the two datasets, because the cannot really be joined together.
What is the idiomatic way to do this in PowerBI?
I've tried:
adding a column to each source with its respective status ("real" vs "plan")
creating a union (i.e. "Append Queries as New")
adding a column Month = MONTH([Date])
Giving me this data:
But that's weird, because then the KPI visualization will include the "Plan" data either at the start or worse at the end where it will be plotted as the "current" number.
The expected output is a KPI visualization:
showing the absolute number of sales summed by year (or month, if my slicers are set that way!)
with the Target goals retrieved from the plan data
with a trend based on previous years (not included in my sample data)
How do I achieve that?
There are a few ways to join tables like this. What you have are 2 tables with different granularities: a sales table that goes to the day, and a target table that goes down to the month. It's a common request to model them against each other, and it boils down to having a lookup table that both fact tables can join with.
What I would recommend:
Have a table of your real data
Have a table of your plan/target data, using the last day of the month is fine
Do not relate these 2 fact tables together directly
Rather, have a separate date lookup table, to which both tables are joined. This date dimension should, at a minimum, have a month & year column (e.g. March 2017).
Join both fact tables to your date table
Hide the date fields in your 2 fact tables, so that you aren't tempted to use them in visuals (you have to use the date fields from the lookup table instead)
You can then create measures to SUM your actual and targets. And then additional measures that subtract those 2 measures against each other (or divide one into the other). All those measures will then be sliceable by the month & year on your date table. (You could slice them by date too, but because targets are assigned to the last day of the month, that granularity will be less than helpful.)
There's a lot of good information & examples here: http://www.daxpatterns.com/handling-different-granularities/
The way I would do it:
Add a calculated column to both real and targets tables:
Month = Date(Actual[Date].[Year],Actual[Date].[MonthNo],1)
Month = Date(Target[Date].[Year],Target[Date].[MonthNo],1)
Create relashionships between these
Plot SUM(RealData[Sales]) and Target[Sales] against Target[Month]
You can use PowerQuery to transform data.
"Real" table:
let
Source = Table.FromRecords({[Date="16.01.2017", Sales = 1200], [Date="20.01.2017", Sales=1500], [Date="05.02.2017", Sales = 800], [Date="08.02.2017", Sales = 1100], [Date="13.02.2017", Sales = 300], [Date="10.01.2016", Sales = 1400], [Date="02.02.2016", Sales = 1800]}),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Date", type date}, {"Sales", Int64.Type}})
in
#"Changed Type"
"Plan" table:
let
Source = Table.FromRecords({[Date="31.01.2017", Sales = 3000], [Date="28.02.2017", Sales=2500], [Date="31.01.2016", Sales = 2800], [Date="29.02.2016", Sales = 2700]}),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Date", type date}, {"Sales", Int64.Type}})
in
#"Changed Type"
Your query for getting data, let's name it GetData:
let
t1 = Table.AddColumn(Real, "Source", each "Real"),
t2 = Table.AddColumn(Plan, "Source", each "Plan"),
MergedTable = Table.Combine({t1, t2}),
AddYear = Table.AddColumn(MergedTable, "Year", each Date.Year([Date])),
AddMonth = Table.AddColumn(AddYear, "Month", each Date.Month([Date])),
Group = Table.Group(AddMonth, {"Year", "Month", "Source"}, {{"Sales", each List.Sum([Sales]), type number}})
in
Group
You may avoid using last step by grouping results at report level, but this will result in users being able to view amount of each sale. If this is expected behavior, just remove Group step, or replace it with Table.RemoveColumn to remove [Date].
If you need separate columns for Plan and Real values, then pivot Source column.
Then just use GetData query in clustered column chart.
You will have to create a measure to calculate the Actual total and measure to calculate the Planned by each month or end of month. Then create a measure to compare the difference between Planned total and Actual total.
Actual =
CALCULATE (
SUM ( RealDate[Sales] ),
FILTER (
ALL ( RealDate ),
MONTH ( [Date] ) = MONTH ( MAX ( EndOfMonthTargets[Date] ) )
&& YEAR ( [Date] ) = YEAR ( MAX ( EndOfMonthTargets[Date] ) )
)
)
Planned = SUM(EndOfMonthTargets[Sales])
ActualVSPlanned = [Actual] - [Planned]
Now use that measures and the Date in eEndOfMonthTargets table to build a matrix:
For the ActualVSPlanned measure use conditional formating as follows:
You will get something like this: