INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Jobs

Showing selected grid item to another form

Showing selected grid item to another form

(OP)
Here I am again, not able to do this:



When I double click the desired item in the grid in child form (A), I want it to be displayed in the major form (B)




Thank you,
SitesMasstec

RE: Showing selected grid item to another form

It's hard to give you exact instructions, but the best bet is to pass a reference to the relevant control into the child form when you start it. You can store the reference in a property of the child form. Then, you can simply set that control's value in the appropriate method of the child form.

In the child form's Init, it would look something like:

CODE

LPARAMETERS oCodeControl

IF PCOUNT()>0 AND VARTYPE(m.oCodeControl) = 'O' AND NOT ISNULL(m.oCodeControl)
   ThisForm.oCodeControl = m.oCodeControl
ENDIF 

Then, in whatever method you run when the use chooses a record, you'd have something like this:

CODE

LOCAL cCode
cCode = YourTable.Codigo && or whatever is correct

IF NOT ISNULL(This.oCodeControl)
   This.oCodeControl.Value = m.cCode
   This.oCodeControl.Refresh()
ENDIF 

Tamar

RE: Showing selected grid item to another form

I also already hinted you on an easy way to let a child form influence something of its caller form: Let the child form be in that same datasession, because all you need to do is transfer data. It even won't matter, if you can open the same table and position in the same record, but it's easiest, if your child form simply uses the same datasession, then you already have that parent main table open and are positioned at the record you show.

Then all you need to do is set the field value of the table bound to B via

CODE

REPLACE fieldb with gridtable.fielda in maintable 
. That assumes the textbox you marked B is bound to maintable.fieldb, while the grid column is bound to gridtable.fielda. This is what you expect you need to do, isn't it? Is the form object really important? The textbox control? Its name? All you need to put in the right place is the data, in the right table in the right field of it, of course in the right record, too. But that should simply be the current active record, as it's displayed in the parent form.

Bye, Olaf.

RE: Showing selected grid item to another form

(OP)

Hello Tamar!
I put just this in the DblClick event in the Grid inside the child Form:

CODE -->

LOCAL cCode
cCode = itensest.wecodi 

IF NOT ISNULL(This)
  EsteCodigo=cCode 
ELSE
  EsteCodigo=0
ENDIF 
thisform.Release 

In the major Form, in the Text1 property I have:
Value: =EsteCodigo
so that in the line 'The chosen code from table is:' (Text1 value) allways appears the result of the former execution of the application.
For example: I double click code 1003 from the grid, in major window it shows a former choice.
Now I execute the program again, I double click code 8000 from the grid, in major window it shows 1003 (the former choice).


Olaf, in the real application I do not have a main table opened while in major window.

Thank you,
SitesMasstec

RE: Showing selected grid item to another form

You don't have your main form controls bound to a table?
Why not?

Then create one, form communication (transferring) is, of course, easiest via storing the data to transfer into a dbf. If this is nothing you need to store permanently, you can also create a cursor.

Bye, Olaf.

RE: Showing selected grid item to another form

You cannot assume that a variable will have the right scope. When you're working in an OOP world, variables are only useful within a single method.

Did you try what I suggested, passing a reference to the textbox to the child form when you call it, and then using that reference to set its value?

Tamar

RE: Showing selected grid item to another form

(OP)
Hello Tamar!

I declared in the main PRG program the variable EsteCodigo as Public (PUBLIC EsteCodigo).

And, from your solution, when I select a row in the grid it passes the value to a TextBox in the major Form. It is working perfectly well. Thanks again.



Thank you,
SitesMasstec

RE: Showing selected grid item to another form

DON'T EVER USE PUBLIC VARIABLES! (and yes, I'm shouting)

Among the reasons not to is that if you have two instances of the form open, they're going to step on each other. But there are plenty of other reasons.

You don't need a public variable here. Please try what I suggested. Getting it working will be another step on the road to being comfortable with OOP.

Tamar

RE: Showing selected grid item to another form

