How to make MDX Range operator less restrictive? - mdx

I have a date dimension I want to filter on. I use MDX Range (:) operator for that. The problem is it appears that range bounds must be valid members of a set. I have IntDate attribute in my Date dimension, and it's an integer in the YYYYMMDD format. When I browse the dimension, there are 20120705 and 20120706 values, but not 20120704 or 20120707. Still, as far as range is concerned, both 20120705:20120706 and 20120704:20120707 encompass 20120705 and 20120706 and I hoped would return 20120705 and 20120706. But when first one works as expected, second returns empty set. The reason I need loose range to work is that users may enter date range that is not based on data in the dimension. How can I make this work?
The one that works:
The one that returns empty set.
Thank you,
Vlad.

Since your 20130707 member doesn't exist, the cube can't know where it was supposed to go.
It seems odd that you have a date dimension that doesn't contain all of the days in a month. I would suggest repopulating your date dimension so that it has all dates. You can get a fully populated date dimension from the Azure data market if you are using a tabular cube. If you are using multidimensional, you can have SSAS generate one for you. If you have parameters built off of dates, you can limit the list to populate them to show only the data for which there are measures using Exists.
I also wonder why you want users to enter dates rather than choose dates from a valid list. How do you handle the errors when they enter a value that is simply invalid? It seems the easiest/safest choice is to give them the list of dates from which to choose. If they are entering things that don't have data and you have error handling, the result should be the same as if they choose from a valid list.
That being said, you should be able to so something like the below. I check to see if the date is a valid member. If it isn't I substitute the first valid member I find in the list of members (you could choose your own date and insert it there). For the end of the range, I find the last valid member (again, you can substitute your own value).
{Iif(Count(Exists([Date].[Int Date].members, [Date].[Int Date].[20130704]))>0,[Date].[Int Date].[20130704], [Date].[Int Date].firstchild):
Iif(Count(Exists([Date].[Int Date].members, [Date].[Int Date].[20130707]))>0,[Date].[Int Date].[20130707], [Date].[Int Date].lastchild)}

Related

Complex IF. formula in Excel

I checked various posts on IF formulas but I cannot find a way to receive the correct result in my report. I manage deliveries and I would like to calculate the delay days basing on the data from delivery report. The trick is that the delay will depend on the status of delivery, as in each case I have to consider a different date and column in Excel. These are the data:
Status of delivery:
Confirmed
Unloaded
Unloading
Not confirmed
Started
In route
Pick-up pending
Prepared
This delivery status is updated in C column in my Raw Data report. For each, I will have to calculate the delay in a different way therefore I figured that IF formula could be of use.
Below you can see the columns that contain the relevant dates for the calculations:
Status of delivery and reference date:
Confirmed - D
Unloaded - D
Unloading - D
Not confirmed - S
Started - D
In route - S
Pick-up pending - E
Prepared - S
I made this formula as below, sadly, only the first record is calculated correctly, the rest of the delays is "null".
=IF(C2="Confirmed";(TODAY()-D2);IF(C2="Unloaded";(TODAY()-D2);IF(C2="Unloading";(TODAY()-D2);IF(C2="Not confirmed";(TODAY()-S2);IF(C2="Started";(TODAY()-D2);IF(C2="In route";(TODAY()-S2);IF(C2="Pick-up pending";(TODAY()-E2);IF(C2="Prepared";(TODAY()-S2);"null"))))))))
Do you happen to have any idea where am I making the error which I don´t see? I will be grateful for any help. If it´s also relevant, I am using Excel 2016.
Breaking it down so the long line becomes readable.
=IF(C2="Confirmed";
(TODAY()-D2);
IF(C2="Unloaded";
(TODAY()-D2);
IF(C2="Unloading";
(TODAY()-D2);
IF(C2="Not confirmed";
(TODAY()-S2);
IF(C2="Started";
(TODAY()-D2);
IF(C2="In route";
(TODAY()-S2);
IF(C2="Pick-up pending";
(TODAY()-E2);
IF(C2="Prepared";
(TODAY()-S2);
"null"
)
)
)
)
)
)
)
)
At first glance, what I'm looking at is basically a vertical lookup schedule here.
So, I created these two colums. One is the text status we're looking for.
The other is the calculated date.
Single date VLOOKUp
Assuming D2, S2 and E2 are fixed fields I made the formula =TODAY() - $D$2
Then it's a simple matter of doing the VLOOKUP in the correct field.
Because we're working with a date type field we need to convert the number to text to get a meaning full date. (I used JJ in the screenshot for years because I have a dutch locale)
Then we also need to handle when VLOOKUP can't find anything, for that we use IFERROR.
=IFERROR(TEXT(VLOOKUP(F6;$A$2:$B$9;2);"MM-DD-YY");"NULL")
And now you have an easy to expand lookup table you can put anywhere, hide on a worker tab, etc.. where you can calculate your values, where you can add and remove values.
Many rows, many dates
But, say you have many rows with different statusses and dates, and you wish to know the number of days it'll take. Then this vertical lookup doesn't look so useful because it can only be used for one row.
We can still leverage VLOOKUP to make our life a bit easier
Assuming there are dates in colums D, E and S
=IFERROR(DATEDIF(TODAY();INDIRECT(ADDRESS(ROW();VLOOKUP(F2;$A$2:$B$9;2;FALSE)));"d");"NULL")
We use VLOOKUP to see which column we need to look in. We use a number here for column, not a letter.
We then use ADDRESS to get an excel address reference for the current ROW(), and the column we found via vlookup
We funnel that through INDIRECT so we can get the value from that targeted cell.
Then we get a DATEDIFference in days from offset today.
We wrap it all in an IFERROR to keep things clean.
You could use an INDEX($D2:$S2;0;VLOOKUP($F2;$A$2:$B$9;2;FALSE)) to get the same effect, as pointed out by Dirk Reichel but you have to mindful then that the index used is from the start of the matrix range. So here the matrix starts on row D. So D2 is index 1 instead of 4 it is with my original method, so you'd need to adjust the lookup table accordingly.

