I've been working on a report made by someone else which uses the StDev function. I thought it would be simple enough, but the data can contain multiple values for each record, so there are if statements used to determine which value to take from each record. I've exported a table to Excel which contains one value per record (the one that should be used in the StDev), and then calculated the SD there to provide a check.
The report and Excel are giving me very different values :(
So, I'm going back to the report and using some additional formula fields to calculate the SD longhand to act as a kind of deciding vote (fingers crossed it doesn't produce a third set of values...).
I've worked out the syntax errors, but am still getting a run-time error - "Division by zero" which then highlights the section of code indicated below...
My formula fields are:
{#StDevArrayPopulate} - in the details section
NumberVar Array varStDevArray;
NumberVar varStDevArrayCount;
varStDevArray [varStDevArrayCount] := {ValueToSummarise};
varStDevArrayCount := varStDevArrayCount + 1;
{#StDevArrayCalculate} - in the group footer
NumberVar Array varStDevArray;
NumberVar varCounter :=1;
NumberVar varMean := 0;
NumberVar varStDev := 0;
NumberVar varStDevArrayCount;
// START OF MEAN
// Sum of all of the values in the array
for varCounter:= 1 to varStDevArrayCount step 1 do
(
varMean := varMean + varStDevArray [varStDevArrayCount];
);
// Divide by the total number of values in the array
varMean := varMean / varStDevArrayCount; // !! This is the line that highlights after the error message !!
// END OF MEAN
// START OF STANDARD DEVIATION
// Subtract the mean from each value in the array and square the result
for varCounter := 1 to varStDevArrayCount step 1 do
(
varStDevArray[varStDevArrayCount] := (varStDevArray [varStDevArrayCount] - varMean) * (varStDevArray [varStDevArrayCount] - varMean);
);
// Sum of all of the values in the array
for varCounter:= 1 to varStDevArrayCount step 1 do
(
varStDev := varStDev + varStDevArray [varStDevArrayCount];
);
// Divide by the total number of values in the array
varStDev := varStDev / varStDevArrayCount;
// Square root of mean of differences
varStDev := Sqr(varStDev)
// END OF STANDARD DEVIATION
{#StDevArrayCalculate} - in the group footer
NumberVar varMean;
NumberVar varStDev;
"The mean is " & varMean & ", and the standard deviation is " & varStDev & "."
I've tried using a Running Total field but that was giving errors as it need to be count the first record before the Populate formula field ran. I've also tried adding a fourth field to the header, which initialises the varStDevArrayCount as 1.
Does anyone have any suggestions?
Looks like there are no detail records hence you are getting zero in array... I don't think initializing with 1 will make any difference instead make a small change like below and check.
if varStDevArrayCount=0
then
varMean :=varMean
else
varMean := varMean / varStDevArrayCount;
I would advice you to just check records in detail and then debug
Related
If an Order contains 2 lines or more, my report sums it up and prints the whole quantity of items. It should print whichever line I have chosen:
WhilePrintingRecords;
NumberVar ItemCount := ItemCount + 1;
ToText(ItemCount, "0") & "/"
& ToText(Count({rpt_PackingSlip.LabelQTY}, {rpt_PackingSlip.WorkOrderNo}),0,"")
For example, the order below contains a chair called Buzz, but the order contains 3 lines since each has different fabric. The total order quantity is 5:
If I print, the label count shows 1 out of 4 - which automatically sums the chair. If I select the first line, expected output is Buzz 1/2.. and 2/2. Currently output displays Buzz 1/4.. 2/4.. 3/4.. 4/4.. even if I just clicked 1st line. How can I achieve this result?
You'll want to reset the counter on each group. Just create a second formula and drop it in the group header:
global numbervar ItemCount := 0;
I have a formula in my Group Header which looks like the following:
if count({Removals.rpid},{Removals.r-ixservice}) <> 0 then
( sum ({#SIT - Count},{Removals.r-ixservice}) / count({Removals.rpid},{Removals.r-ixservice}) * 100)
else 0;
This works perfectly in that it spits out a % number based on the fields above. However, in the Report Footer I would like to average all the data generated by the above formula and spit it out so that if in the report this formula had been on 3 lines saying 90-80-70, then in the footer it would say 70.
I tried using Average({#Formulaname})but Crystal just says "This field cannot be summarized".
Thanks.
Its already a summarized formula so you can't summarize it again..suggested option would be use arrays and summarize.
Try this
Use the formula in group header and supress
Shared Numbervar array store;
if count({Removals.rpid},{Removals.r-ixservice}) <> 0 then
store:=store+( sum ({#SIT - Count},{Removals.r-ixservice}) / count({Removals.rpid},{Removals.r-ixservice}) * 100)
else store:=store+0;
1
Now in report footer
Shared Numbervar Array store;
Local Numbervar i;
Local numbervar final;
For i:=1 to Ubound(store) do
(
final:=final+store[i];
);
Final/Ubound(store);
I have created a crystal report which groups products based on order number.
I have created a formula which displays the text 'Partially Completed' or 'Fully Completed' based on whether a field on each product called 'Difference' equals 0 or not. If 'Difference' is 0 then 'Fully Completed' is displayed and vice-versa.
What I need to do is to display the corresponding message for the overall order number (i.e. if any of the products for an order have a difference != 0 then display 'Partially Completed'. If all the products have a difference == 0 for an order then display 'Fully Completed'.
This is the code I have attempted so far:
StringVar ouputText;
if {AD_999_SB_Fulfillment__Summary.FulfillmentPicking.Difference} = 0 then
ouputText := 'Full'
else
ouputText := 'Partial';
ouputText;
I assume I need some kind of for-loop to loop through all of the products for an order and check to see if any of the orders have a difference != 0 and then update the message based on if all the products have a difference == 0 or one of the products breaks the condition by having a difference != 0.
Looping is a lenghty process instead you group your report according to the "Order" then place the product in detail part. This will automatically loop entire products in a Order.
Create formula with name reset and place it in group header. Code is below.
Shared stringVar array y;
y:=" ";
join(y);
Create a formula and place it in detail section. This will take the result and store it in array for future use. Use below code.
StringVar ouputText;
Shared stringVar array y;
if {AD_999_SB_Fulfillment__Summary.FulfillmentPicking.Difference} = 0 then
y:= y+'Full'
else
y:= y+'Partial';
if {AD_999_SB_Fulfillment__Summary.FulfillmentPicking.Difference} = 0 then
ouputText := 'Full'
else
ouputText := 'Partial';
ouputText;
In group footer create another formula to display whether result is full or partial for order.
Shared stringVar array y;
if "Partial" in y
Then "partial"
else "Full";
I have a Crystal Report v 9.2.2 and I have three summaries at the end of each group; count of IEP students, count of non-IEP students, and total number of students. For an example, for one group (a class) I have 25 students. 4 Students are IEP, 21 are non-IEP. So I tried to create a formula to calculate the percentages, but the percents are wrong.
sum({#IEP}) % count({Mytable.student_id})
Manually, the math says 4 / 25 * 100 = 16, but when I use the formula above I get 11
I don't think it's a formatting problem.
Check reset value in "Create running Total Field" for the count.
Or
reset the count in the formula.
Your math is right, just do the same thing in the code/formula. The following works for a group based on {YourGroupField} and gives the percentage to one decimal point:
local numbervar IEPstudents := sum({#IEP},{YourGroupField}) //get number of IEP students in group
local numbervar TotalStudents := count({Mytable.student_id},{YourGroupField}) //get total students in group
local numbervar ThePercent := (IEPstudents / TotalStudents) * 100;
totext(ThePercent,1) + '%'
Alternatively, you can keep the formula numeric and add the percent symbol and formatting in the field's format editor.
Here is what I have. I have 15 unique formulas named Week1, Week2, ... Week15. I would like to be able to take a parameter name, MYCount, and use that to loop through the records and sum them. So if MyCount is equal to 3, the loop would sum Week1 + Week2 + Week3. I know how to create a loop, but I cannot figure out how to build the formula name dynamically. Here is what I have so far: (I am using Crystal Xi)
Whileprintingrecords;
local NumberVar i := {?MyCount}
For i := 1 To (MyCount-1) Do (
i = {#Week & "i"} + i
);
x
I think you may be over complicating. Why not just do:
Local numbervar x := 0;
If param > 0 then
X := x + week1;
If param > 1 then
X := x + week;
And so on...
X;
I don't exactly what you are trying to do, but you may want to consider another approach.
Create a formula that will segment a field based on a date field's week number:
//{#amount}
// adjust firstDayOfWeek and firstDayOfYear parameters to match your organization's
// definition of a week
If DatePart("ww", {table.dateField})<={?Week} Then
{table.amount}
Insert a summarized field on the formula field.
If you are using your #Weekn formula fields so that you can summarise by date across the page, then have you considered using Crystal's Crosstab functionality instead?