(OP)
Hello Tamar!

If I do not declare a variable as PUBLIC how do I will pass the code chosen from the Child form to the Parent form? Using LParameters?


Thank you,
SitesMasstec

RE: Showing selected grid item to another form

(OP)
Dear colleagues:

I have searched in many VFP books and VFP9 Help but I have not found how to do this successfully WITHOUT using PUBLIC variables. Using PUBLIC variables the forms are performing very well but, as advised by Tamar, I should not use PUBLIC variables in Forms.

When I execute the Parent Form it immediately opens the Child Form, in order for the user to select an item, but DO NOT return the nCodi and cNome into their textboxes in the Parent Form, as desired!


These are the Forms:


In the Parent Form I have:

In Form1, Init:

CODE

LOCAL nCodi, cNome 

in TextBox nCodi, GotFocus:

CODE

nCodi=0
cNome=""

DO FORM ITENSCAO2 WITH nCodi, cNome

This.Value = nCodi
Thisform.txtNome.Value = cNome

This.Refresh() 


In the Child Form I have the properties:
RecordSource = itensest (a table)
RecordSourceType = 1-Alias

Form1, Init:

CODE

PARAMETERS oCodi, oNome 

Form1, KeyPress:

CODE

LPARAMETERS nKeyCode, nShiftAltCtrl

IF nKeyCode=13 AND nShiftAltCtrl=0 
	oCodi=itensest.wecodi 
	oNome=itensest.wenome
	thisform.Release
ENDIF

IF ISALPHA(CHR(nKeyCode))
  SELECT ITENSEST
  LOCATE FOR UPPER(LEFT(WENOME, 1)) = UPPER(CHR(nKeyCode))
ENDIF 


Thank you,
SitesMasstec

RE: Showing selected grid item to another form

Again, use the same datasession and a cursor and you have an "object" ypou share on both forms without need to pass anything in or out. You should have already learned that from my previous answers.

Bye, Olaf.

RE: Showing selected grid item to another form

(OP)
Hi Olaf!

I haven't yet understood your 24 May post (I hope I can lean about it soon). For now, I would like to have the mechanics of passing data to work, it cannot stand as a mistery to me this single piece of VFP.

The Parent Form calls the Child Form, I select an item, the Child form closes (as expected) and the Parent form is displayed , but with 0(zero) in txtnCodi and blank space in txtcNome textboxes. These textboxes should display the Code and the Name (first 2 fields) from the selected row in the Child form.

It seems to be a small detail (parameter names?) ... well,as said by someone, "The Devil is in the details"...lol

Thank you,
SitesMasstec

RE: Showing selected grid item to another form

I already answered this question. Look at my message from May 24.

Tamar

RE: Showing selected grid item to another form

You can't work with the PARAMETERS oCodi, oNome you passed in, they vanish after form.init finishes and are not available in Keypress. Now if you would be able to store oCodi, oNome somewhere these values are existing until the child form exits, these values would still not come back to the parent form.

But if you simply create a cursor in the parent form, bind two of it's fields to the txtCode and txtNome, then start the child form in the same datasession simply by letting child form.datasession be 1, then you can simply set the cursor fields to the values you want to be displayed in the parent form in the keypress of the child form.

Bye, Olaf.

RE: Showing selected grid item to another form

(OP)
Ok Olaf, but it seems it is possible to work with PARAMETERS (as it is part of VFP language). I truly believe you are sure and I expect soon understand your solution. But now I need to undertand the mechanics of PARAMETERS inside VFP (its like I need to know how to drive a car before flying an helicopter).

I am missing anything in PARAMETERS, maybe I have to use other variable instead of oCodi and oNome.

Tamar, I read again your 24 May post. Where should I write the code you suggested?
Your code:

CODE

LOCAL cCode
cCode = YourTable.Codigo && or whatever is correct

IF NOT ISNULL(This.oCodeControl)
   This.oCodeControl.Value = m.cCode
   This.oCodeControl.Refresh()
ENDIF 

