Concatenating a string in subreport - Crystal Report XI - subreport

I have an existing report that works like this:
Main Report
SubReport 1
SubReport 2
There is a field in SubReport 1 which needs to be a concatenated string from some related record. If I could create a subreport within a subreport, I would be done by now. But since that's not possible, my thought was to create another (non-printing) subreport in Main which loops through the records I need, and concat's the values I want into a shared variable. Then I display that shared variable in SubReport 1.
Well, I've tried a number of things, and I have a lot of problems, but first off, I can't even get the string to populate correctly. The formula in my subreport only get the first value.
Here's my formula:
WhilePrintingRecords;
shared stringvar PressMats;
PressMats := PressMats + {PV_JobStep.ItemCode} + " ";
For the test report I'm running, there are two records in table PV_JobStep that should be picked up. It only picks up the first one. The formula is placed in the Report Header of the SubReport. That's the only place where it will run, even though it seems to me to make sense that it should be in the Details section of the SubReport, but then I get nothing.
Please let me know what other details I can provide. I'm new to Crystal Reports.

Create another formula for reseting variable and place it in footer.
WhilePrintingRecords;
shared stringvar PressMats='';

Related

Printing records with condition Crystal reports

I am using stored procedure in mssql as backend, vb.net as frontend (just info).
There are a lot of records in the database and I am printing in crystal reports.
Now I want to filter the records from crystal report and not by adding a new parameter to procedure or changing database structure or else.
For now,Say there are columns : Name , Amount.
I want to put filter in amount like only display records whose amount above 100 or something. So other records with less than 100 should not be displayed.
This filter will be passed by the user so it'll be random.
I can't find a proper answer on internet. Might be a duplicate question, if so please post the link of the question if it is duplicated.!
Thanx anyways...!
In general the idea is to:
Create the parameter (user choose what will be the input/value) - link
Set filters, what values should be displayed in regards to parameter - link
On right side there is a DataExplorer window, where You need to add a Parameter (define his name, what question will be shown to user and what type the param will be / what values can be set inside).
Once done, You can jump to Data tab of a report, click Interactive Filter and specify which column must fit what condition with what value = Parameter (that one user will enter in Report).
Example: I will create AmountParam, with message "What should be the minimum amount?". Type will be set to Integer. Going to Report->Data->Interactive Filter, choose Amount as a Column, AmountParam as a Parameter and set condition Greater then (>).

Report Builder 3.0 Add Data Elements to an Array

I'm currently working on building a dashboard for some hospital metrics. The state requires that we report median key times. This dashboard will need to display the group median time for each day and the total column will need to display the entire dataset's median.
I'm working with Report Builder 3.0 and SQL Server 2014.
I've built a stored procedure that can calculate all these values accurately but accomplishing the mean this way makes expanding the dataset a bit of a monster when a new field needs to be pulled in.
All the articles (like as this one) I've read for calculating median within Report Builder point to needing to display (or insert and hide) all the data from the dataset. This method seems really hacky to me and is going to make this dashboard an absolute monster to try to manage as it grows.
What I need to know is, is there any way to pass the group values to a custom code function? The report has to have access to the group values at some point or else it wouldn't be able to perform the built in aggregate functions (Sum, First, Last, etc) on these groups. If I can't pass these values as an array to a custom code function, does anybody know how the group aggregate functions are built?
Thanks in advance to any who might have a direction to point me.
You can pass the values from the procedure to a function within SSRS and then have it just display the resulting median. I'll just give you summary to get you started.
Create a hidden parameter that allows multiple values.
Set its available values to pull from the dataset that is populated by your stored procedure.
Also set its default value so that all values are selected by default.
Go to the Code section of the report properties to write your function.
The function will take the parameter as an argument like this Public Function MyFunc(ByVal p1 as object()) as Integer
In the function you can refer to p1.Length and an item in the array like so: p1(i)
In the report you can call the function in an expression like this: =Code.MyFunc(Parameters!p1.Value)
Hope this points you in the right direction.

