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!

Complex Object Usage on a Tab 1

Status
Not open for further replies.

Scott24x7

Programmer
Jul 12, 2001
2,826
JP
Hi All,
Sorry for my vague title, but this is a slightly complex issue I'm wrestling with, and didn't know how to describe it otherwise.
The Challenge:
My team have asked me to create a "quality" score for data completeness on each tab I have in my PageFrame. This is based on certain objects having been populated with data.
Not all objects should be included, so at the base class level, on objects that are to be considered (textbox, spinner, editbox, combobox, etc.) I have created a custom property called lquality which is a logic value .F. (default) or .T.
I then go to the objects I want to include in the quality calculation and set those as .T.
What I then need to be able to do is within the Tab (Page) I need to be able to look at all the objects on the page, and determine if they have an lquality property, and if they do, what state it is in. I also need to count all the .T. values for lquality, and separately count if they have data (i.e. some Value() other than "" or .NULL.
But I haven't the first clue how to interrogate the objects just in that tab. I guess I need 2 accumulators, one like nCountQuality which is incremented every time we find a lquality = .T., and a second nQualityAccumulator which is incremented by 1 when lquality = .T. and EMPTY() = .F. (or something like that?)

This value will then get stuffed into a textbox on the form called txtQuality by assigning a value of 1 to 10 to it based on the % complete (i.e. nQualityAccumulator / nCountQuality > 95% = 10, etc.). I may vary these based on the tab depending on the value of the data itself.

This will become a KPI for our team... if they have low-quality scores means they are not putting in the data that is needed (or not tracking it down), and when they drop below a certain % we will make them go back and collect/enter the data. We're just doing this based on putting info into the field, not really looking at it's quality, but it's a better metric than no metric.
Can anyone help at least guide me in the right direction on how to build this function? (I'll then shove it into my common.prg as a function, and use it on various screens for this kind of stuff in the future).

Many thanks in advance. Hope my description here makes sense. I feel so rusty... I know I should know this stuff.


Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
What comes to mindd first is the Objects() array. The form has one, the Pageframe has one, each Page has one, so in shorrt each container object (an object/control able to hold further objects/controls) has an Objects array.

So if you start at a page level:
Code:
For Each loObj In This.Objects
   *check loObj.lQuality and  Value property exist and/or are fille dwith .T. or not null/empty.
   * Ingredients: PEMSTATUS and GETPEM.
Endfor

I'm a bit lazy right now, so I leave the rest for you as exercise.

Bye, Olaf.

 
Hi Olaf,
Thanks for the point in the right direction. I tried this:

Code:
noObjectCount = 0
noQualityCount = 0
FOR EACH loObjects IN This.Objects
	IF PEMSTATUS(loObjects,lquality,4) = .T.
		IF This.Objects.lQuality
			loObjectCount = loObjectCount + 1
		ENDIF
*
		IF NOT EMPTY(loObject.Value)
			loQualityCount = loQualityCount + 1
		ENDIF
	ENDIF
ENDFOR
*
nQualityValue = loQualityCount / loObjectCount
MESSAGEBOX(nQualityValue)

Just to see if I can get the objects to count and get the % value, but it fails with "lquality" not found object.
I don't really understand the PEMSTATUS fucnction.

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
It's PEMSTATUS(loObjects, "lQuality", 5)

Edit: Well, the main thing is putting the checked property in a string parameter. And the third parameter 4 works too, but mainly you are not concerned about user defined or not user defined, but exists or not exists, and that's 5. 5 also works for checking, whether a Value property exists, checking that as user defined would always give you .F.

And why loObjects? Each loObjects is just one of This.Objects.

Bye, Olaf.
 
Besides your names are slightly whacky, look at initialization with 0 and counting code.

Also: do you really want to count non empty values of objects having lQuality=.F.? You do so.

Bye, Olaf.
 
Hi Olaf,
I will try this.
Oh yeah, the names should really just be nObjectCount and nQualityCount.
I'm not counting lQuality=.F. (at least not intentionally). Isn't my line "IF This.Objects.lQuality" returning .T. or .F. depending on value of it? And if .F. they will skip. Oh, but maybe my next IF should be embedded in the first one... I'm sorry, I'm so rusty my logic at the moment, it's really frustrating because I remember when this used to be AUTOMATIC to me.

Oh, you may remember me here from befor as "TheManiac", but I run a data center forum on here now, so I changed it to Scott7x24.
Cheers, will give this new method a bash.

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Hi Olaf,
Ok, so it's crashing now at the line that says:
IF This.Objects.lQuality = .T.

With message "Property LQUALITY is not found."

The code now looks like this:

Code:
SET STEP ON 
nObjectCount = 0
nQualityCount = 0
nQualityValue = 0
FOR EACH loObjects IN This.Objects
	IF PEMSTATUS(loObjects,"lQuality",5) = .T.
		IF This.Objects.lQuality = .T.
			nObjectCount = nObjectCount + 1
			IF NOT EMPTY(loObject.Value)
				nQualityCount = nQualityCount + 1
			ENDIF
		ENDIF
	ENDIF
ENDFOR
*
nQualityValue = nQualityCount / nObjectCount

So not sure what's going on on that line. I tried to put "SET STEP ON" to watch it run but just looping through the FOR I couldn't tell what object it was on (it clearly went through 5 or 6 objects first, so the PEMSTATUS line must be ok, but I'm not sure what' I'm doing wrong here. Object manipulation was never a strong suit.


Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
This.Objects is a collection of loObjects.
Each individual loObjects must have the lQuality property, not the collection itself.
Please try IF loObjects.lQuality

Respectfully,
Vilhelm-Ion Praisach
Resita, Romania
 
Excellent! It's now working. Here is the final version of the code that does the trick:

Code:
nObjectCount = 0
nQualityCount = 0
nQualityValue = 0
FOR EACH loObjects IN This.Objects
	IF PEMSTATUS(loObjects,"lQuality",5) = .T.
		IF loObjects.lQuality = .T.
			nObjectCount = nObjectCount + 1
			IF NOT EMPTY(loObjects.Value)
				nQualityCount = nQualityCount + 1
			ENDIF
		ENDIF
	ENDIF
ENDFOR
*
nQualityValue = nQualityCount / nObjectCount

My saviour once again.


Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
You misunderstood my suggestion to name loObjects loObject as using This.Objects instead. I never suggested to make the changes you made.

Good Vilhelm-Ion could give it the final touch.

Bye, Olaf.
 
Sorry, you kind of lost me.

Are you suggesting it is better to have the line:

IF PEMSTATUS(This.Objects,"lQuality",5) = .T.

Instead of

IF PEMSTATUS(loObjects,"lQuality",5) = .T.

Is there some reason this is better?
-S


Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
I am just talking about the singular plural of things. You can't do PEMSTATUS(This.Objects,"lQuality",5) simply because This.Objects is not an object, it's an array of objects.
Forget about it. Run the code as it works for you.

Bye, Olaf.
 
I see your point, and I'm kind of crazy about pluralizing/singularizing things as well.
But when I watch that code run, it does them one at a time, in the loop, and not all at once... so, it seems it manages them in the singular not in the collective?

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Yes, the code does the objects one at a time, each object refererence is put into a variabe you called loObjects.
That's all I was pointing out. The code works nevertheless, as it doesn't depend on the right pluralizing/singularizing of variable names.

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top