Thank you,
SitesMasstec

RE: Showing selected grid item to another form

PARAMETERS are good for passing in things you only need to know at init. To make them permanent form values, you'd need to store them in form properties. So you'd first define form properties and then set them with the passed in values. But even if you do so, that's a one way ticket. You can't use parameters of init to also output things, that's only possible in a function when you pass in parameters by reference with a @ in front, but it doesn't help you at all, because a form is not like a function. It has a lifetime span and only finishes sometimes later.

So you have to think about what exists in the lifetime of both the parent and the child form, and that is - can be - the datasession. Any further thought about parameters is just fruitless.

Bye, Olaf.

RE: Showing selected grid item to another form

As the May 24 post said, that code goes in whatever method runs when the user makes the selection, so probably a Click or DoubleClick method.

Tamar

RE: Showing selected grid item to another form

(OP)
Well Tamar, I posted on May 31st the complete code with screen pictures. If anyone can say what s wrong with those code.

As Olaf had told in the same day, I undestood that a parent form cannot call a child form and get a value from it, when child form closes and return to the parent form.

I am trying to get on this train, I cannot loose it...

Thank you,
SitesMasstec

RE: Showing selected grid item to another form

SitesMastec,
Is your child form Modal, or can you tolerate it being modal?
If you can then you can use the TO clause with DO FORM. You can pass parameters to the child form, and then get a return value IF you can tolerate that form being modal. If you need more than one value, there's ways to do that, but it's a little messy.

So from your parent form (I assume you click a button) in the CLICK event:

DO FORM <ChildForm> With <Parameters if you want to pass them... param1, param2, param3> TO lRetValue

In the child form, if you pass parameters, then you need in the INIT:

CODE

LPARAMETER <param1>, <param2>, <param3>...etc.
ADDPROPERTY(This,"lRetVal") && Used to hold a return value to the calling form
*
This.lRetVal = 0 
That will add a property called lRetVal to store whatever value you are returning as a property of the form.

In your child form's UNLOAD event:

RETURN ThisForm.lRetVal

This value gets passed back to the calling form, and now lRetValue in that form that called it, has the value.

But for this to work with the TO clause, the child form must be modal. Not the end of the universe, you just can't click outside it to make it go away. But you can manage that in other ways...

Best Regards,
Scott
MIET, MASHRAE, CDCP, CDCS, CDCE, CTDC, CTIA, ATS

"Everything should be made as simple as possible, and no simpler."hammer

RE: Showing selected grid item to another form

Yes, modal forms can return from their unload event, but only one value. And for the price of restricting the user to the modal form. You can't even use a menu in that case.
Modal forms in themselves are to be avoided in an application, which aims to be for power users doing multiple things in parallel.

I don't get why you refuse to apply my solution, SitesMasstex.

It's only a few steps and you neither need to pass in something to the child form nor return something.

You create a cursor with the necessary fields in the parent form: CREATE CURSOR cursorname (field1 fieldtype1, field2 fieldtype2)
You set the child form to work in the same datasession as the parent form, by setting its DataSession=1

Now you share this cursor in both forms. This means you can
a) display cursorname.field1 and field2 in parent form controls (setting the controls controlsource)
b) Change field1 and field2 values in the child form (with a REPLACE in the cursorname)

The change of the data will get displayed, there is no passing in nor passing back.

It does not even need advanced complex complicated to understand passing of object references. It's totally easy to understand. I don't get why you don't get it. It is even simpler than passing parameters and doing the replace in the parent form, you save all the lines of code concerned with passing in values, storing them, changing them and passing them back so the parent form can receive tham and then do a replace. It's simply the child doing the replace. I don't get why you absolutely insist on doing something more complicated. It's just a shared datasession, there's no magic about that.

Bye, Olaf.

RE: Showing selected grid item to another form

(OP)
Hello dear colleagues!

Quote (Olaf)


I don't get why you absolutely insist on doing something more complicated.

Olaf, of course I prefer simpler solutions, like the one you explained. Problem is I had not understood it, this is the reason why I had not adopted it befone.

