Consolidate rows in report - crystal-reports

If a row has the same ID as the last one, I want to combine them - summing up the cubicFt and Savings. $perFt divides the savings by the cubicFt, so it wouldn't be summed, simply dividing the new results. I also want the Descriptions to be concatenated, like this:

Make a Group based on ID (or whatever the leftmost column is). Then suppress the Details section and the Group Header. Instead, you'll be putting all the fields you want to display in the Group Footer. From there it's simple:
Create a Summary or Running Total for both cubicFt and Savings.
Reconfigure your $PerFt to use the summary/running total fields you made in step 1.
Combine the Descriptions by creating a shared string variable Descriptions. Whenever the group changes, reset it with Descriptions = "". Whenever the group doesn't change, add the description string to your variable. Something like:
Descriptions = Descriptions & " ; " & {yourtable.Description}
Then create a final formula ShowDescription in the Group Footer to display the results with RIGHT(Descriptions, LEN(Descriptions)-2)

You need to do grouping, either by modifying the SELECT statement or the stored query that generates the data, or within Crystal Reports. I'm literally 20 years out of date on Crystal Reports, although I have used similar software, so this will have to be tweaked.
For the first solution, all you need is a concatenation aggregation function for the string field. Your DB may or may not have one built in, so you may need to add it.
SELECT Building, ID,
SUM(cubicFt), SUM(savings),
SUM(savings)/SUM(cubicFt) AS [$perft],
LEFT(STRING_AGG(description, ';'), -1) -- drop extra ; at end
GROUP BY Building, ID;
However, you should be able to do the same within Crystal by setting this up as a subtotal group (not sure if you have to do user definitions for the string aggregation), and then hiding the detail section.

Related

jasper report show count on footer of a specific query

am very new to jasper report
also I have tried looking at videos but can not seem to get this one concept
basically there is this main query which i have
select * from table
which is populated in the details area
however i want a second query
select count(*) from table where name = "tim"
and put the count on the footer
can this be done using jasper
any tutorial to this concept or guidance would be helpful
to sum up the details area should show all the data where as the footer should only show counts of a few things.
You can only have one DataSet (therefore query) for the report. In your case this is your main report select * from table, which seems to be working well.
You have two options for adding the information you want:
(and I would say the better option) is to add a variable $V{tim_count} which is configured as:
initial value 0
expression value "tim".equals($F{name}) ? 1 : 0"
calculation function sum
there are multiple ways to increment this variable, so I'll leave that with you. In the footer you would then add a text field with the $V{tim_count} variable as it's contents.
You can read about variables here https://community.jaspersoft.com/wiki/variables
You can add an object that has it's own DataSet:
Table
List
Subreport
You would then be able to add your query to that object and display it appropriately. As you can see, displaying a COUNT is not really the most appropriate way to do this.
Note - I don't suggest this way

Crystal Reports: price for latest transaction

