Wiki Home

Vfe PCHelper


Namespace: DotNet
Here are two hacks to help the Visual FoxExpress Parent Child Presentation Object wizard.

1. init() of step 2 (Select Child Presentation Objects), select all of the PO's that are probably child records of the Parent PO picked in step 1.
ver 1.0 beta [08/01/99 08:01:58 AM GMT]

2. populatechildlist() of step 3 (Set Parent to Child Relationships), set the Parent Key Field, Child Key Field, and Child Index Tag of the Child PO's selected in step 2. It is now 1:20, and I just noticed the first problem: if you select different fields and keys, then go back to step 2, then forward to step 3 without changing anything, it wacks your settings in favor of the ones based on relations. Not very friendly.
ver 1.0 beta [08/01/99 08:01:58 AM GMT] -- Two weeks later, and I havn't found any problems.

One more to help the "Parent and Child Form" wizard
3. cntparentchildformrelation::init() of Step 5 "Set Parent to Child Relationship", sets the parent and child stuff, just like 2.


To ease my development of these, I duplicated some code a few (6) times. The second copy begins with *(here we go again....) It finds the primary cursor of a PO. Perhaps it should be a method of cWizUtils. Perhaps it already is... There is great similarity between populate_child_list and cntparentchildformrelation::init. One deals with a list of child cursors, the other only one. Another thing to be generalized and reused in a proper way. They are also stuck to the bottom of existing methods, when they should really be added as additional methods.

*==============================================================================
* Method:			Init
* Purpose:			Call the RemoveParentPresObj method.
* Author:			F1 Technologies
* Parameters:		
* Returns:			
*==============================================================================

DODEFAULT()
This.RemoveParentPresObj()

**********************
* Move any child PO to the selected side

LOCAL ;
	lcParentPresObj, ;
	loUtils, ;
	lcBizObj, ;
	lcDE, ;
	laCursorClasses(1,2), ;
	lcClass, ;
	lcLibrary, ;
	lcCursor, ;
	lcDbc, ;
	lcPntPriCsr, ;
	lcDataSource, ;
	laRels(1), ;
	lnRels, ;
	lnI, ;
	lcRel, ;
	lcRelPntTbl, ;
	lcRelPntFld, ;
	lcRelCldTbl, ;
	lcRelCldFld, ;
	lcLstPO, ;
	lcLstPriCsr
	
loUtils = NewObject( "cWizUtils", oVfe.cWizDir + "LIBS\WIZUTILS.VCX" )
assert vartype( loUtils ) = T_OBJECT
	
* Get the name of the parent PO
assert vartype(ThisForm.oWizProps.cPOName) = T_CHARACTER
lcParentPresObj = ThisForm.oWizProps.cPOName

assert NOT EMPTY(lcParentPresObj)

lcParentPresObj = UPPER(ALLTRIM(lcParentPresObj))
	
* get the name of the primary cursor of the parent PO's BO

with loUtils

	lcBizObj = .GetBusinessObject( lcParentPresObj )
	assert !empty( lcBizObj )

	lcDE = .GetDataEnvironment( lcBizObj )
	assert !empty( lcDE )
	
	.GetCursorClasses( lcDE, @laCursorClasses )
	* I think OR should be AND but it was in the original FVE code, so I left it allownkept it around....
	assert alen( laCursorClasses, 1) > 1 OR (!empty( laCursorClasses(1,1) ) and !empty( laCursorClasses(1,2) ) )

    lcClass = laCursorClasses(1,1)
    lcLibrary = laCursorClasses(1,2)
    lcCursor = .GetCursorSource( lcClass, lcLibrary )
	assert "!" $ lcCursor

endwith

lcDbc = LEFT(lcCursor, AT('!', lcCursor) - 1)								
lcPntPriCsr = SUBSTR(lcCursor, AT('!', lcCursor) + 1)								

lcDataSource = lcDbc + "!Relations " + lcPntPriCsr
lnRels = oVFE.oMetaMgr.DBCXGetAllObjects( lcDataSource, @laRels )

thisform.lockscreen = .f.
* set step on

