I have multiple datasets in a report. There is one main dataset which brings in all the Contacts that follow criteria which I then pass to one of my multi-value parameters i.e. ContactIDs by selecting its available and default values to be derived from the main dataset.
Other datasets have a condition built in that they should bring data only related to the contacts in ContactIDs parameter.
Everything is fine until the main dataset returns any records. The moment there is no data or contacts I get an error saying "Parameter ContactIDs is missing a value
I have seen a lot of workarounds which suggest putting a default value in the parameter but I don't see an option to putting a default value and getting rest of the values from the query.
Major consideration
The query is not SQL, instead its FetchXML so there is no scope for me to return a blank or zero or anything if there are no records.
Any suggestions?
Related
I am designing a report for SSRS. I want the user requesting the report to be able to specify, when they generate the report, from a pre-defined selection some values which should be displayed in a tablix on the report.
I have therefore created a multi-value parameter and populated the Available Values with the options I want the user to be able to select from, and, as expected, when the report is generated the user is able to select one or more of these values.
However, what I now want to do is include a tablix in the report, and display a row for every value in the multi-value parameter that the user selected, with the value displayed in the first cell of the row.
If the values were coming from a data table this would obviously be easy. I've also found answers on how to show all of the selected parameter values in a single textbox using the JOIN function, but I don't want to do that.
The only solution I can think of is to replicate the list of available values in the multi-value parameter in a tablix manually, and link the visibility of each row of the tablix to the selected state of the corresponding value in the multi-value parameter, but that's not very elegant and increases the effort involved in maintaining the report definition.
Any ideas on how to do this? I know the selected values from the parameter simply form an array, but I can't see how to bind a tablix to any data that isn't in a dataset, or how to create a dataset from the parameter values.
Considering that a tablix sources from a dataset, I did some experiments to see how to create a low maintenance solution for you.
Option 1: Create a data set with hard-coded options to match your multi-value parameter and select those options WHERE they exist in the parameter.
Example:
SELECT val
FROM (
SELECT 'opt1' as val
UNION SELECT 'opt2'
UNION SELECT 'opt3'
UNION SELECT 'opt4') a
WHERE val IN (#Param)
Thoughts: easier to maintain than visibility on a table, but still two hard-coded places within the report.
Option 2: Create a dataset that selects the multi-value parameter and splits it by each value. This was my first idea, but I ran into some issues with determining how to actually select the multi-value without a syntax error. I came up with a method that creates a deliminated string in the report and than parsed that string back into rows in the dataset:
Step 1) Within the dataset properties, on the parameter tab, join the multiple values together with a JOIN expression
Step 2) Create a simple query which uses the new SQL Server 2016 function string_split. Note that your database compatibility level MUST be 130 or higher to use this function (SQL 2016+). If this isn't your scenario, there are many string split functions that you can find on Stack Overflow to achieve the same thing.
Fun problem!
I have filtering implemented at tablix level in an ssrs report.
The tablix is using a dataset which is getting lots of records from database using a stored procedure.
The report has parameters whose values are used to filter the tablix data.
First time when the report executes it gets all the data from stored procedure and bind it to tablix with all the details as parameters default value is set to select all.
I want to know when user enters parameter values and click on view report , does the report executes the procedure again , get the entire set of data and then filter based on input parameters?
Or the ssrs report is smart enough to know that already the data which was fetched the first time will be used to filter the data in the tablix
First let's talk about the difference between query parameters and report filters. Parameters are passed into the query so that it can run faster and return targeted results. Filters are applied after the fact so the full query has to run and then the report has to go through the records and check criteria row-by-row.
In addition to those options, SSRS offers caching. This allows you to save the query results so that the query is only re-run when needed. This is configured on the report server, not in the report properties.
The best optimization will vary by report. As a general rule it's best to pass parameters into the query/procedure and just get the data you need. If that is too slow, let the query get all the data, cache it, and just use filters at the report level.
I have created a transaction report in ssrs reporting data from dataset1 where one of the reported columns is populated using lookup function to get data from another dataset (dataset2). If no data is found in dataset2, the lookup function returns blank, which is what I want. I have now been asked to filter the report so that only includes those transactions which are not included in dataset2.
I have looked for a way and tried using the lookup function in the tablix filter expression, but have read that the lookup function is done after all filtering which would indicate that this may be one of those requests that will not be fulfilled. Have any of you tried this?
Add a filter like this in your tablix in tablix properties / Filters tab:
For Expression use:
=ISNOTHING(
Lookup(Fields!FieldDS1.Value,Fields!FieldDS2.Value,Fields!FieldDS2.Value,"DataSet2")
)
In Value use:
=True
I would like to create a report which I can use as a sub-report multiple times on the same parent report. However, each occurrence of the subreport should have different values.
For instance, there is a table called DailyReport.
Records in this table contain:
Date, member, team, description
The sub reports should be for each team within a certain date range. However, the date range per subreport/team will not be the same.
So, if the date range for all teams was consistent, then I could create a single subreport, and do some Ordering on the resulting records to separate things out into teams.
However, with inconsistent date ranges, I can't utilize a single query, so the most straight forward solution I see is to create separate subreports and queries for each range of each team.
The problem with this solution is that if I decide to change the format of the subreports I must do so in each specific subreport--a lot of duplicate work.
I would like to create a generic query and subreport. The query and sub report would call VB functions which would return the relevant value.
This means my parent report has the same generic report on it multiple times. As each subreport is rendered, I would like to increment a value behind the scenes so that the functions which the generic query and subreport call know to return a different value.
However, it seems that's not how things work in Access. The subreports on a report are not rendered linearly. A subreport is created, and then "stamped" onto a report where ever required. This means that all of my generic subreports have the same data.
How can I define a generic report and query? Then plug in different values into the report and query while the report is being reused multiple times on the same parent report.
You need to look into the LinkMasterFields and LinkChildFields property of reports. They are designed for exactly this purpose -- to filter a subreport based on current data in the main report, without needing any code or even queries.
You are correct that LMF/LCF do not work on date ranges, only values. So use LMF/LCF for the team filter.
For the date range filtering, you can use an unbound form that launches the report as two parameters defined in the base query. Create frmLaunch, and add two text boxes minDate and maxDate. Set their Format property to Short Date so Access with interpret them correctly and provide the date pickers. Now modify the base query, adding two Date/Time parameters [Forms]![frmLaunch]![minDate] and [Forms]![frmLaunch]![maxDate]. Now, find your date field and set its criterion to Between [Forms]![frmLaunch]![minDate] and [Forms]![frmLaunch]![maxDate]. Add a button to frmLaunch that runs the code DoCmd.OpenReport "YourReportName", acViewPreview.
So, the goal was to make it possible to re-use the same sub-report multiple times on the same parent report, with full flexibility on how the subreport retrieves data.
I placed multiple instances of the same subreport on a parent report. On the subreports Open event I placed a line like
Me.Report.RecordSource = "SELECT * FROM someTable WHERE " & getCriteria()
nextCriteria()
Maybe its possible to pass a value that identifies which instance of the subreport is opening to the getCriteria function. Probably like a getCriteria(Me.Report.Name). But in this case I kept track of how many subreports had been produced in vb.
Unfortunately, if your subreport has controls which have a data source which is a vb function, all reports will show the same value for that control. To get around this I added something like getSomeValue() & "As [Some Value]" into the SELECT of the SQL statement above. Don't forget to add single quotes or hashes around getSomeValue() if you are passing a String or date.
That's basically it, it's a pain. But I couldn't find a more elegant way to do it.
Edit:
One major caveat I experience with doing this, is that although the print preview works correctly, when actually printing or exporting to PDF, some subreports would not be included. Maybe there is something else causing this...
I have two parameters that cascade from a date parameter. The first cascading parameter is able to populate and defaults to selecting all labels (this is what I want). The second successfully populates the values but defaults to selecting none (this is what I want to fix). I have verified that both are returning their respective default values from a query - and I know the query is good for the problematic parameter because it populates with available selections successfully, it just wont default to selecting them all.
Are there any issues with having two parameters cascade from a single one? Any issues in the result set that would successfully return labels for a parameter but would not be valid for default values?
Any help would be appreciated.
Answer was posted in the comments by OP:
I was returning a NULL value which was keeping me from being able
select all in a multi-attribute parameter. I am now handling this with
a CASE statement checking for NULL.
I have reports that have multiple parameters cascading from a single one, so I don't think that's the problem.
My hunch is that something isn't right in the parameter. To troubleshoot this, set the value field and the Label field for the Available Values and the default values all to be the exact same field from the same dataset. (Use the one that was originally the Value field for the parameter.) If you "select all" do you get all the data you expect?