Now after reading your today post, it is clearer to me: I understood that a Cursor can be shared by parent and child forms, is it right? I understood also that I can get back only one value from a child form using PARAMETERS (well, I was going to add the two fields in the child and back in the parent decompound it in the 2 fields). I will try your solution. Thank you.

I beg you pardon, Olaf, Tamar, Mike, Scott and other people trying to help me, for my slow VFP learning.


Thank you,
SitesMasstec

RE: Showing selected grid item to another form

Don't apologize for needing time to learn. I think all of us experienced the move from procedural to OOP as a series of frustrations followed by "aha!" moments.

Tamar

RE: Showing selected grid item to another form

(OP)
In the Grid (from my Child Form), DblClick event I have:

CODE

* Codigo Escolhido
oCodi=itensest.wecodi 
oNome=itensest.wenome


CREATE CURSOR SELECAO1 (CODI1 N(6,0), NOME1 C(10))
APPEND BLANK
REPLACE CODI1 WITH oCodi
REPLACE NOME1 WITH oNome

thisform.Release 

If this the right way to put the selected record into cursor SELECAO1 ?

or this way?:

CODE

* Codigo Escolhido
oCodi=itensest.wecodi 
oNome=itensest.wenome


CREATE CURSOR SELECAO1 (CODI1 N(6,0), NOME1 C(10))
INSERT INTO SELECAO1 (CODI1, NOME1) VALUES oCodi, oNome

thisform.Release 


Thank you,
SitesMasstec

RE: Showing selected grid item to another form

SitesMasstec,
We can see you are trying hard, so that's what matters. I'm still making the transition to a more complete usage of OOP too, and it's not intuitive. It can be really tiresome sometimes, but step by step, it gets better.
Regarding your question, both work. Some prefer one way others prefer the more SQL style of your second example. It has the benefit of being fewer lines, and does both the insert and replace in one call. But nether are right or wrong.

Best Regards,
Scott
MIET, MASHRAE, CDCP, CDCS, CDCE, CTDC, CTIA, ATS

"Everything should be made as simple as possible, and no simpler."hammer

RE: Showing selected grid item to another form

SitesMasstec, no, you don't generate the cursor in the child form, you already create this in the init or even in the load of the parent form, so the cursor is already there. The keypress then only needs to set the field of the current record. I already posted the code you need in your other thread184-1777707: Selecting a row in a Grid with the enter key.

It's exactly the same solution, that can be applied here, too.

Repeated:

CODE --> Init/Load

SELECT * FROM itensest WHERE .F. INTO CURSOR crsMainform READWRITE
APPEND BLANK IN crsMainform 

CODE --> Keypress

LPARAMETERS nKeyCode, nShiftAltCtrl
IF nKeyCode=13 AND nShiftAltCtrl=0
   REPLACE wecodi WITH itensest.wecodi IN crsMainform
   Thisform.Release()
ENDIF 

