Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Numerical computation in report.

Status
Not open for further replies.

Shane1961

Programmer
Oct 1, 2015
14
AU
Hello people.
Could someone please tell me why the 2nd line of code after the ELSE Statement
crashes. The code leads to a report where product and cost is in a list.
Many thanks. Shane.

NB: Seems like Chr(13) is a problem, but why?

Scan
If Eof()
Return
Endif
If Empty(_saleproducts) And _salecost=0
_saleproducts=Ltrim(Str(sales.units))+' '+Trim(sales.brand)+' '+Trim(sales.Description);
+' '+Trim(sales.Type)+' '+Trim(sales.Style)
_salecost=sales.cost
Else
_saleproducts=Alltrim(_saleproducts)+Chr(13)+Ltrim(Str(sales.units))+' '+Trim(sales.brand);
+' '+Trim(sales.Description)+' '+Trim(sales.Type)+' '+Trim(sales.Style)
_salecost=_salecost+Chr(13)+sales.cost && THIS CODE
Endif
Endscan
Endif
 
Couple of obvious things from here.

1) There seems to be an ENDIF lingering at the end

2) unless _salecost is initiated somewhere you can't add a chr(13)... to it, because it will have adopted the Boolean value of .f., but then that's not quite the end of it because
the first iteration of your SCAN loop will most likely set it to a numeric type, which also won't let you add a chr(13) to it (the IF EMPTY() line implies that it may already have a numeric value anyway
otherwise it might fail on that).

I have assumed that SALES.COST is a numeric...

So, perhaps, your code would look better like this?

Code:
** what is the scope of your _SALECOST and _SALEPRODUCTS variables?

_SALECOST = ""
_SALEPRODUCTS = ""
SELECT SALES
GO TOP
IF .NOT. EOF()
    SCAN
	IF EMPTY(_SALEPRODUCTS) .AND. EMPTY(_SALECOST)
		_SALEPRODUCTS=LTRIM(STR(SALES.UNITS))+' '+TRIM(SALES.BRAND)+' '+TRIM(SALES.DESCRIPTION) +' '+TRIM(SALES.TYPE)+' '+TRIM(SALES.STYLE)
		_SALECOST=STR(SALES.COST)
	ELSE
		_SALEPRODUCTS=ALLTRIM(_SALEPRODUCTS)+CHR(13)+LTRIM(STR(SALES.UNITS))+' '+TRIM(SALES.BRAND) +' '+TRIM(SALES.DESCRIPTION)+' '+TRIM(SALES.TYPE)+' '+TRIM(SALES.STYLE)
		_SALECOST=_SALECOST+CHR(13)+STR(SALES.COST) 
	ENDIF
    ENDSCAN
ENDIF

Little things that spring to mind:

I would probably test for the lack of records before the SCAN loop, and I don't like jumps out of loops
like that - a loop, subroutine, function or procedure should IMO only have one exit.

Also, for clarity I would select the SALES table/cursor before the SCAN loop so it was explicit rather than implicit
that was the table you are working with. Does the table have an order or index that needs specifying?


Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
In addition to Griff's good advice ....

I don't see any need for your EOF() test at all. The SCAN loop will never execute while the table is at eof, so the test is pointless.

More to the point, the most likely cause of the error is that you have not initialised _salecost - as Griff rightly says. If that's so, you would see a "variable not found" error at the point. The solution would be to place [tt]_salecost = ""[/tt] before the start of the SCAN loop.

Or, you might have initialised it to a numeric value (which seems plausible, given that it is a cost). You would then be trying add that numeric variable to a character string (the CHR(13)), which would give you a "data type mismatch" error. You can easily check for that by temporarily removing the CHR(13).

Either way, when posting problems of this kind, you really need to tell us what the error message is. Just saying that the code crashes isn't very helpful.

Mike



__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
You haven't come back and told us if the advice above has resolved your problem.

I'd guess that Griff's #1 observation above is likely the problem. In fact I'd guess that you couldn't get a successful Compile of the code with that in place.

Regardless, you might want to consider learning some debug techniques so that you could resolve issues like this yourself.

Put a new line of code in just above where your error occurs which will 'break' your code execution and allow you to debug each part of the string separately.
That 'break' can be with a Breakpoint or with a code line: SET STEP ON
I prefer the SET STEP ON because it will break execution and automatically open the TRACE Window so that parameters can be examined.
A Breakpoint will work similarly except, if the TRACE Window is not already open (I often forget to open it), it will be ignored.

Good Luck,
JRB-Bldr

 
JRB-BLDR said:
You haven't come back and told us if the advice above has resolved your problem.
My guess is this is a time zone thing, he posted just before midnight my time...

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
Hi GriffMG, MikeLewis & jrbbldr

My apologies for not stating the error message.

1. The error message reads 'Operator/operand type mismatch'
2. _salecost & _saleproducts are PUBLIC variables.
3. I changed _salecost from numeric to alpha.
4. Index Order = saleid
5. There are 2 records in 'sales'.

The updated code is below and it works, thank you to one & all.

Except, I have lost the numeric (currency & decimal place) format in the report.

Many thanks, Shane.

If _prnsale
Thisform.Hide

_saleproducts=''
_salecost=''

Select sales

Go Top

If Not Eof()
Scan
If Empty(_saleproducts) And empty(_salecost)
_saleproducts=Ltrim(Str(sales.units))+' '+Trim(sales.brand)+' '+Trim(sales.Description)+' '+;
Trim(sales.Type)+' '+Trim(sales.Style)

_salecost=Str(sales.cost)
Else
_saleproducts=Alltrim(_saleproducts)+Chr(13)+Ltrim(Str(sales.units))+' '+Trim(sales.brand)+' '+;
Trim(sales.Description)+' '+Trim(sales.Type)+' '+Trim(sales.Style)

_salecost=_salecost+Chr(13)+Str(sales.cost)
Endif
Endscan
Endif
Endif
 
Hi

Glad we could help.

The loss of currency etc. comes from my suggestion that you use STR(SALES.COST) to get your numeric value into a string format.
You could use TRANSFORM(SALES.COST,'$$$$.99') which would give you $12.34 or similar.

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
> I have lost the numeric (currency & decimal place) format in the report.
Well, you do [tt]Str(sales.cost)[/tt], look up the help topic or make a few experiments with ?-command in the command window.

If sales.cost is a currency field, [tt]Str(sales.cost)[/tt] converts it to the string of an int value, as you a) do not use the parameters for width and decimal places and b) STR disregards currency and the currency symbol anyway, it's working on numeric, int, float, currency and only regards the numeric part always and by default only converts to a 10 places string without decimal point and decimal places.

For any data type to string rather use TRANSFORM() than STR(), that acts "intelligent" and for example regards your SET DECIMALS setting, which defaults to 2, and your SET CURRENCY symbol and SET CURRENCY LEFT or RIGHT, too.

Bye, Olaf.
 
Transform works perfect.
Thank you so much GriffMG & OlafDoschke.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top