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!

Problem Remains for Linking Data to Child Table

Status
Not open for further replies.

Scott24x7

Programmer
Jul 12, 2001
2,826
JP
I have a form that I'm trying to get to work "interactively" with a parent form.
The difficulty I have is I use a template table structure, which creates another table with a unique name, so that in a multi user environment I don't have a collision.

The difficulty is, when I call the form (DO FORM CHILDFORM.SCX) I created that form using the template table fields, so the controls are bound to that form. In the controls, I have changed the control sources to <alias>.<fieldname>.

I found in the form the "BindControls" property, which I set to .F. and in the form INIT I open the Template, copy the structure to the table with unique name, and then alias the table name (which I thought I could then use in the control source).

The purpose of the form is to stage some data before continuing and when done, control will go back to the parent form, but I think everything will be "done" in this form before returning.

So, the problem I have is, is there a way to use the temporary table, which I have aliased as TEMPDBF to this form as the control source? And if so, what am I missing?
Thanks.


Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
I guess mostly because I'm not used to working with cursors... so not sure if it meets the need. How would it differ though? From a control source perspective wouldn't that really create the same thing? Just <cursorname>.field instead of <aliasname>.field?


Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Basically yes, but cursors are much easier to work with since you don't have to clean up when you don't need them anymore. As far as I understand your problem (which I don't...), you can pass the name of the cursor to the form, "(DO FORM CHILDFORM.SCX with lcYourCursorName". In Childform.init you add "lParameter tcCursorName" and will have access to the cursor that way.
 
If that works with a cursor, would it not work with a table?

Let me back up a bit though... the problem is, I get an error when trying to "bind" the fields to the form (from what I can tell).
What I've done so far was moved the Temp table creation now from the parent for to the child form's INIT this way I don't have to worry about which data environment is seeing the table. (As I understand, with Private data session set on, only the form can see it's own environment... from memory years ago, this was considered the "safe" way to manage tables and record pointers and the like, particularly when moving from form to form.)

So at first I was creating the temporary table before calling the child form, but now I moved those creations to the INIT of the form.

So the INIT now has:
Code:
* Setup Environment from template table, and create a working table for multi-user capability.
IF NOT USED("TTPARSEBC")
	SELECT 0
	USE TTPARSEBC
ELSE
	SELECT 0
	USE TTPARSEBC
ENDIF
*
lcTableName = "TEMP\"+ALLTRIM(SYS(2))+"TTPARSEBC" && using "Seconds since Midnight" + TTPARSEBC for temporoary file name
SELECT TTPARSEBC
COPY STRUCTURE TO &lcTableName
SELECT TTPARSEBC 
USE && releases the Template so that in multi-user environment, no conflict... this will all happen in sub-1 second
*
SELECT 0
USE &lcTableName ALIAS TEMPPARSE && Open the temprorary table under common alias
APPEND BLANK
*
ThisForm.BindControls = .T.

I use that as well, because there are other files that get created with the same filename, so the "cleanup" later is easy as I just macro-sub the name in with the file extension, in total there are 5 files that get created from the process, DBF, FTP, 2x JPG and 1 PDF. So cleaning and moving them all uses the same name, so a CURSOR wouldn't reduce my cleanup really.

BUT the moment I hit the "BIND" call I get an error telling me that "COMPANYNAME variable is not found", now the only mention of CompanyName in the form is in a field with the TEMPPARSE.COMPANYNAME as a control source. I've looked everywhere else, and as I mention the error occurs on that line.

My assumption was that, once I had the table aliased as the same name for the control source, that the fields would bind to the table, but apparently that's not correct... so I'm stumped, and not sure what the right way to proceed is. Been beating my head on this for 2 days now.

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Can you Suspend when that error occurs? If not, have you tried to step through your code until the errors occurs?

And by the way, you use macros (&) a lot. Macros are sloooow and can cause big problems if the variable contains space. Instead of "COPY STRUCTURE TO &lcTableName" you can use "COPY STRUCTURE TO (lcTableName)". Although I would use "Select * from TTPARSEBC into cursor (lcTableName) where .F." This means that ALL code the you provided can be replaced by these few lines:

[pre]
select * from TTPARSEBC into cursor curTemp where .F.
lcTableName = dbf('curTemp') && Which you actually don't use, you can just refer to curTemp
append blank && curTemp is already selected!
Thisform.BindControls = .T.
[/pre]

The only real difference between my code and yours, is that curTemp will have the wrong alias of curtemp.
 
Oh yeah, I seem to recall the debates between Macro Substitution and Name Substitution from years ago, and there are times when to use one and the other, but I honestly don't remember which is which. Since this isn't in a repetitive call, and machines today are literally 1,000 x faster than they were in 2002 I hadn't really worried much about which was better to use. This isn't in a loop, and when I was running tests earlier on just the code without populating it to a table, and adding 200 records at a time, it was still perceptibly "instant". But I appreciate the notion of revisiting the differences between the two substitution methods. I remember some "gotchas" for both though I don't remember the specifics of them.

I understand what your code is doing... the problem doesn't seem to be the creation of the table, rather the linking of that table to the fields on the form.
In stepping through the code, that is how I found that the ThisForm.BindControls = .T. is where the error occurs, it hits that line, and triggers immediately the "ON ERROR". The error itself is as I mentioned, "COMPANYNAME Variable" not found, and as I mentioned the only reference to that is in the txtCompanyName object which has it's control source set to TEMPPARSE.COMPANYNAME.

So my problem isn't creating or populating the temp table... that all happens (I've run other tests on that, the one I showed above is my current one). From what I see, the problem is that my form doesn't seem to recognize my aliased table as the source for data for the field objects that are on the form.

