Agent Query: Trying to understand the usage of variables

Hello,

I am trying to factorize my code using variables.

Where I have a working agent such as:
descendedFrom(“/Fabula”) & ($Text.icontains(“Hanzö”)| $Name.icontains(“Hanzö”));
I wish to put “Hanzö” in a variable so I can replicate the agent more easily.
However, I start seeing strange behavior as soon as I declare a variable.
My guess is I have an obvious syntax error but have not been able to find it.

I am enclosing a test TBX where I show that behavior.

What am I missing?

Note: ultimately I am expecting this to work:
var:string vName=“Hanzö”;
descendedFrom(“/Fabula”) & ($Text.icontains(vName)| $Name.icontains(vName));

Regards,
Philippe
Variables.tbx (110.8 KB)

Close! $AgentQuery holds the query string so set that via code.

Here, I’ve set the target test string in $MyString and used this edict (it could be a rule, stamp, etc.)

var:string vName;
vName = $MyString;
$AgentQuery = 'descendedFrom("/Fabula") & ($Text.icontains("'+vName+'")| $Name.icontains("'+vName+'"))';

I’ve reading vName from an attribute vyt you could set it all sorts of other ways.

If you wanted to read the agent’s $MyString directly, you can use use the agent designator:

$AgentQuery = 'descendedFrom("/Fabula") & ($Text.icontains($MyString(agent))| $Name.icontains($MyString(agent)))';

The above work for me in v10.2.0b717 (current public release) and should work in most recent releases. Does that help?

Hello @mwra,

Thanks for your help.

I have tried both alternatives you showed but cannot get them to work (see enclosed)

  • I need to do some reading but currently assume that $AgenQuery is used as TB will do an “eval”(evaluate the string) of $AgentQuery but not of the content of the query box, is that correct?
  • I like the second alternative better as I no longer see the advantage of using a “var” unless this[1] were legal as per your comment “I’ve reading vName from an attribute vyt you could set it all sorts of other ways.”

Regards,
Philippe
[1]

var:string vName;
vName = "Hanzö";
$AgentQuery = 'descendedFrom("/Fabula") & ($Text.icontains("'+vName+'")| $Name.icontains("'+vName+'"))';

or

var:string vName="Hanzö";
$AgentQuery = 'descendedFrom("/Fabula") & ($Text.icontains("'+vName+'")| $Name.icontains("'+vName+'"))';

Variables.tbx (125.6 KB)

No, you misunderstand. A query must be an actual query, not code. But I think the step you are missing is the $AgentQuery holds the literal query code such as you see in the Action Inspector’s https://www.acrobatfaq.com/atbref10/index/Windows/Inspector/Action_Inspector/Query_tab.html:


You mistake is you are pasting code directly into the Query box of the Query Inspector, rather than running the code, so as to make a string that is the lister value of the query. You store that string as the value of $AgentQuery, and thus set the correct query for the agent:

  • run some action code (rule, stamp, whatever) that creates a query using a value you can vary via a stored value (a var tor an attribute value)
  • store that string value (the ‘compiled’ query) in the agent’s $AgentQuery
  • the agent now sees that as its query

How you set up the per-agent test value is up to you: literal string, or action code variable, or an attribute value.

Using the agent designator takes a different approach as it assumes the test value us stored as the value of an attribute of the agent. A common approach is to store the test value in $MyString for the agent and show $MyString as a Displayed Attributes. this allows the user to edit $MyString and thus automatically update the query without having to edit the query directly.

Which approach works best for you, only you can gauge as user’s work style varies.

Hi @mwra,
Many thanks,
I have been typing code directly into the Query box of the Query Inspector for quite some time now.
I can see now it is being populated, as is $AgentQuery, automatically based on what is typed in the Action Inspector/Query box.
It is also clear that my vocabulary does not match that of TB.
Is it fair to say I should consider the Query Inspector/Query Box&Action Box as read-only?
It is all starting to make a lot more sense but I need to do some more reading and testing:)

