I am modifying a subreport that prints optional report card comments. The data that is supplied (via a stored procedure) is in this format (trimmed for brevity):
StudentID / Grade / CourseNum / ReportCode / CName / Comment
9999991 / KG / EA0_AM1 / M1 / T1Comment / Pam is good!
9999991 / KG / KP0_PM1 / M1 / T1Comment / Pam is okay!
9999992 / 3 / EA3_AM1 / M1 / T1Comment / Joe is good!
9999993 / 5 / EA5_AM1 / M1 / T1Comment / <null>
If a student is not in kindergarten, the only comment I want to print is the one where CourseNum = "EA?_AM1". If they're in Kindergarten, however, the comments should pull from "EA0_AM1", "EA0_PM1", "KP0_AM1", and "KP0_PM1", and those comments should be concatenated. The original report would only print the comment from either "EA0_AM1" or "EA0_PM1", but not both (it didn't know about the other two kindergarten classes, and it used a running total to find the maximum value for Comment), but among the four potential classes there are two potential teachers, and this year they both want their comments to appear on the report card. I don't think it matters, but here's the record selection formula:
(Select {?Marking Period}
Case '1' : {ReportCode} = 'M1'
Case '2' : {ReportCode} in ['M1', 'M2']
Case '3' : {ReportCode} in ['M1', 'M2', 'M3']) and
(Select {Grade}
Case 'KG': {CourseNum} in ["EA0_AM1", "EA0_PM1", "KP0_AM1", "KP0_PM1"]
Default : {CourseNum} like "EA?_AM1")
({?MarkingPeriod} refers to the trimester we're interested in.)
The problem I'm encountering springs from the fact that we want to print T1, T2 and T3 comments separately. I found the start of my solution in an answer given by Abhilash Kumar in a thread here: http://scn.sap.com/thread/3195910. Based on his answer to someone else's question I created a formula GetAllCommentsT1:
WhilePrintingRecords;
stringvar array arrT1;
numbervar iT1;
if not(({Comment} in arrT1) and ({CName} like "T1*")) then
(
iT1 := iT1 + 1;
redim preserve arrT1[iT1];
arrT1[iT1] := {Comment};
);
arrT1[iT1]
GetAllCommentsT2 and GetAllCommentsT3 are identical except that all instances of "T1" are replaced with "T2" and "T3" respectively. I placed these three formulas in the Details section (this section is suppressed: only Group Footer 2a through 2d are enabled).
To display the results, I created three formulas (DisplayT1Comments, DisplayT2Comments, and DisplayT3Comments). All are similar to this:
WhilePrintingRecords;
stringvar array arrT1;
join (arrT1, CHR(13) + CHR(13))
with "T1" replaced with "T2" or "T3" as appropriate. DisplayT1Comments is placed in Group Footer 2b, DisplayT2Comments is placed in Group Footer 2c, and DisplayT3Comments is placed in Group Footer 2d.
Using the data mentioned at the beginning of this question, for StudentID: 999991 DisplayT1Comments is "Pam is good!\n\nPam is okay!", and that's exactly what prints in Group Footer 2b. Since no T2 or T3 comments have been entered yet (verified directly in the database), I would expect both DisplayT2Comments and DisplayT3Comments to be null. However, when I run the subreport the contents all three footers are displaying "Pam is good!\n\nPam is okay!"
Any ideas what I've done wrong? Or maybe suggestions for a better solution (i.e.: one that works!) to my problem? Thanks!
The problem was a stupid logic error on my part: the line that read
if not(({Comment} in arrT1) and ({CName} like "T1*")) then
should have had the not moved inside the first parenthesis, so it negated ({Comment} in arrT1), and not the whole thing. That's what I get for blindly rushing in to modify existing code rather than sit down to think for a moment. Thanks to those who asked for clarification.
Related
I cannot find a solution or workaround that applies to my problem.
I have a complex report that includes several calculations at different levels.
GroupLevel4, which is ({Command.START_TIME}, "by second") has a formula field -- lets call it {Formula_Field1}.
It is defined as:
If DistinctCount ({Command.RECORDED_TIME}, {Command.START_TIME}, "by second") >= Maximum({Command.DOCS_NEEDED}, {Command.START_TIME}, "by second")
then 1 else 0.
It returns either 1 or 0.
Now I want to create a formula at Group3 level that says:
If Sum({Formula_Field1}) >= Maximum({Command.DOCS_NEEDED}, {Command.ID})
then 'Y' else 'N'
However, I can't summarize Formula_Field1 because it's based on something that is already a summary. I feel like I've tried everything. I tried some suggestions I found about declaring variables, but I think they were more specific to a straightforward sum of a sum.
Any suggestions are appreciated.
I am trying to create a QR code in the PF that contains the information of up to 15 records in one QR code. If there are 16-30 records in the report they need to be on a second page with a new QR code for these records. 31-45, 46-60 etc.
The QR code has a general header, followed by the data of up to 15 records (order #, part #, qty,) then finally a general footer.
The code I have now populates and scans. The trouble I am having is breaking the records apart into different pages/codes. I can get one page for all records or one page for each record.
The QR builder formula in the details section (adds the header, body, and trailer together):
WhilePrintingRecords;
evaluateafter ({#QRCode Header});
evaluateafter ({#Body1});
evaluateafter ({#Body2});
evaluateafter ({#Body3});
evaluateafter ({#Body4});
evaluateafter ({#QRCodeEoT});
if RecordNumber in (1 to 15) then {#QRCode Header}+ {#Body1a} +{#QRCodeEoT}
else if
RecordNumber in (16 to 30) then {#QRCode Header}+ {#Body2a} +{#QRCodeEoT}
else if
RecordNumber in (31 to 45) then {#QRCode Header}+ {#Body3a} +{#QRCodeEoT}
else if
RecordNumber in (46 to 60) then {#QRCode Header}+ {#Body4a} +{#QRCodeEoT}
An example of the #Body1 formula, in Details:
Global StringVar Build1;
EvaluateAfter ({#BodyBuilder});
If RecordNumber in (1 to 15) then
Build1:= Build1 + {#BodyBuilder}
else Build1:=""
Body1a formula in PF truncates Body1 but it is not doing anything, Body 1 and Body 1a pull the same data..
Left({#Body1}, (if(Length({#Body1})- Length({#BodyBuilder})<=0) then 0
else (Length ({#Body1})- Length ({#BodyBuilder}))))
I tried to replace {#BodyXa} in the QR builder with the respective global variable BuildX, to no avail. Also, the QR codes grow in size with 1 being the smallest, 15 being the largest, and at 16 it starts over again. Which makes me think they are accumulating e.g. 1st page has 1st record, 2nd page has 1st and 2nd records, so on.
I've been trying to change the way the variables build on each other, it seems like the records are not appending correctly.
Any ideas are appreciated.
Thanks!
Hopefully a straight forwards question.
I have a Report that runs from a stock system, it prints to show all the products in a customers order, as well as a general 'Thank you for your order..' message.
In the details section it currently shows Product and Product Description for everything within that order.
I have a new client though who wants another version of this report, one which only shows the details lines where the Product Code ends in the letter 'C'.
I'm guessing I need to suppress the details section but I'm not sure what Formula I should be using.
I also can't say for certain that all their product codes will remain the same length. I think about 95% of them will be 8 characters, but any 'special edition' versions may have extra characters in.
Thanks in advance for your help.
A suppression formula needs to return a Boolean value, so a formula checking the last character in your Product Code field should do it:
right(trim({ProductCode}),1) = 'C'
To make it work for a single client, you could do something like this (warning: I'm rusty with Crystal syntax - take it with a grain of salt):
IF {CustomerCode} = 123
THEN right(trim({ProductCode}),1) = 'C'
ELSE false
right(trim({ProductCode})) <> 'C'
I am trying to use a global variable to calculate a bonus. I can get the variable to count correctly with the exception that it is not resetting when changing groups. I have three groups - Property, Agent, Type. I have tried to put the reset in every group footer - neither of which are suppressed - and the counting continues. If I use WhilePrinting/ReadingRecords it works fine but then I cannot use the variable in any formula as I get a "summary has been specified on a non recurring field" error.
Here are some sample codes I am using
#LeaseCount- this is in the detail section
EvaluateAfter({#Effective Rent});
global numbervar x;
x:=IIF({#Effective Rent}>={Command.Yieldstar}, x+1, x)
#reset_x
global numbervar x:= 0;
#bonus
IF {#LeaseCount} in 0 TO 6 THEN 50.00
ELSE IF {#LeaseCount} in 7 TO 11 THEN 80.00
ELSE IF {#LeaseCount} >= 12 THEN 100.00 ELSE 0.00
Else 0.00
I have the bonus section evaluating after the counter. Again everything is working just fine except the reset of the variable. If I try to use a shared variable it breaks with the "non-recurring" error. I think i have tried everything I can find and at a loss.
I believe it is something to do with timing I am just not well versed with CR timing but then it may just be my coding. Any help is greatly appreciated.
Try to declare it as "shared" instead of "global". Remember to change the declaration in both formulas: #LeaseCount and #reset_x.
If it does not work, try to change #reset_x in two lines:
shared numbervar x;
numbervar x:= 0;
The issue was with a summary field in the Agent footer. After deleting the summary field and moving the variables to SHARED it solved the immediate issue. I then used another variable to do a running summary instead of a running total summary. –
I'm creating a invoice crystal report for sage mas 500 AR module. In it, I'm attempting to add the tarinvoice.balance field with the following formula:
if {tarPrintInvcHdrWrk.Posted} = 1 then
ToText({tarInvoice.Balance})
I'm assuming that when the {tarPrintInvcHdrWrk.Posted} = 1 conditional statement holds FALSE, it doesn't attempt to pull the invoice field because when I remove the formula from the report, the form displays correctly without it.
When the conditional statement renders true in the report, the balance fields behaves correctly. However, with the formula renders FALSE in the CR form, the entire crystal report bombs and displays blank. Any ideas why or what I'm doing wrong?
Just tried setting everything to zero and the report still bombs. I'm starting to think its more of a query error in the report. I wish there was a way to exclude the field in the query when posted = 0.
With tarinvoice.balance removed when the posted = 0, the report works fine.
With tarinvoice.balance included and posted = 1, report works fine.
With tarinvoice.balance included and posted =0, report bombs.
I believe the conditional statement fails immediately if you encounter a NULL, so your formula needs to test IsNull({tarPrintInvcHdrWrk.Posted}) before it tests equality with "1".
You can change the way Crystal handles a null value for a value in a formula. At the top of the Formula Workshop there is a drop down box that usually says "Exceptions For Nulls".
Change this to the other option "Default Values For Nulls" and your formula should no longer bomb out. You used to be able to specify the what the default values applied were, but more recent versions of Crystal have these hard coded.
Search the help for "Null Treatment" for a table showing them.
I modified the formula to this:
if isnull({tarPrintInvcHdrWrk.Posted}) = FALSE then
if {tarPrintInvcHdrWrk.Posted} = 1 then
if isnull({tarInvoice.Balance}) = FALSE then
ToText({tarInvoice.Balance})
else
"0.00"
else
"0.0"
else
"0"
The crystal report still bombs.. Nevertheless, it does show "0" in the appropriate space.
I saw a suggestion on Exp.Exch to try putting the field into a variable before converting it to text.
e.g.
NumberVar InvoiceBalance;
If isnull({tarInvoice.Balance}) then
InvoiceBalance := 0
Else
InvoiceBalance := {tarInvoice.Balance};
If {tarPrintInvcHdrWrk.Posted} = 1 then
ToText(InvoiceBalance);
I also tried to recreate your problem, since I have see similar things before.
No luck though trying with CR 8.5 & XI R2. Perhpas it has to do with linked tables as well, since I only tried on a simple single table.
I have also seen similar behaviour when using a formula within a Running Total - they do not like nulls at all!
If you put {tarInvoice.Balance} directly on report (into details "debug" section - often needed, don't forget supress it in production :)), what values it displays or does report become empty?
Maybe you have Suppress If Blank section on your report. Try to put: Else " "
if isnull({tarPrintInvcHdrWrk.Posted}) or {tarPrintInvcHdrWrk.Posted}=0 then
" "
else
if {tarPrintInvcHdrWrk.Posted} = 1 then
ToText({tarInvoice.Balance})
else
" "
I have trouble with this kind of field when making reports to export to excel. A field with no data in will pull all columns to the right of it over to "fill the gap".