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

error creating variable name with loop

Status
Not open for further replies.

iara84

Systems Engineer
Oct 25, 2022
13
CO
I must repeat this code for customers1, customers2, customers3 and customers4. the names of the fields also vary TxtNomCli1, TxtNomCli2, TxtNomCli3 and TxtNomCli4.

LOCATE FOR id=1
IF FOUND()
thisform.TxtNomCli1.text="customers1.nombre"
thisform.TxtIdent1.text="customers1.identidfica"
thisform.TxtDirec1.text=""customers1.direccion""
thisform.TxtTele1.text="customers1.nombre"
ENDIF

I am trying to create a variable through a loop to avoid repeating the code four times. this works in other programming languages.

For x=1 TO 4
LOCATE FOR id=x
IF FOUND()
thisform.TxtNomCli+x.Value="customers+"x".nombre"
thisform.TxtIdent+x.Value="customers+"x".identidfica"
thisform.TxtDirec+x.Value=""customers+"x".direccion""
thisform.TxtTele+x.Value="customers+"x".nombre"
ENDIF
ENDFOR

but i get syntax error
 
thisform.TxtNomCli+x.Value="customers+"x".nombre"

No, that's never going to work. The syntax is entirely wrong.

A better solution would be to use the form's Controls collection to loop through the text boxes. Something like this:

Code:
FOR EACH loControl IN THISFORM.Controls
  IF LOWER(loControl.BaseClass) = "textbox"
    * This is a texbox
    loControl.Value = .... && store the value here
  ENDIF
ENDFOR

This is not meant to be working code. It's just to give you the general idea.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
iara84 said:
this works in other programming languages

As Mike already said
Mike Lewis said:
that's never going to work

Well, not as you used it. For example JS console (in a browser):
untyped_czrleg.png

If you have + inside of a string, it's just a "+" character, it's not the + operator for strings used as short notation for concatenation. Never, in no programming language.
Also not in other dynamically typed languages, where string concatenation does indeed often do implicit type conversions. But stillnot always. Not in VFP, for example.
I know you wanted to write "customer"+x. That's not the point, but you err in thinking there is a general rule of dynamically typed language to make all implicit type conversions. VFP is a mixture of strongly and dynamically typed. Operators like + are overloaded to support both mathematically adding numbers and concatenating strings, as it's in almost all programming languages, but VFP does not do implicit conversions from number to string, for example, in places you expect it. you have to live with the rule of the programming language you use, not what you wish for.

VFP has macro substitution, look up how that works. But you're still overall trying a route that's not a good solution and means more work than you need if you would stop insisting on doing things your way and instead ask or follow advice about how to do things the foxpro way.

Let me predict someone will come and argue that using macro substitution it will be easy to do as your wish to iterate your code four times and address all the different controls is possible. I am referring to the warning I gave you about using several groups of controls. That's perhaps HTML style of doing things, nobody needs to maintain HTML forms, they are generated with hell breaks loose ignorance of principles you'd do when designing and maintaining UI visually in winforms, like VFP does its UI.

The main point is, others will even encourage you to use macro substitution for your case, as it's a nice way to learn this feature/tool and make good use of it, while I will say "stop!". Just because some feature is nice and very FoxPro-specific, it's not automatically the best solution. You see from several threads you have now how many problems arise from you trying to use individual textboxes instead of a grid, which is meant to be used for a list of data. Always first find the right context of what to use for something and then dive into details. Your style of working out what to do is head over heels in that respect.

Sorry, it's normal to have beginner problems getting grips about concepts and failing to map your knowledge from other programming languages and platforms to something new. But then that's the reason you get interventions and advice from here. If you stick to something that just causes much more work and pain than simply following advice, then you never will see how simple things are, if you just use the right way, the right controls, for example.

