Problems converting a crystal reports running total string to a number - crystal-reports

I have a problem with converting a running totals string to a number.
The running total is set to retrieve the maximum value of a field that contains results. It is reset with change of a group and evaluated by a formula so that only results from a specific test is used.
The result database field is a string since there are test with text results as well as tests with numeric results in the database. The test I'm filtering out only have numeric results (saved as string).
The running total works fine and gives the correct result, but I want to change it from a string to a number to be able to set the number of decimals and use rounding in the report, and this is where my problem begins.
As far as I can tell there is no way of using the format field in this case. (Which is resonable since it is a string field.)
I've tried using a formula field with the following formula:
if isNumeric({#P-LDL}) then toNumber({#P-LDL})
but that returns 0.00 for all non-null values even though the strings are nice things like "2.36" or "3.74" (without the quotes).
I've also tried the old school approach of resetting a global variable in the group head, assigning it a value in the details section when a post with the correct test comes along, and then finally display it in the group footer, but I get the same 0.00 result. I've tried both using a numeric global variable and do the conversion on the details-level, and using a string variable and do the conversion in the footer-level.

Solved it:
if NumericText(Replace({#P-LDL}, ".", ",")) then
ToNumber(Replace({#P-LDL}, ".", ","))
Stupid locales...

Related

Group data based on different size

I am trying to make a report in which I need to show data based on Width groups. Below is an example of data & the required output. I'm unable to make a group which can give this required output. If someone can help please.
The easiest way to accomplish your grouping needs for this data set would be to create a new Formula Field that evaluates the values of the Width data field for each record to determine which group the record belongs within, then do the grouping on this new formula field.
You formula field will look like this.
Select {WIDTH}
Case 400 to 600 :
"G1"
Case 601 to 849:
"G2"
Case 850 to 1049:
"G3"
Default :
"Default text or error message text goes here"
You will likely need to adjust the integer values I'm used in the Case statements to evaluate the WIDTH field. The text that goes into the Default case is up to you. In fact, if it works logically with your needs, you could eliminate the Default case entirely, as it is not required. However, it is good practice to ensure the Switch statement always returns a value, even if that value is text to indicate that something unexpected occurred. This allows your users to easily recognize a bit of a data that may be out of range for the grouping of the report so the report can be modified or the data can be corrected, whichever is the most appropriate action.
The other 3 columns in your required output appear to just be counting the number of records within each group that have a diameter within a range. To get this output you can use Running Total Fields with a Type of summary of Count and then use the range of values in the Evaluate section. The Reset section will be set to On change of group evaluating the group created by the formula field above. You will want to put a sort order on the diameter field though.

Repeating a result on a line on the rows/lines below untill that result changes?

Image showing problem
I want to know if there is a way of repeating the result of a column downwards until the change of result.
Attached image shows the problem.
I need 9.1stWC column to fill the number(which is actually a string) all the way down until that number changes.
The column is not null where the blank fields are (9.is null, shows this) so I'm going to have to write additional formulas to show I'm guessing.
I've used previous function but that only shows for the next line down then is blank after.
The replicate string function will go across the column not downwards.
I've looked at a stringVar but cant find a way of making this work on this report.
I'm reserved about grouping as I have a lot of other filters and by grouping I could possibly loose the sequence depending on what I group by.
My aim is to show WC which are equal to the current op line by doing a simple formula after I have managed to populate that column
I will assume your column is a field named {Result.WC}.
Try this:
Create a formula. Let's call it #LastWC.
Use this code in the formula:
shared stringvar sharedLastWC;
if not isnull({Result.WC}) and {Result.WC} <> "" then sharedLastWC := {Result.WC};
sharedLastWC; //returns
Replace the field by the formula.
The idea behind this is to set the shared variable when the field is not blank and not null. So, the variable will hold the last "filled" value.
I can't make a test with the purposed solution right now, but give it a try and make adjusts if you need. Tell me if it does not work.
If the first row can be empty, you may need to create an aditional formula do start the value of the shared variable in the header of the report.

Rounding to a variable number of decimal places in SSRS

I am trying to find a way to round a field in SSRS to a dynamic number of decimal places. I know I can format it dynamically, and it may eventually come to that, but many of my users are going to take this report directly to Excel and are going to want to have actual numeric fields.
My t-SQL code includes these declared variables:
NumLong01 DECIMAL(23,8)
, NumLongDP01 INTEGER
The first set of entries in this table is for headers and rounding parameters. So I add values for these two as:
NULL
,4
and then I add the actual table values as:
543210987654321.87654321
,NULL
That way I can put a whole series of numbers into the table but they all have to be formatted the same way.
Running this query yields:
When I go to ReportBuilder, my field has this expression:
=Fields!NumLong01.Value
If I want to format a certain number of decimal places, I can just do this:
=Round(Fields!NumLong01.Value,2) or some such. What I tried to do, though, was to make it dynamic:
=Round(Fields!NumLong01.Value,First(Fields!NumLongDP01.Value, "DataSet1"))
This ended up rounding to 0 decimal places. I subsequently learned--by just using the second half in my field--that this was a NULL value. So I tried Sum instead of First--again, just in my field--and got the 4 that I expected. Great, so now I had my number, and I just put that in as my rounding:
=Round(Fields!NumLong01.Value,Sum(Fields!NumLongDP01.Value, "DataSet1"))
Only problem is, this yields an error. Next I asked myself if maybe it wasn't seeing this as a number for some reason. So i just added it onto my field. No problems. So I really don't know what it's doing. Is it thinking that this field might become so long that it will round to an illegal number of decimals places?
Now, I can do this:
=IIf(Sum(Fields!NumLongDP01.Value, "DataSet1") = 8,Round(Fields!NumLong01.Value,8),IIf(Sum(Fields!NumLongDP01.Value, "DataSet1") = 7,Round(Fields!NumLong01.Value,7),IIf(Sum(Fields!NumLongDP01.Value, "DataSet1") = 6,Round(Fields!NumLong01.Value,6),IIf(Sum(Fields!NumLongDP01.Value, "DataSet1") = 5,Round(Fields!NumLong01.Value,5),IIf(Sum(Fields!NumLongDP01.Value, "DataSet1") = 4,Round(Fields!NumLong01.Value,4),IIf(Sum(Fields!NumLongDP01.Value, "DataSet1") = 3,Round(Fields!NumLong01.Value,3),IIf(Sum(Fields!NumLongDP01.Value, "DataSet1") = 2,Round(Fields!NumLong01.Value,2),IIf(Sum(Fields!NumLongDP01.Value, "DataSet1") = 1,Round(Fields!NumLong01.Value,1),Round(Fields!NumLong01.Value,0)))))))))
...and that works. But it seems like such a ridiculous way to go about it.
I'm also comfortable passing only rounded numbers out of t-SQL. But then I run into the problem of showing only a certain number of decimals on the report, because in the number formatting it doesn't allow for a dynamic number of decimal places for some reason.
Any ideas would be appreciated.
This isn't an exhaustive list of ways to accomplish dynamic rounding or number formatting as you can achieve this using custom code in the report or by adapting your dataset's SQL query.
Using Rounding:
The first set of entries in this table is for headers and rounding parameters. That way I can put a whole series of numbers into the table but they all have to be formatted the same way.
To avoid building expressions in your report that require aggregate functions such First and Sum and generating a blank row that you then have to remove, consider just entering the number of decimal places for every row instead of using a header row. The costs (storage and expression evaluation) are low even if it seems redundant.
This means that instead of using: =Round(Fields!NumLong01.Value,First(Fields!NumLongDP01.Value, "DataSet1")) you can use =Round(Fields!NumLong01.Value,Fields!NumLongDP01.Value) either as an expression or as a calculated field in DataSet1 or whatever your dataset is called.
Using Number Formatting:
But then I run into the problem of showing only a certain number of decimals on the report, because in the number formatting it doesn't allow for a dynamic number of decimal places for some reason.
You can define custom formatting for the NumLong01 field in the report and make it dynamic using an expression to build your custom formatting string.
Open the Text Box Properties for the NumLong01 textbox or tablix field
Open Number tab and select Custom from the Category list
Click the fx button and use the following expression ="0." + StrDup(First(Fields!NumLongDP01.Value, "DataSet1"), "0")
Using your example data, this expression would produce the custom formatting string 0.0000 which changes 543210987654321.87654321 to 543210987654321.8765. For your information, StrDup duplicates the specified string X number of times.
In cases where the fractional part of the number is less than the decimal precision required, this formatting string will pad it with 0s. If that's not desired, change the string to be duplicated to "#" like so: StrDup(First(Fields!NumLongDP01.Value, "DataSet1"), "#").
You can also use this method as a calculated field in the dataset but only if you have removed the header row and are entering the decimal places for every row as mentioned earlier. This is because you can't use the aggregate function in the calculated field expression.
To do this, add a calculated field to your dataset with the expression: =Format(Fields!NumLong01.Value, "0." + StrDup(Fields!NumLongDP01.Value, "0"))

Using running totals in formulas - Crystal reports

I have created a set of running totals looking for specific fields in a database.
If these fields are located, a subsequent sum is performed to calculate the total for that field. e.g. Field to Summarise - DB.Field.Value-Sum. Evaluate - Use a Formula-Field Name ='1'
This sums the totals for this field. The issue is that I have many running totals doing this, and what I want to do is add these together to provide a total for all of these. Currently I have a formula that uses each field with a '+' between each. This appeared to work fine, but when tested against a record where some of these fields are blank, the subsequent formula displays nothing.
Any advise on what I should do here/ am doing wrong?
Thanks
It sounds like a null record (empty value) is breaking your running total. You have a few options
Use a formula to check for, and replace a null value with another value (Zero, for example) and then use that formula in your running total calculation
if isnull({Command.Decimal}) then 0 else {Command.Decimal}
Use a SQL expression to replace null with another value Isnull(Tablename.Columnname,0) - use this in your running total
On the running total, under "evaluate" select Use a formula and use this formula not(isnull({tablename.columnname})) -- If the record IS null, the running total does not evaluate it. It will be ignored by the running total.

Numeric Overflow in crystal report

I have a numeric field in my report that I perform the operation
Time({Command.EndTime}/60,Remainder({Command.EndTime},60),0)
on.
Basically the field is a time field but my predecessor used a numeric field to represent it for some unknown reason. The field is the number of minutes past midnight. For example: 60 is 1am, 65 is 01:05 am...) I would like to report it in a form that is more human friendly. However, I got this error "Numeric overflow" and wonder what might have caused it. Normally, the cause of this error is a division by zero but the divisor is clearly 60.
If I just used {Command.EndTime}, the report was fine... The database is huge with millions of records, so scanning the report line by line is only my last resort. Is there a way to know what was wrong in the data or better yet get around the error mentioned above?
Thanks!
The first parameter to Time() has to be a whole number. Try this instead:
Time(Truncate({Command.EndTime}/60),Remainder({Command.EndTime},60),0)