How can I conditionally group items in Crystal Reports? - crystal-reports

I have a report that is currently separated into two reports, and I'd like to merge them.
Basically it boils down to this:
I ask the user if they want to have a page break for each Property, if they answer yes, I sort/group by Property and then I sort by X
If the user answers no, I want to just sort/group by X
I've tried suppressing the initial Grouping if the user answers No, but it still sorts accordingly (not how I want it to).
How can I do this without keeping it in two reports?

Instead of suppressing the grouping field, try setting it to an empty string "". I was just working on a report last week that was very similar. Even if 'no grouping' was selected, the report was still being grouped by some unknown default. In the formula grouping field, I found that if 'no grouping' was selected the field was not getting set at all. Once I changed it to set the field to an empty string, the report generated as expected.

Are you grouping or sorting? If you do not use the group header/footer it is basically the same as sorting and you should simply use the record sort.
In general, to conditionally group fields you would use formulas. For this to work the fields in question need to be returned as the same type: number, string, date, etc. In your case it sounds like the first grouping formula would be like this...
//{?break_by_property} would be the parameter value to control the page break
if {?break_by_property) then
{the_property_field}
else
"" //any static value of the same type as {the_property_field}
now go the "new page before" formula for that group header and enter this boolean formula (groupnumber is a special keyword)...
{?break_by_property} and groupnumber > 1
then add a record sort for X.

Related

Crystal Report create separate report pages based on field value change

Looking for some advice related to data grouping and printing in Crystal Reports.
I'm working with an order confirmation form. Ideally I would create separate report pages based on a specific field value change for the 'warehouse' field. So, if any given line on an order comes from warehouse A, it prints together. Then we'd get a page break, and we'd see the form repeat for any lines coming from warehouse B.
I've inserted a new group for "warehouse" and configured the group as 'New Page Before.' But when I attempt to print I'm getting an error related to "There must be a group that matches this field". So there must be some pre-existing grouping that I'm not considering. I'm hopeful I can figure this out.
I am interested to get thoughts on overall design, and if the grouping approach I am trying to take is even the correct one.
Somewhere in your report you probably have a formula such as:
Sum({some_value}, {some_field})
where the {some_field} used to be -- but is no longer -- grouped upon.
Fix that expression to set the desired aggregation level (the 2nd argument) to a field you are actually grouping on.

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.

Consolidate rows in report

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.

How to suppress specific bar on bar graph in crystal reports?

So I am trying to suppress a specific bar on my bar graph. So instead of populating the graph from the database, I am populating it from a formula field. So in my formula field, I have something like this:
if field <> "Member" then
formula = field
So it gets rid of the field however it leaves me with this:
I know I can make a subreport that gets rid of that field from the beginning, but I was hoping to avoid creating a subreport for this.
Any ideas? Thanks!!
Instead of leaving the group name as blank when the field is "Member", I suggest changing it to be the same as another group which you can always expect to appear on the report - perhaps "SR not handled timely".
This would lump in all the member values with the other group's values, so if you haven't already done so, I suggest graphing the value of a derived field which is set to 0 for "Member". (I suspect you have already done this, as the blank group is showing a value of 0.)
The least error-prone method is probably the subreport. If this report is very dynamic, and you always want to hide group A in the graph regardless of it's value, then this is the best way to go.
If a static number of groups will be appearing in your graph, you can limit to display the top N groups. i.e. If there are 7 groups total, and you only want to hide 1 of them (which always has a value of 0), then you can display the Top 6 groups (picture is of Crystal XI):
Thanks for all the help guys, the data will be pretty dynamic.. So I am going to go with the subreport. I will add those little tricks to my toolbox though! Thanks again.
Alternatively, you can set a "specific order" and only include the values you want to include in your graph. In the "Other" tab you need to select "Discard all others".

How to count field in Crystal Reports?

First of all, I am new to Crystal Reports so maybe what I am asking might say is stupid.
I added some tables and I want to count the appearance of a field depending on another field in the same table. If the other field has a certain value, I have to increase the counter. I have to use the returned value of the counter as a custom field in my report. I have to add multiple fields like this one, counting another thing. So...
How do I do this counting?
Thank you very much for your answers !
I'd use running total field, evaluated by function (formula), which checks other field value.