* For each relation pertaining to the primary Cursor of the primary BO of the Parent PO,
* both parent and child relations
for each lcRel in laRels

	* Break the relation into (parent and child) (table and field).
	* Example of a relation: "client.cclkey,joborder.cjoclkey"
	* If we had a string function sf( string, start, end ) things would be nicer...
	lcRelPntTbl = substr( lcRel, 1, at( ".", lcRel )-1 )
	lcRelPntFld = substr( lcRel, at( ".", lcRel )+1, at( ",", lcRel )-at( ".", lcRel ) - 1 )
	lcRelCldTbl = substr( lcRel, at( ",", lcRel )+1, at( ".", lcRel, 2 ) - at( ",", lcRel )-1 )
	lcRelCldFld = substr( lcRel, at( ".", lcRel, 2 )+1 ) 

	* If the Parent Table of the Relation is the Table of the "Primary Cursor"
	if upper( lcRelPntTbl ) == upper( lcPntPriCsr )
	
		* For each PO in the Available list
		* whos Primary cursor 
		* is the Current Relation's Child Table 
		* Move it to the Selected list (eek!!!)

		WITH This.cntSelectChildPresObjs

			* Again, one step at a time...
			* For each PO in the Available list

*			FOR lnI = 1 TO .lstAvailable.ListCount
			* As items are removed from the list, the size of the list shrinks, so we can not use for...listcount
			lnI = 1
			do while lnI <= .lstAvailable.ListCount

				.lstAvailable.ListIndex = lnI
				lcLstPO = UPPER(ALLTRIM( .lstAvailable.List(lnI) ))


				* who's Primary cursor 
				* (here we go again....)
				with loUtils
					lcBizObj = .GetBusinessObject( lcLstPO )
					assert !empty( lcBizObj )
					lcDE = .GetDataEnvironment( lcBizObj )
					assert !empty( lcDE )
					laCursorClasses = .f.
					.GetCursorClasses( lcDE, @laCursorClasses )
					assert alen( laCursorClasses, 1) > 1 OR (!empty( laCursorClasses(1,1) ) and !empty( laCursorClasses(1,2) ) )
				    lcClass = laCursorClasses(1,1)
				    lcLibrary = laCursorClasses(1,2)
				    lcCursor = .GetCursorSource( lcClass, lcLibrary )
				endwith
				lcLstPriCsr = SUBSTR(lcCursor, AT('!', lcCursor) + 1)								

				* is the Current Relation's Child Table 
				IF upper( lcLstPriCsr ) == upper( lcRelCldTbl )
					* Move it to the Selected list
					.MoveItem()
					* The "current item" is gone, and the next item moved into the lnI posision, so don't inc(lnI)
				ELSE
					* Only inc the current pointer here, if we didn't wack the current item
					lnI = lnI + 1
				ENDIF
					
			enddo
		
		ENDWITH
				
	ENDIF

endfor

*==============================================================================
* Method:			Populatechildlist
* Purpose:			Populate the list with all of the child business object
*					names.
* Author:			F1 Technologies
* Parameters:		
* Returns:			
*==============================================================================
LOCAL ;
	laChildren[1], ;
	lnI


WITH This

	IF NOT TYPE("ThisForm.oWizProps.aRelations") = T_UNDEFINED
		DIMENSION laChildren[ALEN(ThisForm.oWizProps.aRelations, 1), ALEN(ThisForm.oWizProps.aRelations, 2)]
		=ACOPY(ThisForm.oWizProps.aRelations, laChildren)
		
		FOR lnI = 1 TO ALEN(laChildren, 1)

			IF NOT EMPTY(laChildren[lnI, 1])
				.lstChildPresObjs.AddItem(laChildren[lnI, 1])
			ENDIF
				
		ENDFOR
		
		.lstChildPresObjs.ListIndex = 1
		.lstChildPresObjs.Selected(1) = .T.
		
	ENDIF	
	
ENDWITH	


******************
* Set default Parent Key Field, Child Key Field, and Child Index Tag

local ;
	loUtils, ;
	lcParentPresObj, ;
	lcBizObj, ;
	lcDE, ;
	lcClass, ;
	lcLibrary, ;
	lcCursor, ;
	lcDbc, ;
	lcPntPriCsr, ;
	lcDataSource, ;
	lnRels, ;
	lcRel, ;
	lcRelPntTbl, ;
	lcRelPntFld, ;
	lcRelCldTbl, ;
	lcRelCldFld, ;
	lcLstPO, ;
	lcLstPriCsr, ;
	laCursorClasses(1,2), ;
	laRels(1)

loUtils = NewObject( "cWizUtils", oVfe.cWizDir + "LIBS\WIZUTILS.VCX" )
assert vartype( loUtils ) = T_OBJECT