If I used your SELECT method, and created it INTO CURSOR TEMPPARSE it would be the same, but as I mention, data creation/population isn't the problem. (TTPARSEBC is an empty table anyway, it's just there for structure, as I mentioned, so that when I have multi-user, they each create their own "Temp" table which populates the various tables that are data tables in the system.) This form is just meant to stage the data, and allow the user to make sure it's all clean and ok before proceeding, because it's being brought in from an OCR result.

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
I suggest using GoFish and search for Companyname. Maybe you refer to it in a place you don't remember.
 
I've done that. Looked everywhere, and the fact that it reports that at the time of BindControls says it has to be there.

On another note, I just ran it using the template table as a test, using it as the control source (so no "change of source" table), and that works fine.

But my problem remains, that I can't use that table for a number of reasons, particularly in a multi-user environment. The data is temporary data, but I otherwise have to restrict its use to "one user at a time".

The core here remains... how do I change the control source for objects on a form that?

If I set it not to be initially bound at the form level, and I use an alias name for the control source property in the text boxes, then if I have "BindControls" set to .T. at the time the form loads, it blurbs back the name of every field saying something along the lines of "Table not found, unbinding <fieldname> from <txtObject>, and after you press "OK" on all the objects, then the form loads with blank fields, and no table associated with them. If I set BindControls to .F. and then load the temp table, and then try to set BindControls = .T. then I get errors (that trigger ON ERROR) with "variable name" not found.

So I'm at a loss, clearly it's the wrong approach but I don't understand how to get an ALIAS'd table to be used as the source for text objects on the form...

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
I'm sorry, but I can't provide more help. I don't use DE at all, and most of my data binding is class based. And also I don't use DBFs for data storage anymore, only SQL server.
 
Thanks. I've made it a "nudge" as I can see that it's an issue of getting the temporary table to be recognized as the data source for the controls, just not sure how to get it to do that. The rest of the interaction between the form is all working now. So I'm a step closer, just not there yet.

When I find the solution, I'll post it up here.

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Just a little tips on setting the data source. People try all kind of weird code to set variables to control sources, like "mycontrol.controlsource = &lcMytable..&lcMyfield" or some other hard to read code. One of the mostly misunderstood commands is Store. "Store lcMytable + '.' + lcMyfield to mycontrol.controlsource" does exactly the same, without any macro.
 
Never heard of it...
So if I understand this correctly, I could say, put in the form INIT:

STORE "TEMPDBF.COMPANYNAME" TO ThisForm.txtCompanyName.ControlSource

And then repeat that for each field on the table?
Just want to make sure I'm understanding the syntax right there...?

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Just our of curiosity, how is STORE in this case different to "assign":

ThisForm.txtObject.ControlSource = MyTable.MyField ?



Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
I tried to explain that Store makes macros redundant when using variables for objects, PEMs, tables and fields. This is a better example:
[pre]
&lcMycontrol..&lcControlsource = &lcMytable..&lcMyfield && Messy
Store lcMytable + '.' + lcMyfield to lcMycontrol +'.' + lcControlsource && Much cleaner
[/pre]
Especially when the object tree is "deep", like thiscontrol.parent.parent.ThisOtherControl.ThisOtherContainer.ThisObject.PropertyName and more than one element is a variable, macros can be a PITA.
 
It looks elegant, I like that.
I'll give it a test with my form and see what happens. There are about 20 fields on it, and since COMPANYNAME fails first every time, if I try this on that field, then I should get a "new fail" for the next field if this works.
Will revert, thanks.


Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
I tried:

STORE lcTable + '.' + lcCompanyField TO lcCompanyControl + '.' + lcControlSource

But before I can even leave the code window (INIT) VFP gives the error "Command contains unrecognized phrase/keyword".
I thought I was following your suggestion exactly?


Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Sorry, one lesson learned; never trust your memory! :) I forgot the parentheses, and you need Eval() to get the actual value. Try this:

[pre]Store Eval(lcTable + '.' + lcCompanyField) TO (lcCompanyControl + '.' + lcControlSource)[/pre]
 
AH... I see the point there, after the TO that is name substituting, while the first is EVALUATE()ing from what I understand another kind of substitution, though I don't understand why that's necessary with the STORE function, but maybe that will be clear later.

I'm trying this with the first field as I mentioned and will let you know if it worked (I'm very hopeful it does, it will be a big win to a not-obvious solution I've been chasing now...)


Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
It failed immediately on the STORE EVAL() call.

Here is the full code:
Code:
lcTableName = "TEMP\"+ALLTRIM(SYS(2))+"TTPARSEBC" && using "Seconds since Midnight" + TTPARSEBC for temporoary file name
SELECT TTPARSEBC
COPY STRUCTURE TO &lcTableName
SELECT TTPARSEBC 
USE && releases the Template so that in multi-user environment, no conflict... this will all happen in sub-1 second
*
SELECT 0
USE &lcTableName ALIAS TEMPPARSE && Open the temprorary table under common alias

lcTable = "TEMPPARSE"
lcCompanyField = "COMPANYNAME"
lcCompanyControl = "txtCompanyName"
lcControlSource = "ControlSource"
*
STORE EVALUATE(lcTable + '.' + lcCompanyField) TO (lcCompanyControl + '.' + lcControlSource)

This is in the form's INIT. The field has at the object level's control Source initially set to "TEMPPARSE.COMPANYNAME", and the form level the "BindObjects" property is set to .F. (I tried it both .T. as well, but same result).
Do I have something wrong in my assignments for the substitution values? Or is there some deeper issue still?


Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top