Run dataset on every auto refresh - reporting-services

I am using Report Builder 3.0 and have a dataset that when it runs it increments a value in a table, this determines which subreport to display thanks to expressions.
My problem is that when I set it to auto refresh the dataset query doesn't run again after the first time the report is ran. It will run and display the other subreport if I manually hit refresh but not automatically.
How can I make it so the query in the data set runs every time unattended.
Thanks

Referring back to your earlier question here.. Can you rotate through visible sub reports in report builder 3?
It looks like using the parameter won't work as it does not get refreshed. However you can use the value the dsLoop returns directly. To make the change, simply swap out
Parameters!pLoopPos.Value with =First(Fields!LPos.Value, "dsLoop")
Note: I modified the dsLoop query slightly to give the final result a name (LPos).
You should now be able to delete the parameter as its no longer used.
UPDATE:
The query for dsLoop should be this (assuming you have a table called myReportLoopTable with columns LoopPosition, LoopMax and Reportname)
DECLARE #LoopPosition int
SELECT #LoopPosition = CASE LoopPosition WHEN LoopMax THEN 1 ELSE LoopPosition + 1 END
select * FROM ReportLoopTable
WHERE ReportName = 'myReportName'
UPDATE ReportLoopTable Set LoopPosition = #LoopPosition WHERE ReportName = 'myReportName'
SELECT #LoopPosition as lPos
The script to create the table would be
CREATE TABLE [dbo].[ReportLoopTable](
[LoopPosition] [int] NULL,
[LoopMax] [int] NULL,
[ReportName] [varchar](10) NULL
)
In the table it should have something like
LoopPosition LoopMax ReportName
1 3 'myReportname'
Below is a link to a sample report RDL I created to test this. You'll need to add it to your project and configure the data source to point to your database then it should work . It switches visibility of 3 text boxes but the principle is the same for sub reports.
https://1drv.ms/u/s!AvWOxxoIjY1UlwWbHGG8l_rzDba2

Related

Can you rotate through visible sub reports in report builder 3?

I have one main report with several sub reports. Essentially I want to show each sub report in rotation for about 30 seconds before hiding the first one then showing the next and restarting again after all have had their time up.
Thanks
I 'think' you can do this, but there are some caveats.
You will need to setup a database table to store the current loop position, if you have several of these reports you could key it on report name for example.
(note these names are for the main report, nothing to do with the subreports)
ReportName LoopPosition LoopMax
MyMainReportA 0 3
AnotherReport 7 10
Add a dataset (lets call it dsLoop) to your main report that updates this value and returns it with something like. (Untested)
DECLARE #LoopPosition int
SELECT #LoopPosition = CASE LoopPosition WHEN LoopMax THEN 1 ELSE LoopPosition + 1 END
FROM myReportLoopTable
WHERE ReportName = 'MyMainReportA'
UPDATE myReportLoopTable Set LoopPosition = #LoopPosition WHERE ReportName = 'MyMainReportA'
SELECT #LoopPosition as LPos
This code simply adds 1 to the LoopPosition or resets it to 1 if we've hit the maximum value. It then returns this value.
Now add a parameter pLoopPos to your main report (this can be a hidden parameter) and set it default value to our new dsLoop dataset.
Now change the hidden property of each subreport to only show the subreport when Parameters!pLoopPos.Value = x where x is the order of the subreport.
Now, when the report runs it will update the loop position and get the new value. The first subreport will show as the pLoopPos will be 1 . When your report refreshes (via the AutoRfresh property) the dsLoop dataset will be reevaluated which will run the code to update the value. The pLoopPos value will increase and the next subreport will be displayed.
You may have to force the parameter to always be refreshed (from the parameter properties).
PLEASE NOTE THIS IS UNTRIED AND UNTESTED. This is just off the top of my head so I suggest a simple test report before spending too much time trying to implement it.
UPDATE: 2018-04-10 Following on from your followup question, it looks like using the parameter wont work as it does not get refreshed. However you can use the value the dsLoop returns directly. To make the change, simply swap out
Parameters!pLoopPos.Value with =First(Fields!LPos.Value, "dsLoop")
Note: I modified the dsLoop query slightly to give the final result a name (LPos).
You should now be able to delete the parameter as its no longer used.

Need Code in SSRS to create multiple serialized copies of a report (Label)

