ssrs vlookupset #error when array is empty - reporting-services

So I am using Report Builder in order to create a dashboard connecting the information between 2 lists in Sharepoint and fetching specific cases. Practically speaking, the cases in one lists are sales and the cases on the other list are tracking items (documents) for each sale. They are connected with a common ID (ID on the first list, SaleID on the tracking list) and there can be a relationship of one sale to many tracking items (at least one to one).
There will be various tables on the dashboard but the concept is the same for all (meaning data misalignment).
Since the relationship is one to many, I want to compare the document status on the sales list with the document status on the last tracking item on the tracking list and then filter out all the cases that the tracking status is the same on the 2 lists.
Using the lookupset, I encounter the #Error when the array is empty.
I tried different variations like:
=iif(
(LookupSet(Fields!ID.Value, Cint(Fields!Sale_ID.Value), Fields!document_status.Value, "sales").length) >= 1
,((LookupSet(Fields!ID.Value, Cint(Fields!Sale_ID.Value), Fields!document_status.Value, "tracking"))((LookupSet(Fields!ID.Value, Cint(Fields!Sale_ID.Value), Fields!document_status.Value, "tracking")).Length - 1))
,"")
or
=IIF(
IsNothing(Lookup(Fields!ID.Value, Cint(Fields!Sale_ID.Value), Fields!document_status.Value, "tracking")),
"",
((LookupSet(Fields!ID.Value, Cint(Fields!Sale_ID.Value), Fields!document_status.Value, "tracking"))
((LookupSet(Fields!ID.Value, Cint(Fields!Sale_ID.Value), Fields!document_status.Value, "tracking")).Length - 1))
)
There are other variations of the above too, but no matter how many things I tried, I still get the same error when the array is empty, but I want to just display blank cell in that case. Any help would be appreciated! Thanks in advance!

Related

Tableau's functions - how to find an equivalent to IF EXISTS

I'm creating a Tableau Dashboard with 'buttons' which are coloured red or green based on certain criteria and what is selected in the filters. The filters are just a way to select different offices in different regions and when selecting an office the buttons should change colour depending on whether the targets for the different metrics have been hit for that office or not.
The navigation buttons on Tableau won't accommodate this so I've made a work around. For each 'button' I've created a worksheet with just the text of the metric name on the Label mark and a calculated field on the colour mark. I've then added the worksheet to the Dashboard and added an action to go to the corresponding metric dashboard when the 'button' is clicked on.
The issue I'm having is the conditional colouring of one of these metrics. This metric is based on stock levels. For each office there are multiple categories of stock types, each with a corresponding target, with multiple 'bins' in each category. I want the button to turn red if ANY of the combined total of stock in the bins for one category is over the target for that category for that office.
To try and type it logically-
For the currently filtered data: IF EXISTS(FOR EACH OFFICE( FOR EACH CATEGORY: [SUM(BinValue)< CategoryTarget])) THEN 'Green' ELSE 'Red'
I've tried to translate that logic into Tableau's functions in a calculated field and have the following:
SUM(INT({INCLUDE [Category]:Min([CategoryTarget])} > {INCLUDE [Category]:SUM(BinValue)}))
This colouring is correct when I add the Office Name and Category pills to the worksheet to test my logic however when I remove the pills the colouring isn't correct. Something seems to be going wrong when I try to sum the number of categories that are within target levels over all offices and targets.
I've tried so many iterations of the following functions and have been going around in circles for days now:
INCLUDE, EXCLUDE, FIXED, IF, SUM, INT
If anyone knows how to do this properly or even just a different way of being able to conditionally colour buttons on a dashboard I would be incredibly grateful.
The structure of my data is as follows with some dummy data as an example:
Region
SubRegion
Office
Category
Bin
BinValue
CategoryTarget
North
NorthWest
Manchester
Toys
B123
30
50
North
NorthWest
Manchester
Toys
B456
40
50
So for a Stock Level metric selecting any of ALL/North/NorthWest/Manchester filter options should flag as red due to the total of the bins in one category in an office being higher than the target amount for that category for that office.
I've updated my calculated field however I'm still having issues with the grouping showing as true/false correctly.
This is what it is now:
MAX( {INCLUDE Category, Office:Sum(BinValue)} > {INCLUDE Category, Office:MIN(CategoryTarget)} )
With True showing as Red and False Green (we want to be below target hence the green).
When working on the example to showcase the issue I managed to get it working.
I ended up using the following logic:
max({EXCLUDE [Bin]:SUM([Bin Value])} > [Category Target])
This meant that even if most of the Offices in the filter were within their stock level targets, if there was one with stock levels over target the 'button' showed as red.
I published the example I've used anyway in case it helps others in the future.
Link to the Tableau Public dashboard:
https://public.tableau.com/views/ConditionalColouring/Dashboard1?:language=en-GB&:useGuest=true&:display_count=y&:origin=viz_share_link
Thank you very much for the help!
To work with logical conditions, such as testing whether a condition holds for any (or every) record in a group of data rows, it helps to understand that Tableau treats the boolean value "True" as greater than the boolean value "False".
Once you get comfortable with that idea, you can use the functions MAX() (or MIN()) to test whether a condition holds for any record (or for every record, respectively). So MAX(False, False, True, False) is True.
So to tell if any records have an actual value below their target, test MAX([Actual Value] < [Target Value])
You can then combine this idea with dimensions on the viz (or LOD calcs if necessary) to group the data records appropriately before testing your conditions. If you work with the same conditions repeatedly, this type of calculation can be very useful for defining sets that get used in multiple places.
One technical caveat, if your condition test ever evaluates to NULL, then those null values are ignored by MIN() and MAX() - just like other aggregation functions do. So for example, you could test whether every record satisfies a condition using MIN() and get a possibly misleading result if all the non-null values are True (so MIN() reports True). MIN(TRUE, TRUE, NULL, TRUE) = TRUE. If your condition can evaluate to NULL, and you don't want to ignore nulls, but instead treat it as, say, the same as False, then you can use the IFNULL() function to provide a default value for your condition.
As an example, MIN(IFNULL([Actual Value] > [Target Value], FALSE)) returns True only if every record has a value above its target, treating any records with missing values or targets as failing the condition - i.e. not exceeding the target. The choice of whether to have a default value for a condition, and what it should be, are problem dependent of course. If your data does not have null values, you don't have this complication to consider.
Though the data you have given is very less, yet I think this calculation field you require
IF { FIXED [Region], [Sub-Region], [Office], [Category] : SUM([Bin Value])}
> {FIXED [Region], [Sub-Region], [Office], [Category] : MIN([Category Target])} THEN 'RED' ELSE 'GREEN' END
This is based on assumption that for every group of region/sub-region/office/category target value will be same in each row within the group. Therefore MAX/AVG etc. will all work in place of MIN used in the calculation.
See I added two rows in your data
and result