You just need to change what table to copy fields from (you may not need a copy of itensest.dbf this time) and what field to set (this most probably isn't the wecodi field this time).

It's depressing to me that you take a solution and forget about it the next instance and ask the same question again, not just month later, but at the next moment. This is exactly the same problem you already had and so the same solution applies. You just need to identify the "moving parts", the things that need to be individually changed. And what else is that but the involved tables and fields?

Bye, Olaf.

RE: Showing selected grid item to another form

(OP)
Hello Olaf!

Now I have it working, at last!

For practical purposes in my application, I wrote the code bellow in
txtCodi Textbox, Got Focus on the Parent form (instead of using a Click button)

CODE

DO FORM ITENSCAO3    && calls the Child form

thisform.txtCodi.ControlSource="crsMainform.WECODI"
thisform.txtNome.ControlSource="crsMainform.WENOME"

Thisform.Refresh 


As I executed the Parent form, and selected one item (a row) in the Child form (ITENSCAO3.SCX) I noticed that the file ITENSEST.DBF is opened in area 1.
Well, in the Parent form, Destroy event, I put the code:

CODE

USE IN SELECT("ITENSEST") 

As I have some files in my application, and all of them have a defined area (I am going to step by step change them all.
to open:

CODE -->

USE anyfile in 0 

and to close:

CODE

USE IN SELECT ("anyfile") 

Let's suppose that a file has its area automaticaly opened in area 1 (when using 'USE anyfile in 0').
If in the same form I have a hard command SELECT 1... USE anotherfile, which I haven't changed yet, there will be error.
So I have to change the entire application to 'USE anyfile in 0' instead of 'SELECT (number)... USE anyfile'

While I do not change the commands in the application AT ONCE, I need to define a select area number for ITENSEST.DBF, to avoid error, used in:
SELECT * FROM itensest WHERE .F. INTO CURSOR crsMainform READWRITE

I have not found in the full syntax for the command SELECT a way to define an area number before the command above. Is there a way to (for temporary use) define area number of a file to be opened?

Thank you,
SitesMasstec

RE: Showing selected grid item to another form

No, there is no way to determine in which workarea number a cursor will be created. That's one of the reasons working with fixed workarea numbers is so bad.
Also see thread184-1777495: 'Select area' of a table in Grid. This exactly was already said there. Are you reading us?

Quote (myself)

Think alone about this: SQL-SELECT INTO CURSOR (Select Areas 20-29 in your world) does not allow specifying a workarea number, only alias names.

The best thing you can do is create this cursor last in the initialisation process of the parent form. A temporary solution would be query INTO TABLE instead, generating a DBF file, then open that in a specific workarea number. But you loose performance.

Or you open anything in all the workarea numbers you need as fixed numbers, so the SQL-Select must use a higher workarea.

You could initialize your datasession this way:

CODE

CREATE CURSOR crsEmpty (cDummy C(1))
LOCAL lnWorkarea
FOR lnWorkarea = 1 TO 20
    IF EMPTY(ALIAS(lnWorkarea))
       USE DBF("crsEmpty") IN (lnWorkarea) AGAIN ALIAS (SYS(2015))
    ENDIF
ENDFOR   
SET 
This occupies all workareas 1-20 with the same crsEmpty cursor and every further cursor thus must be generated in a higher workarea number. Also, it leaves any workarea as is, that has something opened in it already.

Everywhere you SELECT N and USE sometable the cursor in that workarea vanishes.

Bye, Olaf.


RE: Showing selected grid item to another form

That hack to occupy all workareas is working, even if you first close the original cursor crsEmpty before closing all the other workareas/aliases of that cursor. Just notice this is not the thing you want to have and do just to be able to stay with your fixed workarea numbers. You can't make use of many advanced FoxPro features like referential integrity triggers also using arbitrary workarea numbers, if only temporary. the only way to reserve workareas is by always using them, but that makes it harder to debug something watching at a cluttered datasession window.

So changing all code to use fixed alias names instead of fixed workarea numbers has to remain your first priority to get going.

What you need to do here is paying what we call a technical debt. You kept things as they are instead of regularly refactoring and modernizing code. You have to take advantage of new features. Staying with old ways just becomes a barrier sooner or later and then this technical debt has interest and compound interest and is more work than a regular upgrading would have cost you. This is like leaving your home in a mess and only clean up once in decades. Of course, you'll find trash and mold once you begin tidying.

Bye, Olaf.

RE: Showing selected grid item to another form

(OP)

Hello Olaf!

Believe me: I am reading every post, and sometimes more than twice.

Besides the VFP 9 Help, I have a collection of books about VFP (including Hentezenweke's "The Fundamentals" for VFP 6, "Megafox", etc). But working with a language with such a large amount of commands and objects and their events, sometimes it's hard to find the best solution and sometimes getting caught using bad code (as Tamar alerted me about public variables). And because of the "technical debt", of course.

It was a surprise because I have been using public variable for more than 10 years and I have not received complaints from users of my applications (please note that I am not saying Tamar and others are wrong; indeed I have a book by Tamar)

I am going to change my code in order to apply the advices I have been learned in this forum. Thank you.

Thank you,
SitesMasstec

RE: Showing selected grid item to another form

I have an application that have been running in many places since 1996.
There are some public declarations in the beginning of the main program, but I will not change anything just for the sake of it. "If it ain't broke..."

RE: Showing selected grid item to another form

(OP)
Drdloittle, thanks for sharing your experience about public declarations. But of course, from now on I will avoid using them, and I am going to change my older applications. Maybe we have been lucky until now, but Murphy's Law may be applied soon...

Thank you,
SitesMasstec

RE: Showing selected grid item to another form

I would actually say a working application is a proof in time. It's bad for maintenance and extensibility, but I wouldn't go as far and change any old applications, too. That would rather be like redrawing your childhood pictures because nowadays you can draw better. Concentrate on recent work you still maintain and extend.

In this case here, once you get to the bottom of it, it is the nicest and easiest solution not even needing passing forth and back parameters, just acting on the shared workarea. Also you get something you can apply in many cases.

And if you like every form to have a private datasession, you still can share data, you do it all the time, if two forms act on the same DBF, so you could also define a permanent DBF instead of a cursor as your shared data source. That means acting on two separate datasessions. Openening tables then remains just to be done by the forms data environment, etc. Cursor are just more compatible with local and current user session only usage without overlap and problems of multi user use of such a DBF. But in the end it shows you how far it is into your all day usage of VFP as a database application language. This time you just bind two forms to the same cursor instead of the same table.

Bye, Olaf.

RE: Showing selected grid item to another form

(OP)

Revisiting "passing parameters", I have tried to understand this:

In Parent Form, txtCodi Textbox, GotFocus:

CODE

DO FORM ITENSCAO5 TO lRetVal 

thisform.txtCodi=VAL(SUBSTR(lRetVal,1,6))
thisform.txtNome=SUBSTR(lRetVal,7,40)

Thisform.Refresh 

In the Child form, Init:

CODE

LPARAMETER codinome
ADDPROPERTY(This,"lRetVal") && Used to hold a return value to the calling form
*
This.lRetVal = 0 

Child Form, Grid1. DblClick:

CODE

* Chosen code
lRetVal=STR(itensest.wecodi,6)+itensest.wenome
thisform.Release 


Child Form, Unload:

CODE

RETURN thisform.lRetVal 

I want to get the lRetVal in the Parent Form. I tested and see that lRetVal has a value while in the Child Form, but Child form does not pass the result to Parent form!




Thank you,
SitesMasstec

RE: Showing selected grid item to another form

Is child form modal? You can only return values from modal forms.

Tamar

RE: Showing selected grid item to another form

Why again? Why go for this outdated and unnecessary concept? It's not fine, it's just stupid.

This is unnecessary code.

You want a form to act like a function. Passing in some parameters, getting back a value.

You are choosing VFP because it is a database oriented language and you want to work in it like it is some BASIC code. You can share what you always share in Foxpro Forms: data. This is the core concept of VFP, to share data. And you still rather want to copy data to variables pass them in, stores them in properties, return them and then finally store them back to the table it came from, now changed. Or similar.

How many more steps to do just to share data? This is something you don't want to learn or be capable to do, this doesn't bring you forward at all.

Bye, Olaf.

RE: Showing selected grid item to another form

(OP)

Yes Tamar, the child form and the parent form are both 1-Modal.

Olaf, the data I wish to get from the child form will not be used in another table, it is just for displaying it in the parent form.

With your valuable help I applied the use of cursor in the aplication I am currently working. About passing & get data between forms, I just want to test it in order to learn how to pass data to a child form and get result back in the parent form, without the use of cursor/table or global variable (Tamar advice is still echoing in my ears...lol). Maybe in the future I will need it, without involving any cursor.

Thank you,
SitesMasstec

RE: Showing selected grid item to another form

>Olaf, the data I wish to get from the child form will not be used in another table, it is just for displaying it in the parent form.

I already said the same thing here, too: Even when you don't want to store data persistent, you can CREATE a CURSOR. CURSORs are just the kind of temporary DBFs ideal for that case.
You can't share a variable with two forms, but you can share a DBF or CURSOR (which also is nothing else but a DBF). Okay?
You can also bind form controls to a cursor, so that makes it the perfect match without all the ado of creating variables, passing them forth and back.

Bye, Olaf.

RE: Showing selected grid item to another form

(OP)

Ok, Olaf, I thought it would be more "natural" to get data through parameters when not using the result in another table, but just for displaying. So if I "can't share a variable with two forms" I will forget it.thanks

Thank you,
SitesMasstec

RE: Showing selected grid item to another form

As said the natural way to share things is a table.

If you have time for the whole background:
There is the topic of passing parameters by value vs by reference, eg:

CODE --> value

* Passing by value
LOCAL lnNumber
lnNumber = 1
lnNumber = Increment(lnNumber)
? lnNumber && prints 2

Function Increment(tnNumber)
Return tnNumber+1 

CODE --> referencee

* Passing by reference
LOCAL lnNumber
lnNumber = 1
Increment(@lnNumber)
? lnNumber && prints 2

Procedure Increment(tnNumber)
tnNumber = tnNumber+1 

The @ extends the scope of the variable to the called procedure, though the procedure still has it's own name tnNumber (notice the t instead of l) for the variable in its code. It's not the procedure but the caller deciding with the @, what memory variable the called procedure acts on with its internal variable name tnNumber.

That works universally, but a form isn't a function or procedure with visual interaction, so if you add @ to your parameters what happens is only the first INIT event of the form with its LParamerters line would act on the passed-in variable by referencing the same memory. The rest of the form - and that is important to you - doesn't know about the init parameters of the form. The form parameter are there to influence the form state or behavior at its beginning, not to act as two-way in and out parameters.

So to act on the passed in values, no matter of you pass them in by reference or value, you need to copy their value to something persisting in the whole life scope of the form. And yes, you can pass something back, to yet another variable the caller specifies in its call as TO clause, TO lcTargetVariable. But that's only possible with modal forms, which in itself is a limitation I would not like, even though it makes the user focus on this current workflow step of picking something. And in that case, as the RETURN something goes back into another variable, you don't have that shareed variable thing at all, unless the init would already give you the feedback you want, but that would never be the intention of the form - to have a result before it is even shown.

You argue from the point of view a variable is the best thing to store a single value, but due to the limitations of passing by reference you're bound to copy your values around multiple time:
1. copy the variable value from the caller to the form init parameter
2. copy the init parameter to a form.property or anything else persistent in the lifetime of the form
3. copy that property or any form element value as return value in the Unload event
4. copy from the target variable back into the original caller variable you wanted it to be, or even copy it somewhere else, into a table field.

And besides this copying, you also have at least 3 names for the same thing, the caller variable, the init parameter name and the child form property or control name.

Using a cursor in the shared datasession, the value we talk about always is in one field of one record of that cursor, referenced by the one single name this has. The value never travels anywhere, it never needs to be copied. Though it takes only split seconds to copy even large values in memory, is it really more natural to do so instead of simply sharing a cursor?

The cursor also allows you to share as many as 254 fields in one record and you can have multiple records, too. Parameters are limited to 27. And Unload only returns 1 value.

There is one more thing you can do also without the @, you can pass objects or variables that refer to objects. Both just means passing the object reference, there is no passing of objects by value, so they don't get copied. Not, that the act of copying is the bad thing, but that has the advantage you act on the original. But you need the same steps as with variable, you need to store the passed object reference to a child-form property, etc. You don't need the RETURN in the Unload, as you can simply act on object properties and thereby let a picked choice come back to the parent also still knowing that same object, but it still is not as easy as sharing data, what a database system is made for, is it?

Bye, Olaf.

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members!

Resources

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close