* Find the primary cursor of the parent PO
* Get the name of the parent PO
assert vartype(ThisForm.oWizProps.cPOName) = T_CHARACTER
lcParentPresObj = ThisForm.oWizProps.cPOName
assert NOT EMPTY(lcParentPresObj)
lcParentPresObj = UPPER(ALLTRIM(lcParentPresObj))
* here we go again!
with loUtils
	lcBizObj = .GetBusinessObject( lcParentPresObj )
	assert !empty( lcBizObj )
	lcDE = .GetDataEnvironment( lcBizObj )
	assert !empty( lcDE )
	.GetCursorClasses( lcDE, @laCursorClasses )
	assert alen( laCursorClasses, 1) > 1 OR (!empty( laCursorClasses(1,1) ) and !empty( laCursorClasses(1,2) ) )
    lcClass = laCursorClasses(1,1)
    lcLibrary = laCursorClasses(1,2)
    lcCursor = .GetCursorSource( lcClass, lcLibrary )
	assert "!" $ lcCursor
endwith
lcDbc = LEFT(lcCursor, AT('!', lcCursor) - 1)								
lcPntPriCsr = SUBSTR(lcCursor, AT('!', lcCursor) + 1)								
lcDataSource = lcDbc + "!Relations " + lcPntPriCsr
lnRels = oVFE.oMetaMgr.DBCXGetAllObjects( lcDataSource, @laRels )

* For each relation, 
* if there is a selected child PO whose primary cursor
* is the child table of the relation
* Set default Parent Key Field, Child Key Field, and Child Index Tag

* Again, but slow...
* For each relation (both parent and child relations)
for each lcRel in laRels

	* Break the relation into (parent and child) (table and field).
	lcRelPntTbl = substr( lcRel, 1, at( ".", lcRel )-1 )
	lcRelPntFld = substr( lcRel, at( ".", lcRel )+1, at( ",", lcRel )-at( ".", lcRel ) - 1 )
	lcRelCldTbl = substr( lcRel, at( ",", lcRel )+1, at( ".", lcRel, 2 ) - at( ",", lcRel )-1 )
	lcRelCldFld = substr( lcRel, at( ".", lcRel, 2 )+1 ) 

	* If the Parent Table of the Relation is the Table of the "Primary Cursor"
	if upper( lcRelPntTbl ) == upper( lcPntPriCsr )
	
		* For each PO in the Child PO list
		* whos Primary cursor 
		* is the Current Relation's Child Table 
		* Set the parent key, child key and child index

		* Again, one step at a time...
		* For each PO in the Selected list
		FOR lnI = 1 TO ALEN(laChildren, 1)

			assert NOT EMPTY(laChildren[lnI, 1])

			lcLstPO = UPPER(ALLTRIM( laChildren( lnI, 1 ) ))

			* who's Primary cursor 
			with loUtils
				lcBizObj = .GetBusinessObject( lcLstPO )
				assert !empty( lcBizObj )
				lcDE = .GetDataEnvironment( lcBizObj )
				assert !empty( lcDE )
				laCursorClasses = .f.
				.GetCursorClasses( lcDE, @laCursorClasses )
				assert alen( laCursorClasses, 1) > 1 OR (!empty( laCursorClasses(1,1) ) and !empty( laCursorClasses(1,2) ) )
			    lcClass = laCursorClasses(1,1)
			    lcLibrary = laCursorClasses(1,2)
			    lcCursor = .GetCursorSource( lcClass, lcLibrary )
			endwith
			lcLstPriCsr = SUBSTR(lcCursor, AT('!', lcCursor) + 1)								

			* is the Current Relation's Child Table 
			IF upper( lcLstPriCsr ) == upper( lcRelCldTbl )
				* Set the parent key, child key and child index
				* We are Assuming that the child of the relation 
				* is the child key field and the index tag.
				ThisForm.oWizProps.aRelations( lnI, 2 ) = lcRelPntFld
				ThisForm.oWizProps.aRelations( lnI, 3 ) = lcRelCldFld
				ThisForm.oWizProps.aRelations( lnI, 4 ) = lcRelCldFld
			ENDIF
				
		endfor
		
			
	ENDIF

endfor


*==============================================================================
* Method:			cntparentchildformrelation::init {vfe6\wizards\libs\vfewiz60.vcx}
* Purpose:			Set up default relation based on persistant relations
* Author:			Carl Karsten
* Parameters:		
* Returns:			
*==============================================================================
******************
* Set default Parent Key Field, Child Key Field, and Child Index Tag

