RDLC #Error driving me nuts (per page subtotals) - c#

I've got a report with a table looking like this:
UserCode|RecordID|OriginatingBranch|OriginatingAccount|HomingBranch|HomingAccount|Amount|ActionDate|SeqNo|Onus|Homedback
The last two columns are booleans, they contain either Y or N. In fact, the Onus column will only contain Ys. I need to have a subtotal at the end of each page showing how many Onus transactions there are and their value, and the same for Onus transactions.
I've tried several things including everything described here but when I try that I'm left with a nondescript #Error in my report. I have no errors or logs or anything, just an #Error where I should have a number.
Now I'm trying the answer from here, which says:
Add additional column and enter this expression: =Runningvalue(Fields!YourValue.Value,Sum,"yourtable1"), and set its hidden property to true.
In the page header or footer, use the expression: =Last(ReportItems!textbox12.Value) to get the subtotal of all previous pages.( assume that the above column’s detail row is textbox12)
I've put this in my table, this is my expression:
=RunningValue(IIF(Fields!HomedBack.Value="Y", Fields!Amount2.Value, 0),Sum,"Items")
//my tablix is called "Items" and my "Amount" field is a formatted string,
//the actual value is kept in "Amount2"
And lo and behold, I am getting the famous #Error again. My first row contains 0, and every row after that contains #Error.
I should note that I'm not viewing the report in a browser or interactively or anything like that, I'm using my company's old reporting library that is terrible and needs to be rewritten (I wish), and pretty much it takes a dataset and an RDLC and spits it out into a PDF.
Is there anything glaringly obvious that is wrong with my expression? I'm pretty new to RDLC so I feel like I'm missing something silly. Also is there any way to show exactly what these #Errors actually mean or correspond to?
Another note, I designed my RDLC in VS2013 if that makes any difference.

SSRS can give #Error because of data type mismatch. It might be evaluating Amount2 as string field instead of numeric. To avoid such conditions do the explicit conversion.
Try this:
=RunningValue(IIF(Fields!HomedBack.Value="Y", Fields!Amount2.Value*1.0, 0.0),Sum,"Items")
OR
=RunningValue(IIF(Fields!HomedBack.Value="Y", CDBL(Fields!Amount2.Value), 0.0),Sum,"Items")
OR
=RunningValue(IIF(Fields!HomedBack.Value="Y", CDEC(Fields!Amount2.Value), 0),Sum,"Items")

Related

Saving SSRS multi select parameter value with wildcard

I have searched and searched and have not been able to find the answer to this. I'm no stranger to SSRS, .Net (c# and vb.net), SQL, etc...been in it for years. I currently have a multi-select report parameter that is populated by a dataset in my report. There are hundreds of entries, so I built it to be driven by a wildcard character in a preceding parameter. Everything works fine right now. My question is this: is it possible to enter a wildcard value, select one (or more) of the filtered values and then store that/those value(s) on selection so that a user can go back and enter another wildcard value and select from a newly filtered list? (Basically, remember what has been selected in the overall dataset before report execution and create some sort of comma-separated list as the final parameter value to be passed to the report) I realize this may be better served in a web app w/a reportviewer control, but I'm trying to avoid deviating from the native SSRS server if possible. Thanks in advance!
The way I might approach this (not actually done it but the theory sounds ok)
Have 2 parameters for user input, your current one and a hidden one called say #filter (visible) and #filterHistory (this is the hidden one)
Have a textbox (formatted like button) with something like "Refine" as the text. Set the action to call your report again but set the #filterHistory to be something like #filterHistory & ", " & #filter. Basically we keep appending the last user input to the history.
Then your report would filter based on both parameters. You'll have to do some parsing of the delimited parameter now to split it out into the constituent parts but you get the idea.
I've no time to build a test report but hopefully that will point you in the right direction. If it doesn't help or work then comment and I'll see if I can knock up a quick example.

SSIS: Column Size Not Changing Based on Query

