Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
THISFORM.DoAll function similar to THISFORM.SetAll
Message
From
30/12/1998 10:21:41
Cetin Basoz
Engineerica Inc.
Izmir, Turkey
 
General information
Forum:
Visual FoxPro
Category:
Other
Miscellaneous
Thread ID:
00171476
Message ID:
00171523
Views:
32
>Hi everyone,
>
>Is there some way I can run a method for all controls on a form who are part of a class ... in the same way I can set a property on all controls on a form who are part of a class?
>
>THISFORM.DoAll("Refresh","MyClass") ????
Hi Klas,
Here is part of a class for same purpose (ExecuteAll) :
DEFINE CLASS udfobjcollector AS custom

  *-- Object ref to a container for which object refs are placed into collection array (this.aCollection[])
  containerref = "thisform"
  Name = "udfobjcollector"

  *-- Array containing all object refs for this.containerref [Object ref to a container].
  *-- ie: this.containerref = "thisform" - all thisform objects are in collection
  DIMENSION acollection[1]


  *-- Method to fill collection array aCollection with members of all contained objects
  PROCEDURE fillcollection
  LPARAMETERS oContainerObject
  LOCAL ix, nMembers, lnExpand, oObjectRef, aContainerObjects[1]
  nMembers = amembers(aContainerObjects, oContainerObject,2)
  FOR ix = 1 to nMembers   && Start collecting
    lnExpand = iif(type("this.aCollection[1]")= "L",0,1)
    DIMENSION this.acollection[alen(this.aCollection,1)+lnExpand]
    oObjectRef = eval("oContainerObject."+aContainerObjects[ix])
    this.acollection[alen(this.aCollection,1)] = oObjectRef
    this.fillcollection(oObjectRef)  && Recurse
  ENDFOR
  * Handle _screen and _vfp to also collect their objects
  DO case
    CASE compobj(oContainerObject,_screen) && Handle _screen specially
      FOR each oForm in _screen.Forms
        this.fillcollection(oForm)  && Recurse
      ENDFOR
    CASE compobj(oContainerObject,_vfp) && Handle _vfp specially
      FOR each oFrmObject in _vfp.Objects
        this.fillcollection(oFrmObject)  && Recurse
      ENDFOR
      * _screen.forms # _vfp.objects
      * So also handle _screen.forms too
      this.fillcollection(_screen)
  ENDCASE
ENDPROC

*-- Execute method for all objects in container with a specific property value
  PROCEDURE execall
  LPARAMETERS poContainerObject, pcProperty, pcExpr, pcExecMethodName

  *!*		Sample call for a grid.afterrowcallchange to refresh controls with same recordsource
  *!* 	This is handy when there are relation and you don't want the call thisform.refresh
  *!*		thisform.objectcollector1.ExecAll(thisform, ;
  *!*					"controlsource", ;
  *!*					"upper(%_%getvalue%_%) = ["+upper(this.recordsource)+".]", ;
  *!*					"refresh()")

  *!*	 Example : Refresh all controls where controlsource = "CUSTOMER"
  *!*		ExecAll(thisform, "controlsource", "upper(%_%getvalue%_%) = [CUSTOMER.]", "refresh()")
  *!*		poContainerObject = thisform
  *!*		pcProperty = "controlsource"
  *!*		pcExpr = "upper(%_%getvalue%_%) = [CUSTOMER.]"
  *!*		pcExecMethodName = "refresh()"

  *!*	 Example : Refresh all controls where inlist(controlsource,[CUSTOMER.],[EMPLOYEE.])
  *!*		ExecAll(thisform, "controlsource", "inlist(upper(%_%getvalue%_%), [CUSTOMER.],[EMPLOYEE.])", "refresh()")
  *!*		poContainerObject = thisform
  *!*		pcProperty = "controlsource"
  *!*		pcExpr = "inlist(upper(%_%getvalue%_%), [CUSTOMER.],[EMPLOYEE.])"
  *!*		pcExecMethodName = "refresh()"

  *!*	 Notice how %_%getvalue%_% is used as a placeholder for propertyname in expression

  this.fillcollection(poContainerObject)							&& Collect all objects of object
  IF type("this.aCollection[1]") = "L"							&& No member objects
    RETURN
  ENDIF
  pcExecMethodName = pcExecMethodName + ;
    iif(at("(",pcExecMethodName)=0, "()","")	&& Eval() needs () for EM
  lcExecMethodName = substr(pcExecMethodName,1,;
    at("(",pcExecMethodName)-1)					&& Pure EM name
  lcExpr = stuff(pcExpr, ;
    at("%_%getvalue%_%",pcExpr),;
    len("%_%getvalue%_%"),;
    "loObjectName."+pcProperty)									&& Prepare expression
  FOR each loObjectName in this.acollection						&& Loop through member objects
&& Property exists and !protected and object is one we're looking for and EM exists
    IF pemstatus(loObjectName, pcProperty, 5) ;
        and !pemstatus(loObjectName, pcProperty, 2) ;
        and eval(lcExpr) ;
        and pemstatus(loObjectName, lcExecMethodName, 5)
      EVAL("loObjectName."+pcExecMethodName)					&& Execute its own method -pcExecMethodName-
    ENDIF
  ENDFOR
  this.acollection=.f.	&& Release Object References
  DIMENSION this.acollection[1]
ENDPROC
ENDDEFINE
To speed up you can move "this.fillcollection(poContainerObject)" to init of custom object and remove lines :
this.acollection=.f. && Release Object References
DIMENSION this.acollection[1]
But in this case you should explicitly call those removed lines or removeobject it to prevent hanging object refs. If you group controls in containers and just send that container as a parameter (instead of thisform) this executes fast w/o no change to code.
Cetin
Çetin Basöz

The way to Go
Flutter - For mobile, web and desktop.
World's most advanced open source relational database.
.Net for foxheads - Blog (main)
FoxSharp - Blog (mirror)
Welcome to FoxyClasses

LinqPad - C#,VB,F#,SQL,eSQL ... scratchpad
Previous
Reply
Map
View

Click here to load this message in the networking platform