get total from two different datasets into a third different tablix ssrs

Here I am, again with another doubt.
Here is my problem:
I have a report where I show ALL the incomes and expenses of the company for the last two days, which i managed by placing a column group grouping the columns by the date
Originally, the report contained a single matrix with both incomes and expenses fed by a dataset that points to the company cube applying the following filter expression
=IIF(Fields!Fecha.Value=Parameters!FechaHoy.Value or Fields!Fecha.Value = Parameters!DiaAnterior.Value,true,false)
FechaHoy = date sent via report parameter input
FechaAyer = date
parameter minus one day
and the filter value set to
=true
So far so good. Today, the upper management decided to split it into three matrix. One for incomes and other two for expenses (one for each expense category), so i startet with this
initial report layout
I created two new datasets for each one of the expense categories with the same filters, and now i'm here
current report layout
THE THING IS... as you can see, there is a "Total Destino" independent table where i have to add the totals of the second and third matrix in the image I added, but, as I already said I have to show the last two days, so i also have to partially add the total of each day (which are column grouped by date)
I'm pretty sured that there's also a better and more efficient way to manage what I did with the three matrices but the main issue which needs your assistance is how do i add the totals of the second and third matrices.
I already tried with
=Sum(Fields!Saldo.Value, "Informacion_Destino") + Sum(Fields!Saldo.Value, "Info_InvTesoreria")
but it adds the two days and repeat it for the two days. I also tried with ReportItems!TextBox + ReportItems!TextBox but the preview loads sends me an error message.
Thanks in advance for your time and help
Like Harry stated already out you can use for your overall total the following expression for the Tesoreria Subtotal + Destino Subtotal :
=ReportItems!TesoreriaSubtotal.Value + ReportItems!DestinoSubtotal.Value
This would give you the overall total for all days. Now if you just have to show the last two days you can add a tablix filter, like this:
'Expression
=IIF(CDate(Fields!YourDate.Value) < DateAdd("d", -2, Now()), True, False)
'Format
=Boolean
'Value
=False

Sum Values from Dataset based on condition: Report Builder