SSRS parameter returns a data type that is not valid

I got the Tumbleweed badge for this question.... :)
I've moved on a little from the original question but still looking at using internal/hidden parameters, this time passing to another report which runs a stored procedure (which sends an email).
The main report (report A) has a parameter called StudentCourses (originally called ReportParameter1) which I have tried both as Hidden or Internal, and currently has ticked Allow blank value and Allow multiple values.
(Its default value is a field from the result of a query, which shows the courses a student is enrolled on).
Action for my textbox no longer goes to URL (to open PHP form) but now uses Go to report to call report B. Under action options I've added two parameters; StudNetworkID and StudCourses. The number of courses can vary from 2 to 5.
The new report (report B) has two parameters also called StudNetworkID and StudCourses; both are Hidden and StudCourses has ticked Allow blank value. [All parameters are text, btw].
If Report A StudCourses is set to =Parameters!StudentCourses.Value(0) then the first course is shown on Report B. So far so good.
If Report B StudCourses is set to Allow multiple values, then Report B shows #Error and the Warning description given is "[rsInvalidExpressionDataType] The Value expression used in textrun ‘Textbox3.Paragraphs[0].TextRuns[0]’ returned a data type that is not valid."
If Report B StudCourses is set to NOT Allow multiple values and Report A StudCourses value is set to [#StudentCourses] then Report B shows the text "[#StudentCourses]".
If Report B StudCourses is set to Allow multiple values again, then I get the same invalid data type error as before.
Having turned off Allow multiple values on Report B to avoid the #Error issue...
Setting Report A StudCourses to =Parameters!StudentCourses.Value(0) & Parameters!StudentCourses.Value(1) then Report B shows course 1 and course 2 on one line. OK so far.
However, setting Report A StudCourses to =Parameters!StudentCourses.Value(0) & Parameters!StudentCourses.Value(1) & Parameters!StudentCourses.Value(2) gives me a runtime error that the Index was outside the bounds of the array (because there are currently only two courses). On clicking the textbox, Report B just says "The 'StudCourses' parameter is missing a value".
OK...
I turned off Allow multiple values on Report A StudentCourses parameter (the one holding the result from the query) and for the Go to report parameter StudCourses I added the other values, so eventually had value(0) to value(4), the result was interesting. For each parameter value used it gave me a letter from the first course on Report B. Hence when I included up to value(4) it gave me the first five letters of course one!
Yep, ok, this is because it is no longer reading multiple values and so specifying a number just returns the letter from that position.
SO...
How do I allow for up to 5 courses to be passed over???
What follows below is the original question
I have a small report designed in Visual Studio that displays courses that a student is enrolled on. The number of courses can vary from 2 to 5, depending on the student.
Also on the report is a text box, which when clicked will action a url to open a PHP form.
I have worked out how to pass the user id to this PHP form but, if possible, I would also like to pass the course titles.
If I use internal report parameters* I can add these to the url, like this:
="http://myurl/webform.php?param=" & Mid(User!UserID,InStrRev(User!UserID,"\")+1)
& Parameters!ReportParameter1.Value(0)
& Parameters!ReportParameter1.Value(1)
& Parameters!ReportParameter1.Value(2)
& Parameters!ReportParameter1.Value(3)
& Parameters!ReportParameter1.Value(4)
but unfortunately I get the runtime error "The Hyperlink expression for the text box 'Textbox7' contains an error: Index was outside the bounds of the array."
If I just put the first two report parameters it works fine.
I tried using parameter count, e.g. iif(Parameters!ReportParameter1.Count > 2, Parameters!ReportParameter1.Value(2), " "), but I still get the same error.
Please can someone show me how to get around this runtime error, or suggest another way to do this?
Thanks
PS * Report Parameters set up as Text, Allow blank value, Allow multiple values, Internal, Available Values = None, Default Values = Get values from a query; Value field = course title.

UNION multiple datasets in SSRS outside query

I have two data sets with exactly the same fields that I would like to combine into one dataset.
I cannot put a UNION/JOIN and make it return one dataset in the query as all data is encrypted and gets decrypted by an assembly reference loaded in SSRS (so I cannot run the necessary WHERE's unless I use a filter once the data is in SSRS).
I can return the second dataset using Lookup/LookupSet however I am using this data in a bar chart so (somehow) need both sets of data to display on it. If I was using a tablix I would be able to "hack" it by putting a second tablix without headers underneath the main tablix and show it like that. Unfortunately being a graph I cannot do this.
I also tried running it as one dataset, returning all values and then running "filters" based on category groups in the chart however for whatever reason [bug in SSRS?] the filter on these filters the whole result set, not just the one category group.
Is what I am trying to do possible in SSRS? Seems so basic but after a week of trying I have just about given up!
Merging two datasets is not possible but there may be a way to fake it for your chart purposes by doing a SUM of LookUpSet. What ever field is used as your value needs to be looked up using whatever criteria is being used for your axis.
Let's say you're displaying sales by month. Your value field is SUM(Fields!TotalSales.value) and your date field is Fields!month.value. You'd want to add the value from dataset1 and lookup the total from dataset2 - like:
=Fields!TotalSales.value + Code.SumLookup( LookupSet(Fields!month.Value, Fields!month.Value, Fields!TotalSales.value, "Dataset2") )
Unfortunately, SSRS doesn't let you sum a lookupset (so what's the point of it?), so you have to use custom code to do it.
Function SumLookup(ByVal items As Object()) As Decimal
If items Is Nothing Then
Return Nothing
End If
Dim suma As Decimal = New Decimal()
suma = 0
For Each item As Object In items
suma += Convert.ToDecimal(item)
Next
Return suma
End Function
Stolen from: How to combine aggregates within a group with aggregates across groups within SSRS
You're data is obviously different but the concept should be the same.

SSRS 2008 R2 custom code clear dictionary in render lifecycle event

My report gets data from SQL based on a date range, uses custom code to calculate totals by Employee and CategoryType and stores the values in a dictionary. To get the grand total by Employee, in a matrix cell, I call a function and pass it the EmployeeID which returns the accumulated total. A chart is populated with data the exact same way.
Everything works as it should when running the report directly in Report Builder 3.0. However, problems arise when exporting the report to Excel. The first time it's exported, the totals are doubled. Each consecutive time, the multiplier is incremented by one. (1st - doubled; 2nd - tripled; 3rd - quadrupled, etc.). To work around this problem, I override the Init event and clear the dictionary variable (see below for code--notice I'm using the keyword Shared which I found out about on another posted question). Problem solved for Excel as now the dictionary is garbage collected and it will not recalculate from what already exists in memory.
But now a different problem exists. When executing the report via the Web, the matrix populates with data and the totals are correct although the chart only populates with data within a week date range from the current date. Very strange! If I increase the date range to longer than a week, I get a blank chart. The link above implies this may be due to the "report on demand" engine of SSRS but offers no solution to the problem in my mind. I need a solution that will work (showing correct totals and populating chart with data) when exporting the report to Excel and when simply viewing on the Web. I will post screenshots and more info if needed.
I've tried overriding the LoadComplete event (thinking this would be a great time to clear the dictionary as all other controls on page are loaded), but not sure this is possible in SSRS custom code and unsure of the proper syntax.
Is there a different render event I should be using instead to make this work? Anyone ever run across something similar and have a reasonable solution?
public Shared Dim dict As New System.Collections.Generic.Dictionary(Of String, Decimal)
'Override built-in OnInit function and clears dictionary; ensures correct totals when exporting to Excel
Protected Overrides Sub OnInit()
dict.Clear()
End Sub

Resources