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!

Showing selected grid item to another form 2

Status
Not open for further replies.

SitesMasstec

Programmer
Sep 26, 2010
523
Brasil
Here I am again, not able to do this:

Grid2a_rtzf9g.jpg


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
 
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
 
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.

 

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
 
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.
 
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
 
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
 
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
 
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
 
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:
Grid8a_ae29nh.jpg


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
 
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.
 
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
 
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.

 
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
 
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.
 
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
 
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
 
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]
 
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.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top