Winforms never is HTML and vice versa. Try to understand the paradigms can't be mapped onto each other. What is good practice in one isn't in the other. One major difference: HTTP is stateless and you do a lot with your HTML+JS+backend programming to overcome this, even though this very disadvantage of HTTP is praised at the same time. In Winforms, also in VFP you have a stateful process you run that is all in one, client and business logic, only data is in files at a file server. It's head over heels and so you also work head over heels in VFP vs HMTL. In HTML the browse is mainly just the frontend visual representation, actions are done on the server side, if you don't bring it to the client side with the help of JS. You have a lot of communication between a client browser and the server, serve a lot of sessions all at once and may be sparse about only paging data. In VFP, on the other hand, there is little to do on the server side, the form has also the code to act on itself and the DBFs, you don't have a bottleneck here which you have in HTML. There still is the network that's the bottleneck for data, but that's not a reason for paging data in portions of 10 or 4 records. The grid actually is clever in only fetching as much data as it needs to fill its visible portion, it does not load all millions of records of a DBF just because a DBF has a million records. You don't even know how many things you get for free in VFP without programming a single line for it, just by using and combining the right things.

Chriss
 
One more thing spanning several of your threads. I don't get the overall plan you have in mind.

Your thread184-1819227 seemed to have no question but be a tip how to show one result record in a secondary grid.
Well, there I told you the easiest way to show one record in a grid is have a recordsource that also only has one record.
And as you keep the overall list, the first grid, binding to the same workarea isn't a solution as both grids then show all records and SET FILTER isn't a solution as it also again effects both grids, you really need two workareas for two grids, or you always have to handle more side effects than you can think of one step you do to get what you want in one grid without changing the first grid that causes the need for two steps which in short open a can of worms or the box of the Pandora.

Then from thread184-1819246 on and also in thread184-1819252 you show a self made "grid" that is supposed to show 4 records each with 4 columns in 16 textboxes? What makes you think this is working better than a simple grid. This is really the core job of a simple grid that shows all rows of a table. I ask you please to read my post from 27 Oct 22 10:13 in that thread on how you use a combination of grid and one set of 4 textboxes to get near to what you want with as little work and also - just by accident - with as least code as you could imagine needing for such complexity. In short you let the designer do it's best job in creating this form with just a few drag&drops and the grid do what it's designed for and the single textboxes, too.

Instead of reinventing wheels, look at what you're given. I do this for your best, I want to stop you going down a path to a corner of dead ends and lead you on the main path of how to make use of VFPs ID and controls.



Chriss
 
Just to show the result you would get from my advice (not tidied for good looks, just showing it works):

showcaseform_adetx5.png


In the left part you see what I got from dragging things from DataEnvironment to the form canvas. Grid and single textboxes.
On the right side what I also suggested work, the grid isn't recognizable, I removed header, record and deletemark and gridlines, used only 1 column that has a container in it with 2 textboxes and a button. And I even implemented toggling edit mode to only make one record editable at any time, though I don't see the use case for it. But you can individualize the grid look and have repeated set of controls you could also call subforms within a grid, one per record.

Here's the class browse view of the myrecord class defining the group of controls within the right grid
myrecordclassbrowser_fj5cse.png


And here's that container replacing the usual Text1 textbox control in column1 (the only column) of that grid:
containeringrid_pqlrej.png


How versatile the grid is was also once shown here in this blog article:

Why I show this? It's a design that repeats the myrecord container without repeating controls and needing all different names for them, which introduces the problem that you can't really recycle code as any code will need to first compute a controlname it wants to address. Even just using the container would help, even without a grid. But c'mon, use what you have. The grid is a list control, a repeater per record. Make use of that. In this form every record has Text1 and Text2 within the container within the grid. And that's actually only one set of controls, the grid just repeats them visually, it only has one set of controls. Just intelligent use of the grid and the column.sparse property.

Chriss
 
For x=1 TO 4
LOCATE FOR id=x
IF FOUND()
cx=LTRIM(STR(x))
mymacro="thisform.TxtNomCli"+cx+".Value=customers"+cx+".nombre"
&mymacro
mymacro="thisform.TxtIdent"+cx+".Value=customers"+cx+".identidfica"
&mymacro
mymacro="thisform.TxtDirec"+cx+".Value=customers"+cx+".direccion"
&mymacro
mymacro="thisform.TxtTele"+cx+".Value=customers"+cx+".TxtTele"
&mymacro
ENDIF
ENDFOR
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top