I have a number of SSRS Reports that are printing to dedicated Zebra Label printers where the printer is the default for the user. Each report is passed a parameter: Number_Of_Copies. In the application that calls this there can be 1 to any number of copies as a value for Number_Of_Copies. Somehow I need to product a report with however many copies are indicated (with page breaks between) and a field that indicates which sequence number the label is: "x of Number_Of_copies." This is apparently easier said than done. Is there a way in the SSRS Report itself (which is being called via a command line) to do this?
Here's how you can do it...
Oh, and this is quite wordy but it's actually very simple..
First thing we need is your label report, which I assume you've got and I'll call it LabelA for the purpose of this answer.
We need to edit this report so that it accepts 2 parameters (Copies and CurrentCopy). Add a text field with an appropriate expression to display this info e.g.
="Label " & Parameters!CurrentCopy.Value & " of " & Parameters!Copies.Value
Run this report and test it works by typing in numbers for the two parameters by hand. Once you know this is working OK, proceed.
Next we need another report which will act as our loop, so....
Create a new report, let's called it LabelA_Loop (I know terrible name!)
In LabelA_Loop, create dataset and call it dsLoop
Set the query for the dataset to something like this..
DECLARE #counter int = 1
DECLARE #t TABLE (RowNum int)
WHILE #Copies >= #counter
BEGIN
INSERT INTO #t SELECT #counter
SET #counter = #counter +1
END
SELECT * FROM #t ORDER BY rownum
(Of course you can use anything to create a list of numbers even have a big numbers table but this works and is easy to do...)
At this point, a parameter (#Copies) will have been created automatically as it's required by your dsLoop dataset.
Next step, add a table to the report.
Next, set the dataset property for the tablix (the table we just added) to be dsLoop
The table will only need to be one column wide and no header row so essentially we'll be left with a single 'cell'. Delete the row header and last two columns until you only have a single cell left.
In the table cell, insert a subreport and set the subreport property to be our label report LabelA.
In the parameters for the subreport, set Copies to be your Copies parameter and set CurrentCopy to be the RowNum field from your dsLoop dataset.
You'll need to resize the cell to suit and set page breaks but that's it. The loop report takes a parameter Copies which the dataset uses to generate the correct number of records. It will add one row per record in the dataset, each row will contain a label subreport and each subreport will be passed two parameters, the current copy and the total copies, which in turn are rendered in the final label.

SSRS subreport with parameter rendering only one record of group

I want to build a report that returns records for a group of employees and by specific dates and supervisor, and renders the report by employee (as in a batch). I am doing this with a main report and 3 subreports. My subreports work individually and I just got one subreport to render from main but only the 1st record in the group displays.
Dataset on main has 3 parameters, USERID, BegDate, EndDate. Dataset on subreport take EMPID, BegDate, EndDate. I inserted subreport on main and subreport parameters as follows:
Name Value
CurEmp =First(Fields!EMPID.Value, "DataSet1")
BegDate [#BegDate]
EndDate [#EndDate]
Where CurEmp is used in the where clause of DataSet1/sql query i.e. WHERE EMPID = #CurEmp
Main report parameters in DataSet1 are:
Name Value
#USERID [#USERID]
#BegDate [#BegDate]
#EndDate [#EndDate]
Now I realize that the =First in the Expression in Value of parameter is supposed to render only the first record but nothing I change it to will render at all. I have done tutorials and googled for 2 days. I can get the simple subreports to work but nothing seems to apply to what I am trying to do. Can someone direct me to an example that applies to my situation?
BTW I have set my VS2008 environment to a Business Inteligence Project.
UPDATE: I have added my sql queries below to help explain per suggestion by #Sam. I actually was starting to look at the fact that maybe I am writing the queries wrong. I am confused about what the main report query should be compared to subquery....I hope this helps to clarify my meaning.
Main report dataset =
SELECT
v.EMPID,
UPPER(p.FirstName + ' ' + p.LastName) as EmpFullName,
v.dtmDate,
v.TCode,
v.Hours,
v.ProjectNo,
from vwPersonSummary v
join tblPerson t on v.EMPID = p.EMPID
WHERE v.USERID = #USERID --Supervisor’s EMPID
AND
v.dtmDate BETWEEN #BegDate AND #EndDate
ORDER BY v.EMPID, v.dtmDate
Subreport dataset=
SELECT
v.EMPID,
UPPER(p.FirstName + ' ' + p.LastName) as EmpFullName,
v.dtmDate,
v.Tcode,
v.Hours,
v.ProjectNo
from vwPersonSummary v
join tblPerson t on v. EMPID = t. EMPID
WHERE
v.EMPID = #CurEmp
AND v.dtmDate BETWEEN #BegDate AND #EndDate
ORDER BY v.dtmDate
So your fix/answer is going to be something like below.
When defining the the parameter from the main report it should be something like this.
=Join(LookupSet(1,1,Fields!EMPID.Value,"DataSet1"),",")
Once that is defined make sure that the sub report parameter Data Type is set as Text and Allow multiple values have been checked.
After that for the data set of the sub report don't set a where condition. Instead in Data Set properties go to Filters.
In Expression set something like
=CStr(Fields!EMPID.Value)
and set Operator as In and set the Value as something like below.
=Split(Parameters!EmpId.Value(0),",")
Well basically that's it. Hope this helps.

Reporting Services Cscading Parameter refresh

I have googled it a lot and found that usually it cannot be done. I came across one of the hacks here:
http://www.bp-msbi.com/2011/04/ssrs-cascading-parameters-refresh-solved/
But its not working for me in ssrs 2005. Just wondering if anyone else tried it in 2005.
Or is there any other hacks that can be tried.
As per this article the dependent parameter gets refreshed only when its values are invalidated by the selection in the first parameter. If we can invalidate the dependent parameter every time a parameter changes we will enforce a complete refresh. An easy way to do this is to attach a value such as a GUID obtained with the NEWID() T-SQL function.
So basically we want to introduce a fake parameter in between two real parameters. This fake parameter is supposed to return new values everytime as the storedproc behind it will add a guid to the resultset everytime that proc is called. So it forces complete refresh of the other parameters.
Now the main issue I am facing is :
Setting the default value of this fake parameter.
For the available values the storedproc behind the fake param runs and it returns data in the format say : result1,result2_GUIDFROMSQL
Now it looks like the same storedproc is called again to set the defult value if i ask it to get the default value from query. But as the storedproc is run again new guid comes and so the old value cannot be found so its not being set as desired.
I just need to figure out a mechanism to pass this guid from introduced param to the next param.
Thats where I am failing.
My issue can simply be replicated by creating a param whose datasource is this querystring.
select getdate() id, #name nid
So in this case how to set a default value for this param.
Below I'm going to present a detailed scenario and then I'll show the example implementation based on Visser and Abbi's answers.
Imagine that I have a report where each row is a project. A project has a Status column with values "In Progress" or "Complete" and a Project Manager column whose values are a person's name. Here are the rows in the table:
Project A (Status = In Progress, Project Manager = Bob)
Project B (Status = In Progress, Project Manager = Tom)
Project C (Status = Complete, Project Manager = Jack)
Project D (Status = Complete, Project Manager = Tom)
Project E (Status = Complete, Project Manager = Jill)
I want to have 2 parameters on my report
Show Completed Projects? - This is a boolean parameter
When false will only show "In Progress" projects A & B
When true will show "In Progress" projects A & B in addition to "Complete" projects C, D, & E.
Project Manager - This is a multi-value text parameter whose options and default values will need to change based on the Show Completed Projects? parameter upon which it is dependent.
If Show Completed Projects? is set to false then only "Bob" and "Tom" options will show up because they are the project managers for the in progress projects Project A & B respectively.
If Show Completed Projects? is set to true then in addition to "Bob" and "Tom" you will also have "Jack" and "Jill" show up as options because they are project managers for the inactive projects Project C & Project E respectively.
Now for the implementation:
Show Completed Projects? parameter
Project Managers dataset query (See Visser and Abbi's answers for details on how this generates a key that will change based on the independent parameter and will force SSRS to reload the default values)
SELECT
[ProjectManager_Key] =
pOuterAlias.[ProjectManager_Key] + '_' +
CAST(ROW_NUMBER() OVER(ORDER BY pOuterAlias.[ProjectManager_Key] DESC) AS NVARCHAR(MAX)),
[ProjectManager] = pOuterAlias.[ProjectManager]
FROM
(
SELECT
[ProjectManager_Key] =
pInnerAlias.ProjectManager + '_' +
CAST(ROW_NUMBER() OVER(ORDER BY pInnerAlias.ProjectManager ASC) AS NVARCHAR(MAX)),
[ProjectManager] = pInnerAlias.ProjectManager
FROM
(
SELECT
[ProjectManager]
FROM
[dbo].[Project]
WHERE
Status = 'In Progress' OR
#ShowCompletedProjects = 1
) pInnerAlias
) pOuterAlias
ORDER BY
pOuterAlias.[ProjectManager]
Project Manager parameter
General
Available Values
Default Values
Projects dataset
Query
SELECT
*
FROM
[dbo].[Project]
WHERE
(
Status = 'In Progress' OR
#ShowCompletedProjects = 1
) AND
Project Manager IN (#ProjectManager)
Parameters (Make sure to note the [#ProjectManager.Label] portion which will make it match the project on the actual project manager value from the database and not the key that we generated.
Finally I was able to resolve this. This link was a helpful start.
http://www.optimusbi.com/2012/07/16/multilevel-cascading-select/
Basically what it does is : Writing parameter query in a manner so that the dependent parameter changes its value every time you change its parent parameter.
The query adds rownumber with a "_" preceeding it. So every time user selects other values the rownumber changes and hence the query resultset.
Then when using the resultset remove the text after the underscore to get the real codes.
There is a workaround to fix this issue for all situations.
Note that the previous answer provided, writing parameter the query in a manner so that the dependent parameter changes its value every time you change its parent parameter, works for some cases but not all cases. If the dependent parameter's "Available" values change as a result of another parameter AND the dependent parameter is visible, it works, If the dependent parameter is hidden or internal, or if the "Available" values do not change as a result of the other parameter, it will not work.
The foolproof workaround is to define a custom function in the report and call it in an expression for the dependent parameter. The custom function takes the parameter's (the parameter that the dependent parameter depends upon) value as an argument, and simply returns its value. Even though function is simply taking the value and returning it, SSRS does not inspect the code and assumes that the code could do anything (generate a random number, pull files from disk, etc ...). So SSRS calls the function every single time the value changes regardless of whether the dependent parameter's "Available" values change, and regardless of whether the dependent parameter is visible, hidden, or internal.
Something like this:
public function returnArg(ByVal TheArg As String) As String
return TheArg
end function
Assume you have two parameters:
Parameter1
Parameter2
And that Parameter2 depends upon Parameter1.
Set Parameter2's value as an expression that includes the call to Parameter1 with the function, like:
=CODE.returnArg(Parameters!Parameter1.Value)
Now in this case Parameter2 simply displays the value in Parameter1, but this logic can be extended to more complex expressions and more than one parameter. As long as there is a CODE.returnArg(...) function call for each parameter in the expression, SSRS will always refresh the value.
#Abbi's second link is no longer valid. The article can now be found at:
http://www.optimusinfo.com/multilevel-cascading-select/
Unfortunately the images are broken and the article is a little incomplete without them. There is one image I was able to locate in its moved location (I could not find the others even with trying appropriate variations): http://www.optimusinfo.com/wp-content/uploads/2012/07/Multilevel-Cascading-with-Select-All-18.jpeg
This gave me the last clue I needed to get the technique working: when you're setting up the dataset parameter properties, you need to manually specify the parameter value as e.g. [#City.Label] rather than the usual plain old [#City] (which corresponds to [#City.Value].
This is because the technique alters the "Value" to a custom value which can no longer be looked up in the DB! So you need to use the user-friendly, db-existing "Label" as the parameter. (Probably should be obvious but...) The rest is all pretty standard if you understand report builder.
Also note that this link as it stands doesn't work with multi value cascading parameters. However it can easily be modified to do so: just alter the parameter stored procs to join to a value splitting function. I adapted mine from the udf_splitvarible function given at SQL Server - In clause with a declared variable
The modification is fairly simple but I'll give an example. This is from the article (with terrible formatting fixed).
SELECT
l11.CompanyName1+'_'+ CAST(row_number() over( order by l11.CompanyName1 desc) AS VARCHAR(50) )as CompanyName11
,l11.CompanyName
FROM
(
SELECT
l1.CompanyName+'_'+ CAST(row_number() over( order by l1.CompanyName asc) AS VARCHAR(50) )as CompanyName1
,l1.CompanyName
FROM
(
SELECT DISTINCT CompanyName
FROM Customers
WHERE City IN(#City)
)l1
)l11
ORDER BY l11.CompanyName ASC
Change:
SELECT DISTINCT CompanyName
FROM Customers
WHERE City IN(#City)
to:
SELECT DISTINCT CompanyName
FROM Customers
INNER JOIN udf_SplitVariable(#City,',') v ON City = v.Value
This all applies to SQL Server 2008/Report Builder 3 also.
I wasn't able to understand/apply #borkmark's answer. The limitations don't seem to apply to my case.

Setting Parameters from another Parameter In SSRS

I was able to get this working is SSRS 2008, but do to the fact that my company only has 2005 servers I need to downgrade the report to 2005.
The idea is for a given person name there are two key fields EntityType and EntityId
So I have a parameter from a dataset where the Label is the Name and the value is EntityType_EntityId
I use the split function to take the left and right sides of from _
In 2008, I set the query parameters of the dataset to the split function and it works
In 2005, I set the Default Value of each Report Parameters
Now when I run the report and put textboxes showing the value of the parameters, the values are shown correctly but the query does not run. I am guessing that this is a lifecycle issue being
Get Name Parameter
Run Report
THEN Set Parameters = Split of Name
But the problem with that is the second time I run the report I should get result and I do not. Does anyone know what I am doing wrong.
I guess I can pass in the underscore delimted string to the stored procedure and parse it there, but my question is can this be done in the report? Reason being other callers will pass in the parameters as two seperate values.
I already found a suitable answer
Set the query source as text
DECLARE #EntityType INT
DECLARE #EntityId INT
IF #Name = '0_0'
BEGIN
SET #EntityType = NULL
SET #EntityId = NULL
END
ELSE
BEGIN
SET #EntityType = LEFT(#Name,CHARINDEX('_',#Name)-1)
SET #EntityId = RIGHT(#Name,LEN(#Name) - CHARINDEX('_',#Name))
END
EXEC proc #EntityType, #EntityId