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!

Substitute memory variable for attribute 2

Status
Not open for further replies.

taterday

Programmer
Jan 28, 2009
183
US
I want to reproduce the object name in a do while loop.
this.parent.iimage1.value='ABCD'

iimage1
iimage2
iimage3
iimage4, etc


local iimage
add1=add1+1
iimage=alltrim(iimage)+alltrim(str(add1,1,0))

this.parent.iimage.value='ABCD'

I get an error object not found on iimage.
Are there a way to substitute a variable into the object name?

Thank you
 
Code:
iimage=alltrim(iimage)+alltrim(str(add1,1,0))
WITH EVALUATE("this.parent."+iimage)
     .value='ABCD'
ENDWITH

Borislav Borissov
VFP9 SP2, SQL Server 2000,2005 & 2008.
 
You can't really expect foxpro to know you mean to use the iimage variable value inside the expression this.parent.iimage.value. This is looking for a property or object literally called iimage. If you want to let foxpro use the value of the iimage variable, you know and have shown in other threads, that can for example be done by macro substitution.

So This.praent.&iimage.value would also work.

Borissov is giving the more performant solution, as Evaluate() is faster than the macro substitution operator &. Macro substitution means a compile of the line containing macro substiotution, while Evaluate just executes a muich simpler expression evaluation code in comparison with running a compiler.

Bye, Olaf.
 
Code:
this.parent.iimage.value='ABCD'

Should be:

Code:
this.parent.&iimage..value='ABCD'

The &iimage. is a separator to replace "iimage" with whatever iimage contains. The trailing . isn't always needed if it's obvious from context what it is.

As in:
Code:
LOCAL lcArrayName
lcArrayName = sys(2015)
DECLARE &lcArrayName.[1]

Which could also be written as:
Code:
DECLARE &lcArrayName[1]
without error.

The same is common to use for parent container objects which either have the "ControlCount" and "Controls" array, or another name. By setting a variable name to the thing which exists on the parent, you can always reference it logically:
Code:
loParent.&lcControlArray[lnIterator].Whatever

Hope this helps.

Best regards,
Rick C. Hodgin
 
I actually remember a session of Mike Feltman at Prague Devcon 2007 or 2008, about using Collections and Arrays of controls or control references to write less painful code addressing controls a bit similar but even more selective than via SetAll().

Googling I think the title of that session was "Collection Iteration and Arrays", eg a reference to that is found here [link fox.wikis.com/wc.dll?Wiki~PastEvents][/url], if you search for Array on that page.

Spot on for using the dot as end of macro substitution seperator before .value. It's needed here, true. Otherwise iimage="image1" substituted with this.parent.&iimage.value would for example substitute to this.parent.image1value instead of this.parent.image1.value

That dot is alsoe needed, if you do substitution of an alias name, ie &lcAlias..fieldname instead of &lcAlias.fieldname.

Bye, Olaf.
 
I could not get the

WITH EVALUATE("this.parent."+iimage)
.value='ABCD'
ENDWITH

to work, but I got the macro suggestion to work. I saw I needed another "." when the error display with the iimagevalue together. I am going to work on
the evaluate some more.

I appreciate all you guys suggestion. I click on the link and read some of the whitepages. Good reading.

Thank you again.

 
Very strange. If this.parent.&iimage. is working, then evaluate("this.parent."+iimage) will result in the same object reference. And evaluate also works with WITH..ENDWITH:

Code:
With Evaluate("_screen")
   .caption ="This is the screen"
Endwith
Does that change the screen caption for you?

Bye, Olaf.
 
Yes, that's what's to be expected. And it's what works here, too.

So if WITH is not failing in conjunction with EVALUATE(), then I don't know another reason why this won't work with Evaluate("this.parent."+iimage), besides a typo in the iimage value or executing in the wrong place (where this.parent is the wrong reference). But both errors would make macro substitution fail, so the only thing I could imagine failing is EVALUATE in conjunction with WITH. We both also know vfp has problems, if returning from within WITH ENDWITH, so there could be other bugs about it.

Bye, Olaf.
 
Personally, I'd use EVAL() to give me a reference and then use it without the WITH:

oObject = EVAL("This.Parent" + iimage)
oObject.Value = "ABCD"

Tamar
 
Hehe,

this just proves another time, that there are at least 3 ways to solve any problem in foxpro.

Bye, Olaf.
 
Code:
WITH this.parent.&iimage
also gives you an object.

I've never understood why so many people use EVAL() when it works otherwise, and through macro substitution is often times more revealing in the source code line about exactly what's happening.

What's the advantage?

I see from MSDN it warns:
1) EVALUATE() cannot be optimized by Rushmore Query Optimization.
2) Including the EVALUATE() function in the WHERE clause of a SQL query can return incorrect data.

Nice. :-(

But it also says:
"Whenever possible, use EVALUATE() or a name expression to replace macro substitution using the & Command. EVALUATE and name expressions execute faster than macro substitution."

I don't see this as a valid reason to use EVAL() for 99% of coding tasks. Depending on what you're coding, the speed differences will be of so little consequence (such as updating an image on a form) so as to be completely ignored as a reason to use it.

Best regards,
Rick C. Hodgin
 
I prefer storing an object reference using EVAL() because, often, when I need to refer to one property or method of such an object, I'll turn out to need multiple references.

I think it makes my code much more readable and maintainable.

Tamar
 
foxmulder,

To start with the most important acknowledgement: You're right, macro substitution is not much of a performance hit in this case, where this is done once to change an image control property.

I don't know from what context you come with your statements 1) and 2) about evaluate(). They both don't matter at all here, as the evaluate() is not evaluating sql at all her.

1) is also a very vacuous statement, as rushmore optimisation only is applied to SQL where and join clauses and for clauses of several commands anyway, so that statement can also be made about really any function or command, not only about EVALUATE(). Then you can also argue only anything related to SQL and tables is the usable, because only those parts of the language can be rushmore optimised.

And in regard to statement 2) that's not only true for EVALUATE(), also macro substitution and also any function call can lead to wrong results, if you do have an error in there, that's quite some nonsense to only apply that reasoning to EVALUTE().

There are two things, why it's better to avoid macro substitution wherever possible:

1. Any line containing any macrosubstitution is accepted by COMPILE or BUILD, even if it can't turn into a valid code line in no way, eg you can compile "Fdjkfhd&R", while no value of R can turn this into valid code at runtime. This is making macro substitution the most risky thing to do of all, as errors of it's usage will only show up at runtime, you don't detect many typos. Of course you will run and test your code, so such errors will show up early.

2. In perspective of migrating to other languages you better prefer generally available options instead of vfp specifics like macro substitution. There is of course a point where this is stupid, eg if it limits you in using the best option and forces you into unelegant code, which in turn runs slow and forces you to migrate. That would be self fullfilling prophecy of the worst kind.

That said, yes, macro substitution is especially nice within SQL to generate queries danymically. And the reulsting query can look much more elegant and in the end also run faster than a static query. Also that is one of VFPs advantages: In other languages SQL queries only exist as strings you send to your database, while in VFP it compiles as native part of the language.

And actually I never had a reson to use EVAL() in SQL, but macro substitution is useful there. The reasoning for that is that SQL only needs to be compiled once and actually compares to a loop through the records, if not even nested loops, so here it really pays to have one compilation for an overall best optimised query.

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top