QlikView Dynamic Date Comparisons

I’m relatively new to Qlikview and have a dataset that shows metrics by date.
This data spans two years and the requirement is to have a comparison/variance that is dynamic and can handle the date filters on the report.
For example if the user selects 2018 this field should show the current date compared to the previous year date. Similar for Quarters, months, weeks and weekdays.
Ideally it should always show for the previous period. They’ve had this created in Excel but it can’t handle the amount of records and I suggested QlikView as I had created some other Dashboards in it.
I have tried set analysis though I struggle to see how that would fit into one expression.
Any thoughts would be appreciated!
I would say you would need two expressions, one without a set analysis (that would be filtered by your current selection) and one with a set analysis to guarantee that you only get today's value. This would be something like :
Sum($<[Date Field] = {"$(=Date(Today(), 'DD/MM/YYYY'))}>} [Value Field])
Check the date format conversion to see if it matches the date format of your field.

Combine sets and tuples in calculated mdx member

I'm creating a member in an mdx query containing my slicer information and the last one is my measure. When I add a set to my tuple (for having multiple slicers on one dimension), i get this error.
This function expects a string or numeric expression for the argument.
A tuple set expression was used.
When I add one of the 2 members of my set to my tuple, I don't get this error.
what does this mean, I don't really know what to make of this, fundamentally there isn't a difference between adding a slicer or
A tuple is a cell. A set contains cells. A set cannot be one of the coordinates of a tuple, as the end result is not a cell (a cell is given by 1 and ONLY one member in each dimension, where unspecified members will be taken to be either the All member or the Default member.
The way around it is by creating calculated members:
With Member [Time].[Current Period] as { [Time].[2013], [Time].[2014] }
Select (... your query here ...)
Where ( [Products].[My product], [Time].[Current Period], ... )
In the slicer you in fact have a tuple, as in each dimension a single member is specified. The fact that the member on the Time dimension is not a "pure" member coming from a dimension table column but instead is a calculated member has no influence.
Without your actual code it is difficult to help you.
Anyway, from your question it seems you are confused with sets and tuples (e.g., you cannot add a set to a tuple). I would advise you to check a MDX tutorial explaining these basic concepts: e.g., the icCube gentle MDX introduction should be fine for that.

Reporting Services - Two filters on the same chart Category Group?

I have sales data that I'd like to plot on my chart. However, at a specific point in time, we had a change taking place I'd like to ensure is clearly visible in the chart, preferably by dividing the sales data (which is stored in a single SQL Server column) into two different chunks, which would allow me to then treat them as different data series.
I used to solve this in Excel by storing the post-event data in a different column (by simply dragging them to a different column), and thus I was able to treat them as a different series (the blue and green line in the chart below. The red and orange line are pre-event and post-event averages):
I'd like to reproduce this effect in SSRS, but am not sure how to tackle it. I've tried using an approach where I added two category groups, both pointing to the date-time column, and applying filters to them (one <= the cutoff date, the other >=).
I then added my sales data twice, with the idea I could somehow connect them to the individual category groups, but that does not seem possible.
Has anyone tried anything like this before, or would have a different approach to achieve what I'm trying to get?
Thanks!
I managed to get this to work, and figured I'd share how to do it.
My dataset contains a field called DATEKEY, which stores the date in the format YYYYMMDD. It's possible to use this in an expression and evaluate the date for a specific row. In case the expression evaluates to true, we display the value. If not, we display a blank string.
In case we want to show the values prior to the date, the expression would be:
=IIF(Fields!DATEKEY.Value <= 20130601, Avg(Fields!My_NUMBER.Value), "")
The second series can then be made by reversing the symbol:
=IIF(Fields!DATEKEY.Value >= 20130601, Avg(Fields!My_NUMBER.Value), "")
The graph then looks like this:

Formatting measure based on dimension attribute

This may be very basic. I'm trying to change the format string used on a measure based on the attribute of a dimension connected to the measure. I'm doing this in a calculated measure at the moment.
Essentially, the fact table row contains a value for the ID of the dimension, and that dimension has the format information I want. I'd like to apply formatting based on that value, without the dimension being required in my query.
something like this:
WHEN [Format Source].[Hierarchy].CurrentMember.Properties("Format") is [Format Source].[Format].&[Number (123)]
THEN FORMAT([Measures].[Volume], "#.#")
I'd like this formatting to be applied regardless of having the dimension in the query, as I won't always have control over how the reports the users create. The data could be whole number or % with differing levels of decimal precision, based on the attribute of the format dimension.
I think that I may just be way off on this one, thanks in advance for any help