I need to create a field to put on group footer #1 that shows the latest price by customer type. The grouping is item_ID (see below). So for example if there were transactions over time with varying prices to Factories and to Retail stores, it would only show the price for the last time that item was sold for a factory(I have a separate field for retail stores). I have tried a few things but nothing is working. For example:
On the detail level:
if {TRANSACTIONS.TRANDATE} = Maximum ({#FactoryTranDate}, {TRANSACTION_LINES.ITEM_ID}) then
{TRANSACTIONS_LINES.PRICE}
FactoryTranDate is basically: if customer type = factory then trandate. Then I created a max of this on group footer #1.
This appears correctly on the transaction line but if the last transaction for that item wasn't to a factory, it will be 0 on the summary line. I tried to do a Max of that detail level field but it doesn't come up for my summary fields, I am assuming cause it gets confused upon doing a summary of a summary?
Sounds like the problem you are running into is the column of data you are trying to print in the footer has multiple rows and you can't predict where the value you want might be within those rows. So by the time you get to the footer, it only has the value held by the last row that printed.
To get around this you would want to use a few formula fields to create variables that can be used to store the value you want from the correct row when it is printed.
I would plan to use 3 formula fields. One to initialize your variable and set it to a default value of zero. Place this formula field in the header that corresponds to your footer and this will ensure the variable exists and is reset to a default value for each grouped value in this header. The formula will look something like this:
WhilePrintingRecords;
Shared NumberVar price:=0.00;
The second formula will declare the same variable again, and it will also include some logic to know when to set the value of the variable. This formula field should be placed within the section that prints the detail records for the grouping. The formula would look something like this:
WhilePrintingRecords;
If <condition to evaluate> Then
Shared NumberVar price:={TRANSACTIONS_LINES.PRICE}
I'm not entirely sure what condition you will want to evaluate here though based on the information you've provided, but I suspect it will be along the lines of if customer type = factory. However, it should be a condition that is only true when you want to capture the price of the detail record within the grouping. If you have multiple cases where it might be true, then you will want to sort them in such a way that the one you wish to capture is printed last within the group. Since you stated that it should be the last factory price, then I would sort by Transaction Date and the variable will change its value with each record that has a true condition and will only keep the price from the one with the latest Transaction Date.
The third formula field is simply for printing the value of your variable in the footer. This field will be placed in the footer section and will display the value of the variable on your report. The formula for this field will look something like this:
WhilePrintingRecords;
Shared NumberVar price;
The formula fields used in the header and details sections can be suppressed if you don't want them to print on your report, but I would recommend waiting until you have the final value printed in the footer verified before suppressing them. This will allow you to see how the value of your variable changes as the report is generated if you are not familiar already with using variable in this manner. You may also want to read up on the scope of variables in crystal reports if this is a new topic for you. My suggestions here all use the SHARED scope, but there are also LOCAL and GLOBAL scopes. GLOBAL might work better in your case, but I tend to favor SHARED in examples such as these because they have the most broad scope. LOCAL definitely will not work for you here though.

How do I do a CR-type formula in SQL Server Reporting services?

In Crystal Reports, I could define a formula that would evaluate for each detail line. For example, if I had a query that would return a PatientId, an ObsTerm name, and an ObsTerm value, I could define a formula called {#Hispanic} that had the value:
If {Command.OBSNAME} = "HISPANIC" Then
{Command.OBSVALUE}
Else
" "
Then, in the group footer, I could take Maximum({#Hispanic}, {Command.PATIENTID}) to see if I had gotten a value returned for the patient's ethnicity - either I'd get the value (assume only one, since that's how I built the query) or a blank.
I'm trying to convert a CR report over to SSRS 2008R2: how would I do the above? Thanks.
Add a calculated field to your data source (called 'Hispanic' or whatever) with a formula of:
=IIF(Fields!OBSNAME.Value="Hispanic",Fields!OBSVALUE.Value,"")
In your report, add a parent group to your detail row and type [Max(Hispanic)] into a field in the group row. You may then want to hide the detail row and show only the aggregate data. I think there's probably a much easier way to do what you want but it's not clear from your question.
I made the transition from Crystal to SSRS and it is a hard road. You need to unlearn all your Crystal (especially formatting).

Crystal Report-Running Total

I have a problem with running Total in Crsystal report9
if their is no values available for a Paticular field how can we return the running total as '0'
Instead of display the Running Total directly in your report create a Formula Field based on the Running Total and drag it into the report.
Your formula should look like this (Crystal Syntax)...
if ISNULL({#RunningTotalField}) then
"0.00"
else
ToText(RunningTotalField, 2)
If there is no data for that particular group, then Crystal won't show it easily. Your options are :
1) Use subreports to display the values for a particular group, and keep the main report just looking at the table(s) containing the group headers.
2) Use a stored procedure as the source so you have full control over the SQL that is run.
The problem is that as soon as you use a field to group, Crystal will only return records where that field has been used. If it was simply in the Details section you could modify the link to a LEFT JOIN and it wouldn't matter, but the group forces the INNER JOIN which means the groups without data are not returned.
Unfortunately Running Totals don't show up if there are no records that match your criteria. An alternative is to use a set of formulas calculated in various sections of the report. The technique is widely described in the Crystal literature. For example, this TekTips gives a very succinct overview of your options.
You set up an initialising formula in each header, with the evaluation time directive "WhilePrintingRecords". This approach was the only one available for doing running totals in the "good ol' days" before RunningTotal objects were available.

Displaying static text instead of empty group in JasperReports

I have a Jasper report that displays a list of bill line items. These items are grouped by billing period, and then by whether the item is a charge or credit. For billing periods in which there are charges but no credits, I would like to display a static text field stating "No credits" in the Credit group for that period. How can this be done?
Edited to add: This is assuming that I am using an SQL query for the data source, as opposed to customizing one. If I customize my data source, I can handle this in pre-processing before I reach the report, but I was hoping to discover a way to get around Jasper's behavior of skipping groups with no rows meeting the group criteria.
If you were able to, in your data source, have a count of total # of credits for each group, then you could use the 'print when expression' property on the static text. e.g:
new Boolean ($F{total_credits}.equals(0));
The static text would need to go in the group header or footer as it wouldn't work in the group detail section (it would print out multiple times).
You may need to create a variable instead of use $F{total_credits} directly - I'm not certain how JasperReports deals with accessing fields in group footers. You may also find that in the group header it picks up the correct total_credits while in the group footer it doesn't.
The other way would be to have a variable that counts the total # of credits in the group. You would need to set the 'reset type' for the variable to 'group', then set the reset group. The Variable expression would be something like:
$V{myvariable} +
($F{credit_or_debit}.equals("credit") ? new Integer(1) : new Integer(0))
and the initial value expression would be new Integer(0)
Then in the group footer you could use the 'print when expression' on the static text to look at the variable.