Print field from first record in a group in the group footer - crystal-reports

I have a series of transactions that contain a receive and return date and are grouped. In the group footer, I want to print the receive date of the first record in the group and the return date of the last record in the group. I created a formula to populate only when it is the first record in the group. But if the group contains more than one record, the formula field prints out blank. If there is only one record in the group, it prints OK. I'm using SAP Business Object Crystal Reports 2013.

There are a few ways to handle this. If you were sorting by Date, (which I've just learned you aren't) you could use a Summary to find the Minimum value. You'd place it in the relevant Group Footer and it should reset each time.
But since you're not sorting them by Date, I'd try setting up a Running Total that counts the number of records in the current Group (and resets on change of group.) Then set up a Shared Variable in a Formula that gets set every time the Group Count resets to 1. Finally, put another Formula in the Group Footer which prints out the Shared Variable.
Done correctly each Group Footer will display the first date value in that Group.

Related

Crystal reports - Can't filter on custom formula number field

Crystal reports don't let me use a custom count formula field to filter which transactions to show in a manager report.
I'm creating a Crystal report that team leaders are supposed to take out to see on how many occasions their employees have reported in sick. A record is only supposed to show if that person has reported in sick 6 or more times the last 12 months.
The report shows a record (a page) for each employee belonging to the managers organisational unit. Below the employee information is a subreport where I show the transactions from the salary/time system. Using select expert, I have filtered out the transactions that is supposed to show. I have then created a database field that count which day was 12 months back from today, and filtered so that only the transactions falling into this period shows.
My last problem is that I only want to show the record that has a minimum of 6 such transactions during the period. I created a formula field named #Antal ("amount" in Swedish) that simply counts the distinct number of dates in the "from"-date for the salary transactions I'm showing (since a change of law 2019-01-01 we needed to create a new transaction type, so some of the occasions after 2019 may have two transactions referring to one sick leave, thus I'm counting the first day of the period instead), DistinctCount ({P_LSTAT.P_SXXX06})
Now, the subreport has a new column with Antal (amount) that counts the amount of the desired salary transaction. I then try to use the selection formula to only show records where {#Antal} >= 6 but I get the following error:
This formula cannot be used because it must be evaluated later
Is there any other (better) way of doing this, or am I simply missing something?
For your selection based on {#Antal} >= 6 you need to use the group selection formula, not the record selection formula. Record selection is used to select records which meet the criteria before reading in the data. Group selection is used to filter out entire groups of records based on summarised values, after the records have been read in and the summaries calculated - which sounds like exactly what you need here.
The value of a Formula Field is out of scope when the Select Expert is evaluated.
There is no process for calculating the value of a Formula Field before it is printed within the section of the report it is placed. The Select Expert is evaluated prior to any section of the report being printed, so at this time all Formula Fields are effectively Nothing.

Jaspersoft Studio subtotal from amount shown on group header

I have data that is "filtered" through three groups.
First group is defined by departments, second is defined by course id and third is for individual class session id (i.e. room and schedule). Also the source query is giving me the list of all students for each class session, and this causes that the other columns get repeated for every student (i.e. credits per course, total enrollment per session, total students dropped per session, total students auditing per session, etc).
When you drop any of those query counts on the report group's footer the sum is not correct. For example if we have 10 students for a session our sum is 100 enrollment. I want to count 10 enrolled students only once.
The amounts are not shown multiple times because I placed the fields on the group header. So on every group break the row of data is displayed only once.
I believe I need a custom running total and not the default created when you drag and drop the field on the group's footer.
I got something working.
On the report Outline I right clicked on 'Variables' and 'Create Variable'.
For example for the audit count I did the following:
Named my variable 'sum_au'
Value Class Name set to java.math.BigDecimal
Calculation set to Sum
Expression set to the query field for the audit total 'AU': $F{AU}
Increment Type set to [Group]GroupBy_CRN
Reset Type set to [Group]GroupBy_CrseNum
All other fields left untouched (default values)
Once this variable is created you can drag and drop it to the CrseNum Group Footer and it will add the values only once per break on the course session id (CRN).
I will reproduce this for the other values to see if this solution is consistent...

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.

Check last record of each group

My formula needs to detect when it reaches the last record in a group before the group changes. I tried using both OnLastRecord and creating a running total field (which resets on change of group) to do this. In both cases it only checks the very last record on the very last page of the report.
My ultimate goal is that I want my report to check if a number field, {#Calc} on the last record is < 0. If so output "Outsanding:" &{#Calc}*-1.
I have figured out my problem. I am now using:
{grouped field} <> next({grouped field})
which gives the value of last record for each group value.
Have you considered using the Group Footer for the group in question?
When you reach that particular footer, the active record will be the last one in the group. So any calculations you perform, or any fields you choose to print, will be based on the final record read in that group.
Note: If you're suppressing some records in the group, this might not work. In which case, you can instead use Shared Variables to store the latest valid value for Calc.
Then by the time you reach the footer, you can check to see if the variable is less than zero and display your Outstanding field based on the result.

Referencing first record in a group in crystal reports

In my report, in group footer, I want to add the sum on a column from all records in the group except the first one. How can I do that?
I tried Insert - Subtotal but it adds all records. If I can access the first record from each group, I can subtract it from the sum.
Let's say you're grouping your report by {Table.GroupID} and want to get the total per group, excluding the first record in the group, for {Table.NumericField}.
You can do this by creating a running total where:
Field to summarize: Table.NumericField; Type of summary: Sum
Set to evaluate with a formula: previous({Table.GroupID})={Table.GroupID}
Reset on change of group
The second step ensures that the group total is updated for every record except the first one in the group and can be read as "Only evaluate this running total when the previous record's GroupID is the same as the current record's GroupID.