Composite Paramaters

The objectinfo( function has a “Composite Properties” option called “countall”. But that function, entered by itself (e.g. objectinfo(“countall”) always returns 1. Does it need other parameters?

Vic

Works for me…

Hmm, this seems to work only for the form that is active when it is run. I could not get it to work for a form that has not been opened or even another open form that was not the active form.

I checked the source code and you’re right, it will only work for the active window. However, I don’t think that is Vic’s issue, since he stated he was not entering a second parameter for the form name.

Hello Gary and Jim,

Looks like that is the problem - the form I want counted is not open. But that is because Jim provided me a great macro that retrieves object info WITHOUT having to open the form. But now, it looks like I will have to open (and then close) each form anyway. The last time I tried that in this file, the file got corrupted - badly.

I’ll have to find another approach in lieu of the “countall” approach. Don’t want to take a chance with opening/closing form windows again.

Vic

There is a way to count the number of objects on any form in any open database using the formblueprint statement and some fancy filtering to get that information. Here is the experimental code I used to check a form named “TestForm” in the current database that did not need to be open at the time.

let formObjects=""
formblueprint "", "TestForm", formObjects
message arraysize(arraystrip(arrayfilter(formObjects, lf(), {?(import() beginswith 
"newformobject","x","")}),lf()),lf())

This returned the number of objects in any of the forms I checked and could be included in the code previously posted in the other tread. The more objects on a form the longer it will take to gather this information so that might be a problem running this within a loop.

Regardless, it is the only thing I can think of at the moment. :thinking:

That procedure (which I posted here on another thread) could easily be modified to count the objects as it scans them. It’s already scanning every object in every form, so it won’t take any extra time to count the objects. Just add a variable and add one as each object is scanned, then reset to zero as each form starts. Or you could just group the resulting database by form name after the scanning is complete.

Actually, the macro I sent you already provides the count – the object id of the last object in each form is guaranteed to be the same as the count of the number of objects in the form.

Update: See the bottom of this post for another way to find out the count.


I am puzzled though – why do(Vic) you care what the count is? I don’t see why knowing the count would help with your goal of understanding which of your form objects call what code.

The formblueprint statement is doing more or less the same thing as the procedure I sent to Vic a few days ago (and also posted here).

The formblueprint statement simply uses the objectinfo( function to do it’s work. I’ve seen people scan blueprints before to extract information, if the information is what you need, I would suggest it is always simpler to just use objectinfo(.

The original purpose of blueprints was for tracking changes to your database using source control systems (git, etc.). They are great for that. They are also great if you want to know the code needed to re-create an object. But they weren’t designed to be a parseable data source. Of course that can be done, but it’s generally easier to go to the original source material. The blueprint statements are all “open source” so you can look to see how the blueprint data is compiled if you want to access that data yourself directly.

Guess what – I just checked the source code for formblueprint and there is another way to get the object count for any form – the getformoption( function. This will work for any form in any open database, whether the form is open or not.

So if you really really need the object count, you can easily get it for any form.

I can simplify the code further:

let formObjects=""
formblueprint "", "TestForm", formObjects
message tagcount(formObjects, "newformobject", " ")

I think our replies crossed, but I think this is the most simple possible implementation:

message getformoption("", "TestForm", "OBJECTCOUNT")

It could also be used with a different database:

message getformoption("TestDatabase", "TestForm", "OBJECTCOUNT")

I don’t feel so bad since you only found the getformoption( function by looking up the source code. Anyway, Vic’s needs are now met - even though I can’t imagine what he needs it for either.

Hello Jim and Gary,

I slightly modified your code, Jim, and added a loop. I wanted to end the loop when all objects were inspected. To end the loop, I added a

stoploopif Objectnumber > objectinfo("count")

but that statement didn’t work for the reasons stated above. But the getformoption( function should do the trick. I’ll give it a try.

Gary, thanks for your continuing help. You have a knack of coming up with creative solutions. I’m guessing you are an engineer, but maybe I’m prejudiced.

Vic

This is redundant, the loop was already there and there was already code to stop the loop once all objects had been inspected. Here is the line of code that stops the loop.

stoploopif oClass=""

There is no need to check the count, since the oClass variable will always be empty once all of the objects have been scanned (and non-empty if there is at least one object remaining to be scanned).

Here is the portion of the code I sent you that scans all of the objects in a particular form. (The entire code also contained another loop enclosing this one that looped for each form). The second line of the loop is where it checks to see if all of the objects have been scanned.

loop
    let oClass = catcherror("",objectinfo("class",objectNumber,formName,scanBase))
    stoploopif oClass=""
    if Form<>""
        addrecord
    endif
    Form = formName
    Object = str(objectNumber)
    Class = oClass
    Name = objectinfo("name",objectNumber,formName,scanBase)
    Code = objectinfo("procedure",objectNumber,formName,scanBase)
    objectNumber = objectNumber+1
endloop

At the end of this code, after the endloop statement, the objectNumber variable contains the count of the objects in the form. But you don’t need that to stop the loop.

Actually at that point the “objectNumber” variable will be one more than the real object count.

Yes, Gary is correct, I made a classic “off by one” error on that!

This is why good programmers avoid using counts whenever they can – it’s so easy to make that kind of mistake. A lot of security bugs are “off by one” errors.

Good point, Jim. I use counts often in loops, which goes to prove I’m not a “good programmer”. But, with care and debugging, the job eventually gets done.

I noticed the catcherror function in your code, but I didn’t know what that was. Now, I looked it up and see what it accomplishes. Very clever. You set up a loop which gives an impossible result in one iteration, and stop that loop when Panorama objects to the impossibility with an error.

Live and learn. At this rate, I figure by the time I am 104, I’ll have PanX down pat!

Vic