I'm trying to perform a very basic depreciation calculation based on the age of an asset using a For loop in Crystal 2008, and cannot get it working for the life of me.
The loop looks like this:
NumberVar AssetValue := {CIID.Currency4};
NumberVar DepreciationPercentage := {vw_DepreciationValues.Percent};
NumberVar AssetAge := DateDiff("yyyy",{CIID.Date4},CurrentDate);
Numbervar i := 0;
for i := 0 to AssetAge do
(
AssetValue = AssetValue - ((AssetValue/100)*DepreciationPercentage);
i = i + 1;
);
AssetValue;
For some reason, it always outputs AssetValue as the same number that went in....almost like it gets reset after being run.
I've tested the depreciation formula outside of the loop, and it works fine.
I've also verified that the i counter is getting incremented properly by the loop.
Anyone got a clue as to where I'm going wrong? I've even tried creating a custom function using private variables, but it made no difference.
Thanks in advance!
Typos:
AssetValue = AssetValue - ((AssetValue/100)*DepreciationPercentage);
^--- equality test
i = i + 1
^-- ditto
it should be := to do an assignment.
Related
I was trying to create a timed loop into an array but than I discovered something was not working right so I got back to a simpler example. Now I discovered that my loop skips all the time 1 index and places a value. So I get in index0, index1, index3 only values. I do not understand why this is happening, I'll show my code.
FOR vCount := 0 TO 9 DO
vVsample[vCount] := INT_TO_REAL(WORD_TO_INT(vVin));
vCount := vCount +1;
END_FOR
The result will be:
vVsample[0] = value vVin
vVsample[1] = did not change the value and is therefore 0
vVsample[2] = value vVin
vVsample[3] = did not change the value and is therefore 0
vVsample[4] = vVin
etc up to vCount = 10
I'm using Codesys V2.3 and tested this in simmulation mode
FOR loops already do increment the iterator, thus the vCount := vCount +1; line is the problem. Just remove it:
FOR vCount := 0 TO 9 DO
vVsample[vCount] := INT_TO_REAL(WORD_TO_INT(vVin));
END_FOR
Or change to a while loop:
vCount := 0;
WHILE vCount <> 10 DO
vVsample[vCount] := INT_TO_REAL(WORD_TO_INT(vVin));
vCount := vCount +1;
END_WHILE
I have found the answer by myself allready it is not needed to count up vCount by 1.
When doing this it will skip always one index of the array.
Silly mistake by me
I have records coming in to my report that contain fields "masterTypeId" and "amount". In my report footer I have an String field "#UnboundString30". The formula is:
(Local NumberVar r;
r := 0;
WhileReadingRecords;
if{Table.masterTypeId}=2
then r := r + {Table.amount})
The Formula Workshop will save and close. When I run the report #UnboundString30 is always 0 despite there being many masterTypeIds of 2 and many amounts. It appears to me that I need to tell my field that it should be the value of r but I don't know how to do that?
Thanks!
It looks like you are missing the return. Try to add on line, like this:
Local NumberVar r;
r := 0;
WhileReadingRecords;
if{Table.masterTypeId}=2
then r := r + {Table.amount};
r; //this is the return
whileprintingrecords;
Global numbervar var;
if (({USP_ExCombWeaponAmmunitionList;1.RegistrationNo}) =
previous({USP_ExCombWeaponAmmunitionList;1.RegistrationNo})) then
var := var
else
var := var+1;
Why above code skip first row sequence no blank and started from second row by sequence 1?
The formula silently "crashes" as there is no previous record before the first record.
One possibility is to foremost check if the current record is the first record by using OnFirstRecord.
In this case assign 1 to var.
whileprintingrecords;
Global numbervar var;
if OnFirstRecord then
var := 1
else if (({USP_ExCombWeaponAmmunitionList;1.RegistrationNo}) =
previous({USP_ExCombWeaponAmmunitionList;1.RegistrationNo})) then
var
else
var := var+1;
BTW one can write var instead of var := var, as this is just a unnecessary reassignment of the variable.
So i am working on report in crystal report and i have some problem
i have filed name opening that come from database
i have numberVar in the formula so
if on first record to sum numberVar =(opening +INqty - Outqty)
else numberVar +INqty - Outqty
and i want for every item
but what happen is when the information on the first item end it take the last sum of numberVar and sum to it the second item
this is my formlua :
numberVar BALQTY;
IF OnFirstRecord THEN
BALQTY := 0 ;
IF OnFirstRecord THEN
BALQTY := {stockCard;1.open1}+{stockCard;1.InQty}-{stockCard;1.outQty}
ELSE
BALQTY := BALQTY + {stockCard;1.InQty} -{stockCard;1.outQty} ;
any help plz
According to your explanation, looks like you need to run for every record separately and your variable is retaining the previous item value, this is because of incorrect variable declaration
You have declared the variable with Global scope instead create a variable with Local scope.
Change numberVar BALQTY; to Local numberVar BALQTY;
I am trying to perform a quick fix for a client. We have a report field that shows tolerance values in strings like +/-20 , -19 +18. This is in micrometer and the client wants it in millimeter. So i need to divide only the numeric part of this string by 1000 and display the result.
I am relatively new to crystal reports, with my limited knowledge and from searching this site for suggestions, i created a function with the following code lines,
Function (stringvar x)
local stringvar array input := split(x,"+/-");
val(input[ubound(input)])/1000
The above function works perfectly for tolerance values of +/-. However i am not able to figure out a way to do it for '-19 +18'. I would like to have the result as -0.019 +0.018
I can easily do it in the database source and send it to the report. However the client needs a quick fix of just the report. Any help would be greatly appreciated.
try this
if(Left (x, 3 )="+/-")
then ToNumber(split(x ,"+/-")[2])/100
else if(Left ({x , 1 )="+")
then ToNumber(split(x ,"+")[2])/100
else if(Left (x , 1 )="-")
then ToNumber(split(x ,"-")[2])/100
I figured out an answer which would work for this specific case.
I used the following conditions in a formula field. Based on the condition I called a User defined function 'Tolerance','Tolerance2', 'Tolerance3'.
Formula field:
IF (Left ({PDPRINTDATA.PD_T45}, 3 )="+/-") THEN
'+/-' + ToText(Tolerance({PDPRINTDATA.PD_T45}),3)
ELSE IF (Left ({PDPRINTDATA.PD_T45} , 1 )="-") THEN
'-' + ToText(Tolerance2({PDPRINTDATA.PD_T45}),3) + ' +' + ToText(Tolerance3({PDPRINTDATA.PD_T45}),3)
Tolerance:
Function (stringvar x)
local stringvar array input := split(x,"+/-");
val(input[ubound(input)])/1000;
Tolerance2:
Function (stringvar x) local stringvar mystr := x;
If NumericText (mystr[2 to 3]) Then
ToNumber(mystr[2 to 3])/1000
Else 0
Tolerance3:
Function (stringvar x)
local stringvar mystr := x;
If NumericText (mystr[7 to 8]) Then
ToNumber(mystr[7 to 8])/1000
Else
0
This solution works for me considering the fact that the string will always be of this format '+/-XX' or '-XX +YY'.