I have a "Select Year" Parameter for Year.
If I select from "Select Year", then I want to display results for Selected Year and Previous Year (both) in a CrossTab View on the same Sheet.
Please refer to attached to know more about my query.
*Other way (unwanted): *
I tried to create two Calculated Fields (Dimensions Filters for selecting the Year), then created two different sheets - "Selected Period Value" and "previous Period Value", but I want just one sheet to display it together.
//Selected Year
IF YEAR([Year]) = INT([Year Parameter]) THEN
INT([Year Parameter])
END
//Previous Year
IF YEAR([Year]) = INT([Year Parameter])-1 THEN
INT([Year Parameter])-1
END
Please assist.
Just assuming 46.34% and 46.85% as Profit measure.
Create two calculated fields, one for the year selected from parameter and the other for prior year.
Profit_Current calculated field:
IF YEAR([Year]) = INT([Year Parameter]) THEN Profit
ELSE 0 END
Profit_Previous calculated field:
IF YEAR([Year]) = INT([Year Parameter])-1 THEN Profit
ELSE 0 END
Use these two calculated fields in cross tab
Let us know if this works!
Related
I have a dimdate table that is represented below. I have each day flagged as BusinessDay Y/N. I also have a DimSalesRep table that has a daily goal for each rep. I want to be able to allow users to input a StartDt and EndDt with filters on the report and have a calculated column look at the business days between those dates. I can calculate daysbetween with defined dates but I am unsure how I would use DAX with variable dates that are applied through Report filters.
I should also note I am not sure how best to handle a startdt and enddt filter based of the column, TheDate
Cheers!
Reference your dimdate table twice
StartDate = 'dimdate'
EndDate = 'dimdate'
and use this measure:
Num BusinessDays =
CALCULATE(
COUNTROWS('dimdate'),
'dimdate'[BusinessDay] = "Y",
'dimdate'[Date] >= SELECTEDVALUE(StartDate[Date]),
'dimdate'[Date] <= SELECTEDVALUE(EndDate[Date])
)
So I have a table with StartDate and EndDate and I need to know if this dates overlap in a natural year. In example January 1st 2021 and December 31st 2021 and know how many days where in that period.
I have a formula that works in PowerBI that is:
Note: "DATA" is the name of the query.
OVERLAP days 2021 = MAX(MIN(DATE(2021,12,31),'DATA'[StartDate].[Date])-MAX(DATE(2021,1,1),'DATA'[EndDate].[Date])+1,0)
But now I need to translate it to PowerQuery.
Thanks!
How about
let Source = #table({"StartDate", "EndDate"},{{#date(2021,5,31),#date(2021,7,31)}}),
year=2021,
#"Added Custom" = Table.AddColumn(Source, "Overlap", each
if [EndDate]<#date(year,1,1) or [StartDate]>#date(year,12,31) or [EndDate]<[StartDate] then null else
Number.From(if [EndDate]<#date(year,1,1) then #date(year,1,1)
else if [EndDate]>#date(year,12,31) then #date(year,12,31)
else [EndDate]) -
Number.From(if [StartDate]<#date(year,1,1) then #date(year,1,1)
else if [StartDate]>#date(year,12,31) then #date(year,12,31)
else [StartDate]))
in #"Added Custom"
The basic algorithm is pretty much the same. But I confess I got a bit carried away with implementing it.
The problem is in how you want to define the years of interest, and how you want to display the result when there are multiple years.
To use Power Query
Select some cell in your Data Table
Data => Get&Transform => from Table/Range or from within sheet
When the PQ Editor opens: Home => Advanced Editor
Make note of the Table Name in Line 2
Paste the M Code below in place of what you see
Change the Table name in line 2 back to what was generated originally.
Read the comments and explore the Applied Steps to understand the algorithm
Here is a method using various M-Coding to develop
a list of all the years that are represented in the table
List.Generate to generate a list of days in any one Year
List.Accumulate to iterate through List.Generate for each year
Some other functions to create the table with the additional columns.
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Start Date", type date}, {"End Date", type date}}),
//add columns for each year
//create list of years for the table
Years =
let
firstYear = List.Transform(#"Changed Type"[Start Date], each Date.Year(_)),
lastYear = List.Transform(#"Changed Type"[End Date], each Date.Year(_))
in
List.Numbers(List.Min(firstYear), List.Max(lastYear) - List.Min(firstYear)+1),
//create lists of days count for each year, based on the start and end dates
newcols = List.Accumulate(Years, {}, (state, current) => state &
{let
ends = List.Transform(#"Changed Type"[End Date], each List.Min({#date(current,12,31), _})),
starts = List.Transform(#"Changed Type"[Start Date], each List.Max({#date(current-1,12,31), _})),
dys = List.Generate(
()=>[d=List.Max({0,Duration.Days(ends{0} - starts {0})}), idx=0],
each [idx] < List.Count(ends),
each [d=List.Max({0,Duration.Days(ends{[idx]+1} - starts {[idx]+1})}), idx=[idx]+1],
each [d]
)
in
dys}),
//add the new columns to original table
newColNames = List.Transform(Years, each "Days in " & Text.From(_)),
newTable = Table.FromColumns(
Table.ToColumns(#"Changed Type") & newcols,
Table.ColumnNames(#"Changed Type") & newColNames),
//Set data types
typed = Table.TransformColumnTypes(newTable, List.Transform(newColNames, each {_, Int64.Type}))
in
typed
How do I dynamically calculate the Year To Date (YTD) for the current year without using a table calculation in Tableau?
I have used the below formulas to calculate YoY for the current year:
if datediff('year',[Date],TODAY())=0 then [Sales] END
For the previous year:
if datediff('year',[Date],TODAY())=1 then [Sales] END
YoY:
sum(current year)/sum(previous year)-1
create a calculated field:
[date] >= MAKEDATE(Year(today()),1,1) and
[date]<= today()
Drag this to filter and select True
It depends on what you're trying to achieve. If you want to filter dates to show only values in the current year without a table calculation, then you could create a calculated field like below and filter on the result:
if Year([Date]) = YEAR(TODAY()) then "YTD" else "Not" END
I have a dataset of dates. It has just one column CreatedOnDate and its values are in datetime as shown below.
This dataset has 6 months of values as shown. I have a parameter called Report Type which has possible values Monthly, Weekly, Daily (Screenshot below)
I have created a calculated field (called Created On Date) which converts the date based on Report Type selected. The formula is shown below
CASE [Report Type]
WHEN "Monthly" THEN DATENAME('month', [CreatedOnDate])
WHEN "Weekly" THEN "Week " + STR(DATEPART('week',[CreatedOnDate]))
WHEN "Daily" THEN STR(MONTH([CreatedOnDate])) + "/" + STR(DAY([CreatedOnDate])) + "/" + STR(YEAR([CreatedOnDate]))
END
This works perfectly. The result of the calculated field is shown below.
I now need to incorporate the following logic
IFF Report Type = "Daily" Display only the last 30 days in the dataset
Other cases Show all values
How do I achieve this?
woodhead92, I'd suggest using so called Level of Detail expressions that were introduced in Tableau v8. First create a calculated field that will calculate the most recent (=MAX) date available:
{FIXED : MAX(CreatedOnDate) }
Let's call this MaxDate LOD. Then adding a new calculated field Show/Hide:
IF [Report Type] = "Daily" AND
([CreatedOnDate] >= DATEADD('day', -30, [MaxDate LOD]) THEN 'Show'
ELSEIF [Report Type] = "Weekly" OR [Report Type] = "Monthly" THEN 'Show'
ELSE 'Hide'
END
Add this filter and select 'Show' value only. I am assuming that you want to see all dates when Weekly/Monthly date granularity is selected - if that's not the case, simply add more ELSEIF conditions.
The formula above could be simplified, but I wanted to make it as verbose as possible so that it helps you understand how Level of Detail expressions work.
One thing to keep in mind - FIXED LOD calculation overwrites filters, so if you have a date-range filter available, you will have to make sure it's added to context. More details on filter context are available here in this a bit out-dated, but still excellent blog post.
Create a calculated field for your condition and then place it on the filter shelf to include only rows that evaluate to true.
[Report Date] <> "Daily" or
datediff('day', [CreatedOnDate], { max[CreatedOnDate] } < 30
The Curley braces are significant, an LOD calculation
My client has a report that accepts a date range to get a report showing projected revenue. So, a user would enter a date range of '1/1/2015 to 1/31/2015' and the report should return data only in the range '1/1/2015 to 1/31/2015 grouped by week. I am instead for the week of 12/29/2014 (which 1/1/2015 fall into) and 2/1/2015 (which 1/31/2015 falls into). The report is intended to group by week, but I do not want days on the report that are earlier than the start date parameter or later than the end date parameter.
The sql statement for this report is:
SELECT job.job, job.status, job.customer_po, job.part_number, job.unit_price,
job.price_uofm, delivery.promiseddate, delivery.remaining_quantity, job.build_to_stock, job.description, job.make_quantity, job.pick_quantity, job.shipped_quantity, job.lead_days
FROM dbo.delivery as delivery RIGHT OUTER JOIN db.job as job on delivery.job = job.job
WHERE job.build_to_stock = 0 AND (job.status = 'active' OR job.status = 'hold' OR job.status = 'pending')
The date range is from this code and parameters:
Max – Maximum(?Date Range)
Min – Minimun(?Date Range)
Date Range - "From " & {#Min} & " to " & {#Max}
This is the group expression
Group 2 Name - GroupName ({#Adj Date 2}, "weekly") & " thru " & cdate(GroupName ({#Adj Date 2}, "weekly"))+6
This is the select expression
{#Date} = {?Date Range} and
not {Job.Build_To_Stock} and
{Job.Status} in ["Active", "Hold", "Pending"]
Do you know how I can prevent the "overflow" of dates outside of date range?
Thx
As long as you have date filtering in your record selection formula there will not be any "overflow" outside of that range. If you've got {Record.Date} in Minimum({?DateRange}) to Maximum({?DateRange}), which it sounds like you do, then your report will not contain any records outside of the parameter regardless of how you group them.
Your problem might stem from over-complicating or misinterpreting the grouping. All you need to do is group by {Record.Date} and select "Group by week" in the grouping options... you don't need any complicated formulas to break it out by week. But be aware that the way weeks are referred to is by their starting date. For example, if you had a record with a date of Feb. 19, 2015, that record would fall into the group labeled "Feb. 15, 2015" even if your {?DateRange} parameter was Feb. 18 - Feb. 15.