I want to show the current “$TextListQueryFormula” of a named TextList in a TextDisplay box to help with troubleshooting and info for the user. I know how to set the value, but can’t find how to query it so it will return the text string.
You can use a procedure like
Object "Name of Your Text List" Variable = objectinfo("$TextListQueryFormula")
Your Text Display object would display the variable.
Oops. I forgot. The objectinfo( function now has an optional parameter, that lets you name the object, so you could just use
objectinfo("$TextListQueryFormula", "Name of Your Text List")
as the formula in your Text Display object.
I was writing a response, then saw that you added just what I was thinking to it, and it works just fine. The docs suggest that the Property argument is limited to simple things like color or font, but clearly it can reference anything in the Blueprint so this works fine. Thank you Dave.
Read the part under Native Object Properties.
I will do that, but I may have spoken too soon about my “success.” The display does not refresh when I take an action that changes the query.
If the procedure that changes the query does a
ShowPage after the change, the display will refresh.
I have a lot of procedures making changes, but this is doable. Showpage does what I want, but the latency between setting the Query text and updating the Query TextDisplay is unexpectedly long. The TextList display affected by the new query updates immediately.
A more complicated, but quicker solution would be to put a FileGlobal variable in your Text Display formula. Make it the second parameter in an
ignore( function. The first parameter would be the
objectinfo( function. Then your procedure could do a
ShowVariables naming the variable. If your variable isn’t in the formula for any other object, that one object would be the only one redrawn. I don’t think the variable even needs to exist. I think the error would also be ignored, but I haven’t tested that.
It doesn’t need to exist, but if it doesn’t, you need to use the catcherror( function. I demonstrated this in one of the class videos, I think the one about data values.
In fact, the code that creates blueprints uses the objectinfo( function, it’s in _DatabaseLib in the FORMOBJECTBLUEPRINT procedure.
I have tested it now, and the undefined variable is ignored, without using catcherror(. The ignore( function simply ignores the error returned by its second parameter.
Wow, it helps to have the guys who know the nuts and bolts under the hood work this out. I can’t imagine how I would ever stumble upon this approach by myself. I just invented a variable named IgnoreMe, didn’t define it in any way, and it is working nicely. No catcherror( required. Thank you.
While I have your attention, is there any facility in existence or in your imagination to provide a “roomier” editing environment for a procedure entered directly in the Procedure pane of an object? The forced wrapping of code text due to the very narrow confines of this pane makes it difficult to evaluate for missing parentheses, etc. Something like a small button on that pane that opens a resizable window that contains the code and puts it back in the properties when finished editing. I would be reluctant to put large complex procedures in there, but when we have very long variable names (like $TextListQueryFormula) it makes things difficult to read and evaluate. This could also go for the Formula pane.
Oh, I missed where you mentioned the ignore function. That will work also.
Here’s what I had in mind:
catcherror("",syncVariable)+objectinfo("$TextListQueryFormula", "Name of Your Text List")
Then to update you use:
But using ignore( will work also.
No immediate plans for that – maybe someday. However, don’t forget that you can use the call statement and put the bulk of the code in a regular procedure, where you can use the “roomy” editor. That’s what I usually do if the code is more than 2 or 3 lines. Another advantage of this is that it allows you to edit the code even when the form is in data mode.
Of course, that’s how I had to do everything in Pan 6 and earlier, so that’s familiar. My suggestion helps keep the number of open windows down when I’m deep in development.
I have used a special procedure set up for this purpose. The individual fields that require larger procedures would use something like
call .myfieldproc,"__fieldname" to call the procedure using the added parameter to identify the calling field. The .myfieldproc procedure itself would look something like this:
local __caller __caller=parameter(1) if __caller=__firstfield // do some stuff elseif __caller=__secondfield // do other stuff elseif __caller=__thirdfield // do different stuff ............ endif
This allows for only one procedure window to handle all the field procedures and keeps everything in one place and handy for editing. Note that I used “__”+field name as the parameter designation so each section of code is easily identifiable as to the field that called.
That’s a good idea, but Panorama X makes this much easier. Instead of using call, use callwithin. This allows you to put a bunch of routines in one procedure, giving each one a label. Panorama jumps right to the spot needed (instead of using a bunch of if statements). This is easier to write, and will be a lot faster to execute also (those if statements take time).
Basically, Panorama X breaks the 1/1 lock between “procedure” and “subroutine”.
I think Gary’s example is for code that runs when a field is modified. In that case, you can make it even simpler. Just use
call .myfieldproc, and then .myfieldproc looks like this:
goto "__"+info("fieldname") if error rtn endif // in case a field has no code __field1: ... code for field 1 ... return __field2: ... code for field 1 ... return __field3: ... code for field 1 ... return
Actually, in this case, just call the procedure .ModifyRecord and then you don’t even need to call it!
I’m reviving this thread because I’ve encountered another issue within the same situation. The “ignore” construction works fine when it is in the formula of the form’s TextDisplay object. This works well when I am modifying the Query from controls on the form itself. Now I am performing a query originating from an external source (a button in another database), using changeobject. It performs the query correctly, displaying exactly the data I asked for, but my form’s TextDisplay object that shows the current query remains showing the previous query from before I pushed the button. In Graphics mode I can see that the current $TextListQueryFormula is exactly what I asked for, but the display is a step behind. I have tried using a “showpage” at the end of my procedure but it has no effect. How can I force this TextDisplay object to update itself when I give it a new query from an outside source?
Dave covered this earlier in the thread – you need to set up a special “sync variable” and by including that in the text display formula (probably using catcherror, as Dave illustrated) and using
showvariables on that variable it will update.