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

OOP Syntax problem 2

Status
Not open for further replies.

audiopro

Programmer
Apr 1, 2004
3,165
GB
I am tidying up some lengthy code but I can't fathom part of the syntax.
At the start of my code I assign a variable - VARB to a container.
I can set the properties of the container and any object within it.
Code:
	VARB="THISFORM.PAGEFRAME"+TRANSFORM(X)+".PAGE2.COL2"
	WITH &VARB
		.VISIBLE = .T.
		.S.ENABLED = .T.
	ENDWITH

I also need to set the value of a variable to the value of a field within the container.
The first line below is the working 'long hand' code but the second line errors - COL2W - is not an object.
How do I combine &VARB with the additional object reference?
Code:
*	COL2WID = THISFORM.PAGEFRAME1.PAGE2.COL2.W.VALUE
	COL2WID = &VARB.W.VALUE


Keith
 
It's &VARB..W.VALUE.

you can write &VARB in cases like WITH &VARB, but in cases like &VARB.W.VALUE. Why? Well, VFP needs to know, where the variable name for macrosubstitution ends. "It's obvious", you say. Stop. That's true, but only if you don't know that the first "." also can be the end delimiter for the variable name used in the macro substitution.

That's just little-known, as it's optional in almost all cases but the case you use it for substituting an object name or also &lcAlias.field is not working. Instead the dot is swallowed as end delimiter of the variable name and so the substitution results in THISFORM.PAGEFRAME1.PAGE2.COL2W.VALUE instead of THISFORM.PAGEFRAME1.PAGE2.COL2.W.VALUE

The dot as end delimiter is introduced to be able to do something like that:

that = "this"
&that.form

If the end delimiter would not exist you couldn't put together "this" from that variable with form hardcoded, because if youd instead write...

&thatform

...VFP would look for a variable named thatform, not for a variable named that to add to the rest "form". In other words The & operator does not parse the following text until it finds a variable, as in searaching for "t" - not found, "th" - not found, "tha" - not found, "that" - found, ah, take it. No. It parses for either the first dot or any other chracter not allowed in a variable name, eg space or return also ends the variable name the macrosubstitution & operator needs to knwo. So here that dot marks the end of the variable name to substitute and the begining of the rest of the code not substituted.

It's seldom necessary. I also stumbled upon this quite late.

Bye, Olaf.
 
Keith,

Olaf has given you the answer. I'll just add that in cases like this, I much prefer to use EVAL() rather than macro substitution - if only to avoid the "double dot" problem.

Something like this:

Code:
COL2WID = EVAL(VARB + ".W.VALUE")

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
In this case it's needed, so it's of course no problem.

In what way? Do you think about always using double dot? You shouldn't. You wouold always decide on a case by case basis. But if you contine with a dot after the variable name, as there needs to be a dot for further sub properties or objects, the double dot is the rule.

What you can always make a rule is to end macro substitution with a dot, eg also this works:
Code:
lcSQL = "Select * from Persons Where Name='Olaf'"
&lcSQL.
This doesn't add a dot after 'Olaf', but is just the end delimter. You can continue to not use the dot in this case thoug, it doesn't make your code quality better, if you adjust all macro subsitutions.

Just get used to the double dot when you need a dot in the final code after substitution. You could also put the dot into the string, eg what would work is

Code:
var = "_screen."
? &var.Caption

That doesn't look as awkward as ? &var..Caption with var = "_screen", but if you set var = "_screen." you can't do WITH &var anymore, as WITH _SCREEN. does error.

So there are pros and cons. If it's about objects I'd always choose the method using an object reference instead of macro substitution. If it's about &alias..field you can either instead USE (tcTable) IN 0 AGAIN ALIAS theTable and work with theTable.field or you select (tcTable) and then work with field names only.

In general you can avoid macro substitution in many cases anyway, and that's normally the best solution.

Bye, Olaf.
 
&lcSQL.

you can also see it this way: You also don't expect the & itself to remain after the lcSQL string is substituted. In the same way one single dot after the variable name is removed.

Like ? "text" does not print "text" with quotation marks, but only text. So the dot is a delimiter for the macrosubstitution variable name, it's just an optional delimiter, that's what's unknonw and what therefore makes it harder to cope with.

Bye, Olaf.
 
When I referred to the "double-dot problem", I really meant that by using EVAL() instead of macro substitution, it avoids the need to think about whether the string contains a dot, and whether you need to do anything about it. It's not really a problem. It's just something you have to think about.

In addition, EVAL() is more efficient that macro substitution. But, of course, it's not always possible to use it. It can only be used where the string evaluates to something, not where you are substituting an entire command, for example.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Note that the &macro termination operator is actually one of the oldest features in the language, dating back to at least dBase III.

It was originally documented as serving the purpose of using variables to refer to aliases:

Code:
lcAlias = "foo"
Replace &lcAlias..field with "something"
 
Hi Dan,

interesting. I'd do that as
Code:
lcAlias = "foo"
Replace field with "something" in (lcAlias)

Also, within SQL queries you can do

Code:
Select ... From (lcAlias) as Wahtever Where Whatever.field = "something"

You can avoid macro substitution very much anywhere, also with EVAL, Name expressions, PEMSTATUS, GETPEM.
And store is very helpful in conjunction with name expressions you can do

Code:
lcScreen = "_screen"
Store "VFP rocks AND rolls" to (lcScreen+".caption")

while you can't do

Code:
lcScreen = "_screen"
(lcScreen+".caption") = "VFP rocks AND rolls"

Bye, Olaf.
 
Olaf said:
I'd do that as
Code:
lcAlias = "foo"
Replace field with "something" in (lcAlias)

I would as well. But Dan said it originated in dBASE III, when we didn't have the IN clause (you youngsters don't know how lucky you are).

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Not only didn't we have the IN clause in dBase II, but we didn't have indirect references with parentheses.

FWIW, I agree with Mike. Much better to use EVAL() to get an object reference and then use the object reference throughout. In the case here, I'd do something like:

Code:
oCol = EVAL("THISFORM.PAGEFRAME"+TRANSFORM(X)+".PAGE2.COL2")
WITH oCol
...
ENDWITH

I think this is much more readable than the original code.

Tamar
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top