Thanks again,
Regards,
Philippe

Not at all.

I’d suggest that you start with a small document. Make a bunch of notes — say, things you have in your pantry. Organize them in some sensible way. Now, make an agent and try out some queries.

I think starting with aTbRef may be an issue here; that’s a big and complex document, with some moving parts…

@eastgate - Ok, starting small;)
Regards,
Philippe

I sense the word ‘code’ is part of the confusion here as it sort of has two different meaning, contextually. Queries, as stored in $AgentQuery are written in action code syntax, but essentially a subset of the whole of action code as used in app automation. So, it helps to have a firm grasp of the basics of queries in order to understand how/where to make dynamic changes to the targetting of the query, as is your desire.

As simply as I can put it, the query must be a single complete expression, i.e.

inside("Projects")

No semi-colon terminator is used (it is ignored if put in). Also you cannot have multiple expressions. This is not correct:

inside("Projects");$Prototype=="Person"; NO!

But in a query you can have multiple terms (questions). for that you must use a & (AND) or | (OR) join between each term. For instance, trying the the last above using those types of joins:

inside("Projects") & $Prototype=="Person" (an AND join)

inside("Projects") | $Prototype=="Person" (an OR join)

White space around the join characters is optional.

Working at this sort of level, it doesn’t matter whether you type directly into the Query Inspector (or use Get Info/agent) as the single or multi-term expression used is complete, so to speak.

The first level of allowing some dynamic change of the query’s meaning is to use a test value that is stored in an attribute. then, altering the attribute value alters the query’s meaning. Most usually, this involves a String type attribute, but you can test most types (Number, Boolean, Date). Whilst starting out avoid trying to test lists (List or Set) or dictionaries (Dictionary) as that is more complex usage - keep the latter for after you understand the basics.

So, if you want to test for a prototype the varies with the task at hand (i.e. the tested value of $Prototype needs to differ) you can store the value in the agent (any suitable attribute, here $SomeAttribute) and use the agent designator to address it:

inside("Projects") | $Prototype==$SomeAttribute(agent)`

Your query can also read an attribute value stored in some other note:

inside("Projects") | $Prototype==$SomeAttribute(“My Config Note”)`

But, do not use this:

inside("Projects") | $Prototype==$SomeAttribute`

Why? Because now the value of $SomeAttribute is being read from the note currently being queried and not from the agent’s value, as you might have assumed. This may seem counter-intuitive at first encounter but will make sense once you use agents a bit.

The neat part about the agent designator use is if you make the tested attribute, e.g. here $SomeAttribute, a Displayed Attribute in the agent you can alter its value by hand in the Displayed Attributes table and the meaning of the query is automatically updated and used by the agent.

You can even use action code elsewhere in the doc to set the agent’s $SomeAttribute value and achieve the same effect. By the same token, code can be used to write a complete query (as in the terms described above) into the agent’s $AgentQuery, thus altering the query run. I’d suggest these latter code based approaches you leave for now. Using the agent designator should get you started and you can loop back to a more code-based automation if the need arises, by which time you’ll likely have a better handle on agent and action code.

Lastly, if you haven’t looked at the Getting Started with Tinderbox PDF (accessed via the app’s Help menu) then it’s well worth a read/skim through as it covers the basics of queries.

It’s just Murphy’s Law that often our initial desired use of a feature isn’t the basic form and the form we want requires some understanding of the basics for the explanation of our desired form to make sense. :slight_smile:

HTH

Hello @mwra;
I really appreciate your help.
I am re-visiting and re-organizing my tinderbox-help.tbx which I populated some years ago based on my understanding of the various pieces of documentation. From now on, I’ll built/test/document small bricks before I apply them to my work TBXs:)
Regards,
Philippe

1 Like

Happy to help. Lots of things are only obvious once you know. :slight_smile: