SSRS - Programmatically flag when a report is created as a snapshot - reporting-services

Is there a way to programmatically determine if a report is being run as a snapshot?
I have a suite of reports that need to behave differently when a snapshot is created than when run by the end user.
Differences include:
Tablix and column visibility
Multi-parameters (both available choices and defaults)
Expressions in textboxes in header
Expressions in tablix cells
I have been able to work around most of these issues but it is a series of kludges. Ideally I would like an IsSnapshot() function that I can use throughout the report.

I have been able to use IIf(User!UserID = "",True,False) in expressions to flag scheduled snapshot (but not manually triggered ones).
Unfortunately SSRS realises that User!UserID is volatile and so won't let me use it if I also want to use Data Driven Subscriptions: "You cannot create a data-driven subscription on a report that contains the User!UserID expression"
In order to work round this I made my own public function in the report "Code" properties:
Public Function UserName()
Try
If IsDBNull(Report.User!UserID) Then Return ""
If IsNothing(Report.User!UserID) Then Return ""
Return Report.User!UserID
Catch
Return ""
End Try
End Function
My report therefore uses IIf(Code.UserName() = "",True,False) as a snapshot flag.
My main issue with this is that I am then using the absence of a username to work out if I should show all data (as I want to in my snapshot). This seems like a security flaw in the making.
I would much rather have an explicit Snapshot flag and not rely on some byproduct of the snapshotting process!

Related

Me syntax working instead of writing full control adress. Why?

I am kind of new to VBA programming in Access and I have banged upon strange thing. I have system of myListbox (multi-choice, two of them in testing regime, planning 5 total) to filter myReport contained in subform container by selected items in those listboxes.
Switching "On" filter works kind of fine (I will address it in different question after doing some research first), but switching filter off turned out to be problem. I was getting error message described here.
Managed to find a workaround. Since I have myReport bound to control in parent form, I am not switch off filter, instead I am changing it to resemble the bound field criteria, after that switch it off.
Code:
Forms![myForm]![myReport].Report.Filter = "((sourceQuery.fieldForBoundControl)=Forms![myForm]![boundControl])"
Me.FilterOn = False
but if I try this:
Forms![myForm]![myReport].Report.Filter = "((sourceQuery.fieldForBoundControl)=Forms![myForm]![boundControl])"
Forms![myForm]![myReport].Report.FilterOn = False
...or any other combination, or simply turning it off, I get error messages and procedure termination. Why?
Is my solution correct for future working of the app or I my setting myself for another Access trap?

Problem with the row count transform

I currently deployed an SSIS package (Developed on the 2005 version) (developed on my local server) in a pre production environment for testing. I have used the Row count transform to get a count of good/bad records. It works fine on my local system . However when i deploy this on the pre prod server, the row count does not work! (as in it does not recognize the vairbales i have assigned to the relevant transofm - no drop down abvaliable in the variables attribute part. tried deleting and adding a new transoform.. no luck.
Strangely this does not work for any of the other packages also present/deployed on the same server (tried this out by dropping an rc tramsform onto an existing package... same problem)
Any suggestions?
Thanks a tonne
If you are having problem with the row count transform, another alternative that we use here at my company is creating a script component and incrementing a rowcnt variable by one. The performance is just as good-just add this code:
Public Overrides Sub PostExecute()
MyBase.PostExecute()
Me.Variables.rowcnt = Me.Variables.rowcnt + 1
End Sub
This certainly seems odd. Are you saying that when you are in the Advanced Editor for Row Count, under Custom Properties, that the drop down beside VariableName has no options? You should at least see all of the System:: variables.
If the User:: variables are not listed, my first suspicion is that they do not have the correct scope to be visible in the Data Flow Task where you have your RowCount.
When you go up to the Control Flow, and get the Variables list, do you see your user variable there? What is the scope of it?
Note that I recognize that none of this fits with "it works locally but doesn't work when copied to the server", but it is at least where I would start...

How to automatically change a parameter in Reporting Services when another is changed?

I have a 'Product' parameter in my report. Depending on the product the user chooses, it will call the report generator stored procedure from a different data source. Looking at this article, I've found how to do the first part of this solution. I've created two internal parameters, Server and Database, and the connection string will use them to connect to the right database.
But I need to set this two parameters when the user chooses a product. How could I do this?
(If #Product = X) => #Server = Y, #Database = Z
How did I resolve this:
I didn't do the way the article suggested. Instead, I threw away this two additional parameters and just put a big Switch expression at the connection string definition. Depending on the #Product value, the switch returns a different value. It may sound uglier, but at least it works.

How to print dynamic forms in Microsoft Access?

I have an Access form where each record has some info that is computed on the fly. I'm using the Form_Current() event; each time a record is selected, I compute some information and change some form controls to reflect it, based on the record's ID.
I want to print a bunch of these records. However, in this situation the Form_Current() event isn't being triggered and the printed records lack that dynamic information.
Any ideas?
Make a query that computes the information you need as the source of your report. You can use vba functions if needed for complex calculations.
In a comment, Luis Oliveira asked:
My function was in the Form itself,
which is why I couldn't call it from
the SQL query, I suppose?
By default, functions in a form are private. If made public they can only be called when the form is open, as in Forms!MyForm.PublicFunction(). I would advise against that. Instead, move the function to a public module (which may require revisions to remove references to form controls/fields).

Custom code in Reporting Services report

In Reporting Services I would like to add a parameter that contains data from a custom code block. Ideally, I would be able to run the following code (this is a simple testing example):
Function GetPeriods() As String()
Dim values As System.Collections.ArrayList =
New System.Collections.ArrayList()
For i as integer = 1 to 24
values.Add(i)
Next
Return values.ToArray()
End Function
and put the following in the "Text Field" of the parameter:
=Code.GetPeriods()
However, when I run the report, the parameter I apply this to is disabled and empty. Is there a different technique that should be used? Or am I doing something wrong?
If you're using SQL 2008 Reporting Services then you can have a look at this page which introduces the concept of using custom assemblies.
If you're using SQL 2005 Reporting Services then this link is the one you want.
It's a mostly trivial thing, simply compile your code into a class library and follow the instructions provided to allow your report to reference it.
You are returning an array item (an array of strings) into a text field. Instead, try returning a plain string. That should work. If you would still like to return an array list, you must basically bind it to a list control in your RDL. You can definitely do that with dataset extensions. However, I am not sure if there is any other easy way. Check the proprties of the list control and see if it allows you to directly bind to an array list.
You can create the same stored procedure on SQL Server and load parameter values from that procedure.
To access your members/functions implemented in custom code of SSRS report you should set the access modifier to "Public":
Public Function GetPeriods() As String
...
see article Writing Custom Code in SQL Server Reporting Services
I've been trying to do this same thing, set a simple list of parameter values from report code. None of the links in any of these answers shows how to do this and after quite a bit of digging around I don't think it's even possible. Yes it is possible to get the values from a database query, from a web service, or from a custom assembly, but each of these creates a lot of overhead compared to getting the list from a simple function call like =Code.GetValues(), where the function uses a For loop to create the values.
msvcyc is correct in pointing out that the parameter is expecting a string value, but the function is returning an array. I changed the return type to Array as suggested by prashant sable, but the select list is still grayed out, it does not work. And coldice is correct in saying that the access modifier should be Public.
In my digging around I found an article by James Kovac from 2005 that pointed out why this is not possible. The Parameters class has a get method, but no set method. In the VS 2008 object browser for SSRS 2008 the object name has changed, but it still does not contain a set method (see Microsoft.ReportingServices.Interfaces.IParameter.Name or .Value).
My current workaround is to just hard code the list of values, but if your value list needs to be dynamic then your only choices are database queries, web services, or custom assemblies. I think the easiest workaround of these three is to get the values from the database engine, as suggested by oleksiy.t, as long as you can write a query to return the value list you want. Your list of integers, or my list of time intervals, would both be easy queries to write. Otherwise you will need to use one of the other two workarounds.
I checked your code. The only thing that's wrong is your function returns String(). When I changed your method signature to return Array, it worked fine, in my report.
Change the signature to Function GetPeriods() As Array
Everything I've seen requires parameters and their respective settings to be part of the RDL.
That being said, if you're going to "hardcode" the values, you could create a dataset just for the report, perhaps in XML, or if it needs to be programmatically driven, do it in a web service.