Using PUBLIC variables in VFP.
I know I should be writing stuff about VFP9 and in the coming days I will (for a great intro see Castro Shehata’s summary from the Sydney VFP User Group meeting earlier tonight) but this time I wanted to share a thought on PUBLIC variables.
We all know public variables are bad and should be avoided right?
Well that was what I was taught at uni. But recently I’ve reconsidered and now I use them freely when appropriate. Before you start dismissing me let me explain, and if you have a better, easier method please let me know.
In an application we are writing we create a COM object that holds table record fields (the object is actually a collection of field objects). The app throws container classes onto forms or onto a pageframe on the screen. The container classes have controls that use these COM object as controlsources.
So, what I needed was an easy way of linking the COM objects to the controls.
If it were on a form it’d be easy, just add a property to the form and then refer to that in the controlsource of each control eg:
ThisFormSet.oProperty = CREATEOBJECT('MyCOMObject.MyCOMClass')
Myclass.Control1.ControlSource = ThisFormSet.oProperty.oFields.myfield.Value
But these classes could be thrown onto anything, including other classes, pageframes, _SCREEN, etc, so you are not guarenteed of the FormSet being there.
So I just needed a way of referring to the COM object easily.
Now, initially I went down the path of a collection class that kept all my COM objects together, etc. But I still had the problem of having to keep a reference to the collection index or name. The logical place to put this would be on the container class.
Anyway I was pondering this with Scott at work, and he thinks for a second and suggests using a public variable. I’ll spare you all my protestations, because when it boiled down to it I couldn’t think of a good reason not to use them.
So now instead of storing a collection class reference on the class I instead store the name of the public variable.
The code will do something like this:
LOCAL cObjectName, cString
* create a unique public variable
cObjectName = 'oCOM' + ALLTRIM(SYS(2015))
cString = 'PUBLIC ' + cObjectName
* create the COM object
cString = cObjectName + [ = CREATEOBJECT('MyCOMObject.MyCOMClass') ]
oContainer.cVariableName = cObjectName
* set control sources
oContainer.oControl1.ControlSource = cObjectName + '.oFields.myfield1.Value'
oContainer.oControl2.ControlSource = cObjectName + '.oFields.myfield2.Value'
And on the destroy of the class you release the public variable eg:
cString = 'RELEASE ' + oContainer.cVariableName
Ofcourse we’ve written generic routines for all these things eg for linking the COM objects and the controls all we need to do is a call a method and pass it the name of the COM object and the container class and it does the rest. The release variable is in the base class destroy() etc.
So there’s a thought for public variables. I’m sure there are many solutions to this issue, but this one works really well and is simple to implement.