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 gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

ERROR: Missing ) that is not missing 1

Status
Not open for further replies.

mmerlinn

Programmer
May 20, 2005
749
US


Does anyone know why the following code produces an error when run? It looks OK to me.

This code produces an error message in the highlighted line:

[tt]
= TORDER('IDLabel', 'Ilpartcode') && Open & order table
SEEK(zpartcode)
IF NOT FOUND()
= NOGO(LINE(), '', 'Data missing in IDLabel.DBF', '') && Wait window error message
USE
RETURN
ENDIF
z = 0
\<UL>
DO WHILE NOT EMPTY(qdata)
z = z + 1
zdata = ATXLEFT(qdata, CHR(1)) && Extract data from memo field
IF NOT EMPTY(zdata)
\<LI><<zdata>>
zfield = 'Il' + FORMAT(z) && Build field name
IF NOT EMPTY(&zfield)
[COLOR=black yellow]\\ (<<ALLTRIM(&zfield)>>)[/color]
ENDIF
ENDIF
qdata = ATXRIGHT(qdata, CHR(1)) && Discard data already used
ENDDO
\</UL>
USE
[/tt]

Error message is "missing )" and error number is 1300.

This code works perfectly:

[tt]
= TORDER('IDLabel', 'Ilpartcode') && Open & order table
SEEK(zpartcode)
IF NOT FOUND()
= NOGO(LINE(), '', 'Data missing in IDLabel.DBF', '') && Wait window error message
USE
RETURN
ENDIF
z = 0
\<UL>
DO WHILE NOT EMPTY(qdata)
z = z + 1
zdata = ATXLEFT(qdata, CHR(1)) && Extract data from memo field
IF NOT EMPTY(zdata)
\<LI><<zdata>>
zfield = 'Il' + FORMAT(z) && Build field name
IF NOT EMPTY(&zfield)
[COLOR=black yellow]zname = &zfield[/color]
[COLOR=black yellow]\\ (<<ALLTRIM(zname)>>)[/color]
ENDIF
ENDIF
qdata = ATXRIGHT(qdata, CHR(1)) && Discard data already used
ENDDO
\</UL>
USE
[/tt]

Is this a bug in FP2.6 or am I failing to see something?


mmerlinn

"Political correctness is the BADGE of a COWARD!"

 
Perhaps it has something to do with the content of field zname.
The results of Alltrim(zname) are put in the brackets and perhaps just because of that what is between the brackets is being evaluated. Try putting a space between ( and << and a space between >> and ).

Rob.
 


rob444

Those spaces result in extra unwanted spaces on resulting pages.

Contents of zname (and &zfield) are things like 'Pump Assembly', 'Top', etc.

Content between brackets is supposed to be evaluated then output.


mmerlinn

"Political correctness is the BADGE of a COWARD!"

 
I think it's just one of those errors where Fox doesn't report it correctly.
I'm guessing that when you use (<<ALLTRIM(&zfield)>>), ALLTRIM() is trying to trim the contents of &zfield, which at the time is evaluated as a field name, rather than the contents of the field.

There are a few times when the only way to do it is to store it to a variable first, as you have done in your second example.



-Dave Summers-
[cheers]
Even more Fox stuff at:
 


TamarGranor

When I originally got nailed by this error I tested EVAL(). Don't remember the problem, but I couldn't get it to work either.

However, I changed the ALLTRIM(&zfield) to ALLTRIM(EVAL(zfield))and it just worked fine. Don't know why I couldn't get it to work earlier.

Anyhow, I just modified my code to the following, and everything works correctly. The old code was evaluating the field name twice over 99% of the time. This new code evaluates it once all of the time. That is not much savings in resources for this job, but to me it seems to be better coding with only one evaluation and with one less line in the program.

[tt]
IF NOT EMPTY(zdata)
\<LI><<zdata>>
[COLOR=black yellow]zfield = EVAL('Il' + FORMAT(z))[/color] && Build field name and get field contents
[COLOR=black yellow]IF NOT EMPTY(zfield)[/color]
[COLOR=black yellow]\\ (<<ALLTRIM(zfield)>>)[/color]
ENDIF
ENDIF
[/tt]

In the past I have used macros rather than EVAL() because there are many times that EVAL() will not work while a macro would always work, or so I thought. And since speed is normally not an issue here, it was easier to deal with something that would 'always' work as opposed to two similar ways of doing the same thing, one of which works only sometimes. Since EVAL() seems to work faster, I guess I will begin using it where possible and use macros in those cases where EVAL() is not an option.


mmerlinn

"Political correctness is the BADGE of a COWARD!"

 
Simple rule of thumb:

1) Use a name expression (parens) wherever FoxPro expects a name. For example:

USE (cMyTable) ORDER (cMyOrder)

2) Use EVAL() where FoxPro expects an expression. For example:

STORE EVAL(cExpr) TO m.SomeVar

3) Use a macro when you're replacing neither a name nor an expression. For example:

SET TALK &cOldTalk

In general, name expressions are faster than EVAL() and EVAL() is faster than a macro.

There's one big exception. For a command that will be executed repeatedly, as in a FOR clause, use a macro rather than EVAL(), because the macro is evaluated once, but EVAL() is evaluated for each record. So:

BROWSE FOR &cExpr

is better than:

BROWSE FOR EVAL(cExpr)

unless cExpr is going to change somehow for each record.

Tamar
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top