I have a report where users can select items from various location. And I have 3 datasets performing calculations where the third dataset takes the sum where item number is 4942200 and then calculates the values (as shown below):
=SUM(IIf(Fields!masterno.Value= "4942200",Fields!Owned.Value,0))+SUM(IIf(Fields!masterno.Value= "4942200",Fields!Subbed.Value,0))
This is returning error for some reason. The subbed column is toggled based on parameter (visibility). But before I add the toggle functionality, I want to make sure this is working. Can anyone help. I have also tried:
=SUM(IIf(Fields!masterno.Value= "4942200",Fields!Owned.Value+Fields!Subbed.Value,0))
This seems to fail as well. Help would be greatly appreciated.
I would wrap a CDec around Owned, 0 and Subbed, e.g.
=SUM(IIf(Fields!masterno.Value= "4942200",CDec ( Fields!Owned.Value) ,CDec (0 ) ))+SUM(IIf(Fields!masterno.Value= "4942200",CDec (Fields!Subbed.Value ) ,CDec ( 0 )))
If Owned and Subbed are already Decimals, those CDec's may be redundant. On the other hand SSRS doesnt expose this info and they can change at the whim of the data source.

getting started with loops and iteration in sequel pro

I'm using sequel pro to select data from several tables. There are two things I need to do that seem to need a loop of some kind. I have never used any form of iteration in sql and can't find a beginners-level resource to learn from.
Can anyone suggest how to do the following two tasks, or suggest a tutorial where I can learn the fundamentals and figure it out from there:
Task 1: Go through a version history table, find the relevant history record for a given id that applied at a given date, and select the value from that record. The form of the history table is:
id, Item_id, version-created_at, value
eg
1, 123, 2014-05-01, 754
2, 456, 2014-05-10, 333
3, 123, 2014-05-27, 709
and I need to find what the value of item 123 was on the date 2014-05-25 (ie I need to find record id=1 and value = 754 because that is the most recent version for item 123 created prior to my target date.
So I figure I need to run through the table looking for item 123 and comparing dates of those records. But I don't know how to deal with the iteration of moving from one record to the next and comparing them.
Task 2: Go through a single text field that contains a number of product id and matching product prices in a string, and find the id of the product with the lowest price. Form of the string is a series of pairs of price "p" and id "i", in random order, like this:
"
- :p: 99.8
:i: 3
- :p: 59.0
:i: 5
- :p: 109.8
:i: 18
- :p: 82.45
:i: 46
"
and in this example I need to find "5", being the id of the product with the lowest price $59.
So I figure I need to step through each of the p/i sets, maybe by counting characters, but I have no idea how to iterate through and compare to find the best price.
A little help would go a long way.
Thanks.
For first answer you can do something like this:-
SELECT value FROM history where id = 123 AND version-created_at = '2014-05-01';
and for another task you must try this at front end rather than at back end.

Using running totals in MS access report cumulatively

I am developing a db (MS access 2010) to support a school with a well-defined model for tuition quotation. The list of products is assembled for each quote, then various discounts are applied. The discounts may be a percentage or an absolute dollar amount. So far, so easy. The problem is that their business logic requires:
No limit on number of discounts.
Specific discounts to be applied in a defined sequence (implemented in my case with a "discount ordinal" column, values 1 (first applied) to 100 (last applied).
Each sequential application of a discount is to the running total of the quote. Eg: Total products $1000. Discount: 50%. Value: $500. Subtotal $500.
Subtotal: $500. Discount: $25. Value: $25. Subtotal: $475.
Subtotal: $475. Discount: $10%. Value: $47.50. Subtotal: $427.50.
This appears to be a variation of the "get the value of the field in the previous row" problem, but with the added twist that the "value of the field" is actually a cumulative calculation. It has the flavor of recursion: while discounts remain, subtotal(previous subtotal).
I have no clear idea how to implement this in a report, because the calculation as noted above is self-referential. I'm not looking for code here, just guidance on the general approach to the problem (ie, some kind of global variable, using VBA - in which case, I'm not sure what the "glue" between the query in VBA and the report would be - or some trick with a calculated field although I've spent a lot of time trying to figure one out). Any thoughts?
In that kind of situations, I always create a new table, that will get filled up when the report opens, and base the report in that table, not the original one. That way I can do all the calculations I need, even making several passes. The report then is simply a "dump" of the table. Complex totals can be additional columns, that will be shown only in the totals section.
You could have table for purchase history using an integer to link each purchase since an autonumber by itself will not link each discount stage.
So in excel I would use something like this:
v = Starting Value
i = 1
Do Until i = Last Discount
d = ws.Cells(i, 9).Value
v = v * (1 - d)
ws.Range("B2").Value = v
i = i + 1
Loop
At each stage you could write to the table (using docmd.runsql) the discount applied (d) and the value (v) but it could be quite slow. You could then order the table by purchase identifier then descending by value since sequential discounts will inherently order correctly.