I have a package. It has a query that feeds into a Script Component.
In the query I am selecting a varchar(8) column from a table and then I CAST(myDateCol AS varchar(10)).
SELECT
myPK,
CAST(myDateCol AS varchar(10)), --myDateCol defined as varchar(8)
myOtherCol
FROM
MyServer.MySchema.MyTable
In my script, I am trying to add two characters to the Row.myDateCol in Input0 but I get a Buffer Error and it is in the property setter for myDateCol. You can see that it sets the property to 8 characters but errors out after that.
What I've done is add an output column with Length = 10, set it, and mapped that to the next component in the package but that seems a little silly.
Is there a way to force the size of your input columns based off of the query OR is there a way that I can manually force a refresh in case the package is just stuck thinking that I'm dealing with a varchar(8) as the CAST operation was added later?
Additional Info:
Row.myDateCol = "20170404"
Row.myDateCol = "2017-04-04" // Errors out
This is normal behavior for SSIS. When you create a data source which uses a SQL query, SSIS will look at your query and build the the metadata for the dataflow. The data source will only recalculate that metadata if you change the structure of your query, for example number columns or their names.
The easiest way to force a refresh of the data types without resorting to renaming columns is to go to the columns page of the data source editor, Untick and then tick the top tick box of the Available External Columns. This will deselect all columns and re-select them and at the same time refresh the metadata. You can easily confirm this by hovering your mouse over the External\Output column names listed in the lower section.
Your problem is the result of dealing with Date(Time) as text instead of the number(s) it is. And I really cannot tell from your question if you want to want to add the extra characters added in at the Data Layer (Sql) or at the Application (C#) Layer.
Casting VarChar(8) => VarChar(10) will still just return VarChar(8) if you don't fill in (pad) that value. You could try a Cast VarChar(8) to Char(10).
Another option would be a double conversion of your column value to Date and then back to your desired varchar(10).
SELECT myPK,
Convert(VarChar(10), Convert(Date, myDateCol, 112), 120),
myOtherCol
FROM
MyServer.MySchema.MyTable
So, after some playing around, I found that renaming the column changed the size to varchar(10) per below:
SELECT
myPK,
CAST(myDateCol AS varchar(10)) AS DATECOL,
myOtherCol
FROM
MyServer.MySchema.MyTable
I then changed it back
SELECT
myPK,
CAST(myDateCol AS varchar(10)),
myOtherCol
FROM
MyServer.MySchema.MyTable
And the change stuck. I don't know why or how but VS/SSIS somehow never refreshed itself to change to a different type. I assume it has no handling for query changes after the initial query is input unless names/aliases change.
This wasn't just my machine either. Weird.

Crystal Reports for Visual Studio: display 2 unrelated tables

I ask for advice what would you suggest to display 2 unrelated tables in a single report (if needed with subreport), the first one with groupings and the second one "flat"?
Details:
I am developing a report with C# 4 and Crystal Reports for Visual studio.
Data comes from a Stored procedure in Sql Server 2005, that returns 2 tables.
I pass the data to the report with the .SetDataSource(Dataset) method and I checked that data in the dataset is correct.
I need to display the data from the first table in a quite complex form with different sections. This part works.
At the end of the report I need to print the data from the second table (no grouping, just a "flat" print). To do this I added a subreport.
The tables are not related. I added a Dummy field on them with the same value and used it to mimic a relation in the database expert; I configured the subreport link, based on the dummy field.
I have 2 problems.
The data in the main report is cross joined with the second table (I could expect that since they are related with a constant field)
The subreport is always empty (I checked several times that its table in datasource contains correct data).
I tried different configurations of link and tried to place the subreport in different sections (It should be in the report footer).
I set a border around the subreport: the border is printed but inside it is empty.
I also setup a formula to count the records of both tables and put the count in the report: the count is > 0 for both.
Your approach looks wrong.... At first if both are not releated I don't see any use in creating a dummy field and linking tables which will always provide cross join. Any way as per your descrition table 1 data is saperately displayed and table 2 data is saperately displayed
As per your description in main report you need data from table 1 and in footer you need data from table 2.
Try this approach:
Don't link tables
take table 1 in main report and show the required display.
Take sub report and in that take only table 2 and display in footer and make sure don't link main report and sub report nor link two tables.
Ideally speaking, without linked table not used in crystal report as reporting tools used to display the relevant data based on our criteria and display 2 different set of data without link does not mean as a report as well as tough to integrate in crystal report.
Tough to integrate means at any point you have to link the table either via union in sqlserver or at crystal report side, other wise it display as Cartesian.
As per my thoughts you can do it by some approach.
Approach 1 : You can get the data by union or unionAll with set of columns and filter the data where table's column does not have null value ie.
http://www.maximumimpactsolutions.co.uk/blog/comments.asp?bd=118
Table1col1 Table1col2 Table1col3 Table2Col1 Table2Col2 Table2Col3
value value value null null null --table1data
null null null value value value --table2data
Approach 2 : Second is sub-report, but still need the linked as you already done. But there is proper rule to be set (this is very very tedious job).
Approach 3 : Generate 2 report at c# side and merge into one PDF, then export it.
check this links.
Reporting on multiple tables independently in Crystal Reports 11
http://www.tek-tips.com/viewthread.cfm?qid=241195
http://www.crystalreportsbook.com/Forum/forum_posts.asp?TID=4756
http://www.codeproject.com/Questions/348959/Crystal-reports-for-multiple-tables

Is it possible to pass a report dataset as a method parameter to a custom assembly in SSRS 2008 or above?

TL;DR In a SSRS 2008 report which uses a custom assembly to do some extra calculations can I pass an entire report dataset as a method parameter?
Full story
I have an SSRS report with 3 datasets, each returned from an SQL query.
(In case it makes a difference to my question they're currently shared datasets although I'm sure local would work too)
The largest and primary dataset is a list of tasks which may or may not have been completed. I have information in here such as the ID, status, create date/time, target resolution hours etc of each task.
This dataset is displayed in a tablix and is the focus of the report.
The remaining two datasets are not displayed and are for reference. One is a simple one column query which returns a list of holiday dates for the UK. The other is a small table which contains our exact business hours.
At the moment I'm able to loop through the rows in the tablix of tasks and pass multiple values from the current row to a method. This is useful if I want to do some calculations based on data found only in the current row. For example I could take the create date/time and the response target hours and the assembly would return a target date/time for the current task. Cool so far.
I want to do a more complicated version of this where I not only pass in the row data but the 2 other datasets to get my return value. This is because in reality the due date calculation is much more complex and must take into account changing business hours and holidays from the other 2 datasets.
Can I pass a dataset as a method parameter to an assembly? Something like:
=Code.MyClass.MyMethod(val1, val2, dataset1, dataset2);.
I've been unable to find much definitive information on this. Nearly all tutorials demonstrate what I'm already doing by processing single rows. I'm sure I had an MSDN article that hinted this was not possible but I've lost it (helpful I know). There's a post on the Microsoft forums where a moderator says it's not possible. The general lack of information and tutorials suggests it's not possible or I'm doing this in the wrong way.
Any suggestions?
(I have alternate solutions such as having the assembly fetch the other datasets or just writing something outside SSRS but I'm not pursuing those until I knnow whether it can be done this way).
An older topic on the MSDN forums Iterate through rows of dataset in report's custom code offers a more definitive answer as well as a potential solution to this problem.
Passing the DataSet as an object or collection is not a possibility because:
A dataset in Reporting Services is not the same type of object as an ADO.Net dataset. A report dataset is an internal object managed by the SSRS runtime (it's actually derived from a DataReader object) and not an XML structure containing datatables, etc. and cannot be passed into the report's custom code.
The only way to effectively loop through the rows of a report dataset is to call a custom function or referenced method in a report data region expression. Using this technique, it may be possible to pass all of the the row and field information into a code structure, array or collection.
The hint given in the above statement suggests passing row and field information into a code structure. A contributor to the linked MSDN topic, Migeul Catalao developed a workaround using such an approach.
A real-world scenario of it's usage with example code demonstrating Migeul Catalao's solution can be found here.
Granted, it is still more of a row-by-row approach, so I would strongly suggest moving outside of SSRS and pursue alternative solutions.
Although I've accepted the other answer due to it being clear and helpful I didn't use that solution in the end (I was too stupid to understand it) and went for something else that works.
Disclaimer: This is a horrible hack. It works absolutely great in my scenario so I though I'd share in case it was useful to somebody else. There are many pitfalls here which could most likely be worked around given time.
I ended up following the advice in the comment given by Steven White and looking into LookupSet. This function allows you to query a dataset to return matching rows and a single column of data.
It looks like this:
LookupSet(Fields!ComparisonField.Value, // The value to search for, e.g '001'.
Fields!MatchField.Value, // The column to match on in the target dataset.
Fields!MyColumn.Value, // The column that will be returned.
"MyDataSet") // The dataset to search.
This returns a string array representing the returned values.
So far so good, but I needed ALL columns and rows. This is where the dirty hack appears in the form of string concatenation:
LookupSet(0, // Dummy ID 0.
0, // Matches the dummy ID 0 so all rows are returned.
Fields!Column1.Value + "[^]" // I concatenate all of the values into
+ Fields!Column2.Value + "[^]" // one string with the separator [^]
+ Fields!.Column3.Value, // so I can split them later.
"MyDataSet") // The dataset to query
I can now pass this to my custom assembly:
=MyAssemblyNamespace.Class.Method(LookupSet(0,0,Fields!Column1.Value..., "MyDataSet"), other, parameters, here)
Now in my C# method I have a generic object which after some reflection is actually an array of strings.
Cast to something useful:
var stringList = ((IEnumerable)MyDataSetObject).Cast<string>().ToList();
Split it:
foreach (var item in stringList)
{
var columns = item.Split(new[] { "[^]" }, StringSplitOptions.None);
// columns is a string[] which holds each column value for the current row
// So columns[0] is the value for column 1 in this row
// In my case I pushed the values to a DataTable row each time and built a datatable
// which when finished represented my dataset in full with all rows and columns.
}
I hope this makes sense to anyone trying to achieve a similar result.

conditions handling in reportviewer control

I have report in .rdlc format. I have inserted table in my report which is filled in programatically(in runtime) from datatable(which is also filled by dataadapter programatically). Also I want in table to use conditional formatting - background color of cell based on value. To do that in BackGroundColor property of needed column expression was inserted:
=iif(cdbl(Fields!MyField.Value),"Green","Yellow")
I haven't mentioned that all fields in my datatable are string. Therefore i use cdbl function to convert string to double. And when I render report, i don't have the desired result.
Therefore questions:
How to make sure there is no parsing error?
Is it possible to see step by step computation (as in excel)?
And what else error could be?
I suspect problem might be in culture.
The quickest way to test is to call
=iif(cdbl("3.14"),"Green","Yellow")
=iif(cdbl("3,14"),"Green","Yellow")
And see if it's working.
I don't have a reporting services right now and can't test it. I think you can do a tryParse in Reporting services.

Categories

Resources