local ;
	loUtils, ;
	lcParentPresObj, ;
	lcBizObj, ;
	lcDE, ;
	lcClass, ;
	lcLibrary, ;
	lcCursor, ;
	lcDbc, ;
	lcPntPriCsr, ;
	lcDataSource, ;
	lnRels, ;
	lcRel, ;
	lcRelPntTbl, ;
	lcRelPntFld, ;
	lcRelCldTbl, ;
	lcRelCldFld, ;
	lcLstPO, ;
	lcLstPriCsr, ;
	laCursorClasses(1,2), ;
	laRels(1)

loUtils = NewObject( "cWizUtils", oVfe.cWizDir + "LIBS\WIZUTILS.VCX" )
assert vartype( loUtils ) = T_OBJECT

* Find the "primary cursor" of the parent PO
* Get the name of the parent PO
assert vartype(ThisForm.oWizProps.cParentPO) = T_CHARACTER
lcParentPresObj = ThisForm.oWizProps.cParentPO
assert NOT EMPTY(lcParentPresObj)
lcParentPresObj = UPPER(ALLTRIM(lcParentPresObj))
* here we go again!
with loUtils
	lcBizObj = .GetBusinessObject( lcParentPresObj )
	lcDE = .GetDataEnvironment( lcBizObj )
	.GetCursorClasses( lcDE, @laCursorClasses )
	assert alen( laCursorClasses, 1) > 1 OR (!empty( laCursorClasses(1,1) ) and !empty( laCursorClasses(1,2) ) )
    lcClass = laCursorClasses(1,1)
    lcLibrary = laCursorClasses(1,2)
    lcCursor = .GetCursorSource( lcClass, lcLibrary )
	assert "!" $ lcCursor
endwith
lcDbc = LEFT(lcCursor, AT('!', lcCursor) - 1)								
lcPntPriCsr = SUBSTR(lcCursor, AT('!', lcCursor) + 1)								
lcDataSource = lcDbc + "!Relations " + lcPntPriCsr
lnRels = oVFE.oMetaMgr.DBCXGetAllObjects( lcDataSource, @laRels )

* For each relation, 
* if there is a child PO whose primary cursor
* is the child table of the relation
* Set default Parent Key Field, Child Key Field, and Child Index Tag

* Again, but slow...
* For each relation (both parent and child relations)
for each lcRel in laRels

	* Break the relation into (parent and child) (table and field).
	lcRelPntTbl = substr( lcRel, 1, at( ".", lcRel )-1 )
	lcRelPntFld = substr( lcRel, at( ".", lcRel )+1, at( ",", lcRel )-at( ".", lcRel ) - 1 )
	lcRelCldTbl = substr( lcRel, at( ",", lcRel )+1, at( ".", lcRel, 2 ) - at( ",", lcRel )-1 )
	lcRelCldFld = substr( lcRel, at( ".", lcRel, 2 )+1 ) 

	* If the Parent Table of the Relation is the Table of the "Parent Primary Cursor"
	if upper( lcRelPntTbl ) == upper( lcPntPriCsr )
	
		* If the Primary cursor of the "Child PO Primary Cursor"
		* is the Current Relation's Child Table 
		* Set the parent key, child key and child index

		* Again, one step at a time...
		* If the "Child PO Primary Cursor"
		lcChildPO = upper( ThisForm.oWizProps.cChildPO )
		* who's Primary cursor 
		with loUtils
			lcBizObj = .GetBusinessObject( lcChildPO )
			assert !empty( lcBizObj )
			lcDE = .GetDataEnvironment( lcBizObj )
			assert !empty( lcDE )
			laCursorClasses = .f.
			.GetCursorClasses( lcDE, @laCursorClasses )
			assert alen( laCursorClasses, 1) > 1 OR (!empty( laCursorClasses(1,1) ) and !empty( laCursorClasses(1,2) ) )
		    lcClass = laCursorClasses(1,1)
		    lcLibrary = laCursorClasses(1,2)
		    lcCursor = .GetCursorSource( lcClass, lcLibrary )
		endwith
		lcLstPriCsr = SUBSTR(lcCursor, AT('!', lcCursor) + 1)								

		* is the Current Relation's Child Table 
		IF upper( lcLstPriCsr ) == upper( lcRelCldTbl )
			* Set the parent key, child key and child index
			* We are AssUMing that the child of the relation 
			* is the child key field and the index tag.
			This.txtParentKey.Value = lcRelPntFld
			This.txtChildKey.Value  = lcRelCldFld
			This.txtChildTag.Value  = lcRelCldFld
		ENDIF
			
	ENDIF

endfor

		


Contributors Carl Karsten
Category Visual FoxExpress Category Visual FoxExpress Tips And Tricks
( Topic last updated: 1999.08.12 10:40:47 PM )