Difference between revisions of "FindObjects"

(18 intermediate revisions by 3 users not shown)
Line 1: Line 1:
 
[[Category: Meta-Inference Functions]]
 
[[Category: Meta-Inference Functions]]
''new to [[Analytica 4.7]]''
+
''new to [[Analytica 5.0]]''
  
== FindObjects(regExp, attribute..., excludeAttribute..., class..., excludeClass..., value, influences..., influencedBy..., inclusive, within..., withinAny..., contains..., containsAny..., hasUserInput, hasUserOutput, hasInput, hasOutput, isLiteral, outputOf..., inputOf..., caseSensitive) ==
+
FindObjects is a powerful function that searches a model to find objects that match specified criteria.  For example, FindObjects('$', Units) returns a [[Sets - collections of unique elements|set]] of variables whose 'Units' attribute contains '$'. Among the vast number of criteria you can specify are the search text, the attribute(s) to search and class(s) of object to search (or exclude), what values it contains, which modules to search, variables that influence or are influenced by a variable, or whether an object has user inputs or outputs. For more complex searches, you can combine its results using [[Sets - collections of unique elements|set]] operations.  
  
Searches for Analytica objects matching the criteria specified. It returns a [[Set Functions|set]] of [[handle]]s to these objects. The result is [[Set Functions|a set]] (a [[reference]] to a list), so you should preface it with  [[Using_References#Dereference_Operator:_.23R|a de-reference operator (#)]], to get the list itself, e.g.:
+
=== FindObjects() returns a set ===
 +
The result from FindObjects is [[Set Functions|Set]] -- i.e. a [[reference]] to a list of  [[handle]]s to the objects found. So if you want the list of objects, you should preface the function name with  the [[Using_References#Dereference_Operator:_.23R|de-reference operator (#)]], e.g.:
  
 
:<code> #FindObjects("Cost", Identifier) &rarr; [Cost_of_gasoline, Cost_of_diesel, Levelized_cost]</code>
 
:<code> #FindObjects("Cost", Identifier) &rarr; [Cost_of_gasoline, Cost_of_diesel, Levelized_cost]</code>
  
Since the result is [[Set Functions|a set]], you can use it directly in functions like [[SetUnion]], [[SetDifference]] and [[SetIntersection]] to combine search criteria in arbitrary ways. The function is fully array-abstractable, meaning it works if any parameter is an array. In that case the results will be an array of sets of search results (each a [[reference]] to a list that is the result of a distinct search. You cannot de-reference the result when the result might be an array of searches, so you would not preface with the <code>#</code> operator, unless you know that only a single search has been requested.
+
This example returns a list of variables whose identifiers contain "Cost".
  
A rich set of optional parameters let you specify many types of criteria. You can combine criteria by specifying multiple attributes. When multiple types of criteria are present, they are combined conjunctively (i.e., they must all be true). Most of the attributes accept repeated parameters, e.g. multiple Attributes. These parameters are each followed by an ellipsis (...) in the parameter list above.
+
Since FindObjects() returns [[Set Functions|a set]], you can use it directly in functions like [[SetUnion]], [[SetDifference]] and [[SetIntersection]] to combine search criteria -- for example,
  
== Optional parameters ==
+
:<code> #[[SetUnion]]([FindObjects('$', Units), FindObjects('₤', Units)])</code>
 +
returns a list of all objects whose Units contain '$' or '₤'.
  
All parameters are optional, but you should specify at least one parameter, unless you want the set of all user-defined objects. You should use the named calling convention for all parameters except optionally the first two,  «regExp» and «attribute»,  
+
The function fully supports [[Intelligent Arrays]], meaning it works if any parameter is an array. In that case the results will be an array of sets of search result. Each cell of the array will be a [[reference]] to a list that is the result of a distinct search. You cannot dereference the result when the result might be an array of searches, so you shouldn't apply the <code>#</code> operator, unless you know that it returns only a single set.
 +
 
 +
=== FindObjects(''regExp, attribute..., excludeAttribute..., class..., excludeClass..., value, influences..., influencedBy..., inclusive, within..., withinAny..., contains..., containsAny..., hasUserInput, hasUserOutput, hasInput, hasOutput, isLiteral, outputOf..., inputOf..., caseSensitive'') ===
 +
 
 +
FindObjects has a huge number of parameters, but all are optional. You should specify at least one parameter unless you want the set of ''all'' user-defined objects. It's simplest to use [[Function calls and parameters#Name-based function calls|name-based calling syntax]] for all parameters except optionally the one or two,  «regExp» and «attribute»,  
 +
 
 +
Many parameters can be repeated (denoted by ... in the parameter list). For example, you can specify a list of classes and attributes.  It returns the union of all objects that match. So,<code>FindObjects('Possible', attribute: Title, Description, Class: Decision, Chance)</code>  returns any Decision and Chance objects that have a Title or Description that contains 'Possible'.
 +
 
 +
A variable using FindObjects() does not update automatically when relevant attributes change or objects are created or deleted.  (Analytica's [[flow architecture]] (automatic consistency maintenance) propagates changes only from Definitions and Values to other Variables that depend on them, not from other Attributes.)  That means you must explicitly cause FindObjects() to recompute if you want to reflect any changes to the objects it may search.
  
 
=== regExp ===  
 
=== regExp ===  
It returns a list of objects containing any attribute (or specified attribute) that contains this text value, case insensitive unless specified otherwise.  This parameter may also be a [[regular expression]] specifying matching text with wild-cards, special characters, and so on. .
 
  
''Change parameter name to '''findText'''''
+
This first parameters specifies text to search for. It returns a list of objects containing any attribute (or specified attribute) that contains this text value. The match is case insensitive by default.  This parameter may also be a [[regular expression]] (hence its name) containing wild-cards, special characters, and more for more complex matching.
  
 
=== attribute ===  
 
=== attribute ===  
By default, FindObjects searches all attributes of each object. With this parameter, you can specify one or more specific attributes to search for a match for «searchText» or «value». The search result doesn't include information about which attribute matched.
+
By default, [[FindObjects]] searches every user-defined attribute of each object. Or you can use  this parameters to specify one or more specific attributes in which to match the «searchText» or «value». The search result doesn't include information about which attribute matched.
 +
 
 +
=== caseSensitive ===
 +
Set to True (1) or False (0) to control whether «regExp» is case-sensitive. By default, it is case-insensitive (False).
  
 
=== excludeAttribute ===  
 
=== excludeAttribute ===  
Line 28: Line 40:
  
 
=== class ===  
 
=== class ===  
Specify one or more classes of object to search, such as Variable, Objective, Function, or SysFunction. It then returns objects of only the specified class(es). When not specified, it searches all user-defined object classes, not classes of built-in objects, like '''SysFunction''' and '''SysVar'''. If you specify '''Any''', it searches all object classes, both user and built-in.
+
Specify one or more classes of object to search, such as Variable, Objective, Function, Module, or SysFunction. It returns objects of only the specified class(es). If not specified, it searches all user-defined object classes, but not classes of built-in objects, like '''SysFunction''' and '''SysVar'''. If you specify '''Any''', it searches all object classes, both user and built-in.
  
 
=== excludeClass ===  
 
=== excludeClass ===  
Line 34: Line 46:
  
 
=== value ===  
 
=== value ===  
An [[atomic]] value to find. Previously computed values are search, or the attributes listed in «attribute». Searches within the individual cells of tables and arrays. You can search for [[NaN]] or [[Null]].
+
An [[atomic]] value to find. It returns any computed variable that has a matching value as its atomic value or as a cell in its array or table value (deterministic Value or Probvalue).  You can search for [[NaN]] or [[Null]].  It will not find a match unless the value has been computed.
 +
 
 +
=== outputOf ===
 +
Find objects, usually, Variables, Functions, and Buttons, that use the object(s) listed in «outputOf». Use a handle to each object, or its identifier as a text value. Don't just use the variable's identifier directly, because it will try to evaluate it -- e.g.
 +
 
 +
<code>FindObjects(outputOf: Handle(X), 'Y')</code>    ''not:  ''<code>FindObjects(outputOf: X, Y)</code>
 +
 
 +
It finds Variables and Functions that mention the object(s) X in their Definitions. Unlike the simple attribute access <code>Outputs OF X</code>, it also finds any Button that uses X in its  [[Onclick]] attribute or any variable that uses X in its  [[OnChange]] or [[Check]] attribute. It even finds Objects that use a system function or system variable. In these ways, it is more general that the Outputs attribute.
  
=== influences ===  
+
=== inputOf  ===  
A list of handles to, or names of variables. Finds all objects that influence the listed variable(s), i.e., all objects that are Inputs to the named variable(s) or their Inputs and so on recursively.  
+
Finds objects that are used by the objects listed in «inputOf». As with «outputOf», you should provide a handle to each variable or other object (or its identifier as text) -- and "uses" covers [[OnClick]], OnChange, and Check attributes.
  
 
=== influencedBy ===  
 
=== influencedBy ===  
A list of handles to, or names of variables. Finds all objects downstream from all variables listed.
+
Finds all downstream variables, functions and buttons that are influenced by the specified object(s), directly (as in their OutputOf, above), or indirectly, via other variables or functions.    As with «outputOf», you should provide a handle to each variable or other object (or its identifier as text) and  "influence" includes effects via [[OnClick]], OnChange, and Check, as well as Definition attributes.
 +
 
 +
=== influences ===
 +
Finds all upstream variables, functions and buttons that influence the specified object(s), directly (as in their InputsOf, above), or indirectly, via other variables or functions.    As with «outputOf», you should provide a handle to each variable or other object (or its identifier as text) and  "influence" includes effects via [[OnClick]], OnChange, and Check, as well as Definition attributes.  
  
 
=== inclusive ===  
 
=== inclusive ===  
Boolean. By default <code>FindObjects(influences: x)</code> does not include <code>x</code> itself. When «inclusive» is true, then <code>x</code> is included. This also applies to parameteres «influencedBy», «within», «withinAny», «contains» and «containsAny».
+
Boolean. By default <code>FindObjects(influences: x)</code> does not include <code>x</code> itself. When «inclusive» is true, it includes<code>x</code> in its result. This also applies to parameters «influencedBy», «within», «withinAny», «contains» and «containsAny».
  
 
=== within ===
 
=== within ===
When one or more modules is specified, only objects within the indicated modules are searched.  
+
When you specify one or more modules, it searches only objects within those modules (and their submodules).  
  
 
=== withinAny ===  
 
=== withinAny ===  
Same as «within», except that it also includes objects that are inside the specified module(s) only as a result of a module alias being inside the module.
+
Same as «within», but it also includes objects that are inside the specified module(s) only as a result of a module alias being inside the module.
  
 
=== contains ===  
 
=== contains ===  
Searches among modules that contain all of the objects specified in «contains».
+
Searches among modules that contain any of the objects specified in «contains».
  
 
=== containsAny ===  
 
=== containsAny ===  
Line 58: Line 80:
  
 
=== hasUserInput ===  
 
=== hasUserInput ===  
When true, returns objects that have an input node. When false, objects that have no input node.
+
When true, it returns only objects that have a user input node. When false, it returns only objects that have no user input.
  
 
=== hasUserOutput ===  
 
=== hasUserOutput ===  
When true, returns objects that have an output node. When false, objects that have no output node.  
+
When true, it returns only objects that have a user output node. When false, it returns only objects that have no user output.  
  
 
=== hasInput  ===  
 
=== hasInput  ===  
When true, returns objects that depend on at least one other variable. When false, returns objects that have no dependency parents.
+
When true, it returns only objects that depend on at least one other variable. When false, returns objects that have no Inputs.
  
 
=== hasOutput  ===  
 
=== hasOutput  ===  
When true, returns objects influence at least one other variable. When false, returns objects with no dependents.
+
When true, it returns objects that have at least one Output variable or function. When false, returns only objects with no Outputs.
  
 
=== isLiteral ===  
 
=== isLiteral ===  
When true, returns objects that contain only literals (explicit numbers, text, etc.) or are defined as a table with only literals in the cells'', but refer to no variables and contain no expressions''.
+
When true, it returns objects that contain only literals (explicit numbers, text, etc.) or are defined as a table with only literals in the cells'', but contain no expressions, and refer to no variables other than the Index variables for the table dimensions''.
 
 
=== outputOf  ===
 
Find objects that use the items listed in «outputOf». Specify handles to, or textual names of variables, functions or attributes to «outputOf».
 
 
 
This is not the same as testing whether something is in the outputs attribute of the specified item, which is one of the main things that makes this option very useful. For example, you can find objects that use specific system functions, even though system functions don't have outputs attributes set (with a few exceptions). 
 
 
 
It will also find objects that are in the output attribute of the indicated object.
 
 
 
=== inputOf  ===
 
Finds objects that are used by the items listed in «inputOf». You should specify handles to, or textual names of variables, functions or attributes to «inputOf».
 
 
 
=== caseSensitive ===
 
Controls whether «regExp» is case-sensitive. By default, it is case-insensitive.
 
  
 
== Examples ==
 
== Examples ==
  
 
=== Objects matching specific text ===
 
=== Objects matching specific text ===
 
+
Find all objects having the text "Bacteria" anywhere within any text attribute (including [[Identifier]], [[Units]], [[Title]], [[Description]], [[Definition]], and [[User-defined attributes]]). The match is case insensitive.
Find all objects having the text "Bacteria" anywhere within any textual attribute (such as [[Identifier]], [[Units]], [[Title]], [[Description]], [[Definition]], [[User-defined attributes]], etc.). The match is case insensitive.
+
:<code>#FindObjects("Bacteria")</code>
:<code>#[[FindObjects]]("Bacteria")</code>
 
  
 
Find all objects with an identifier that starts with the prefix "Hydro_". The <code>^</code> character is the [[regular expression]] code for beginning-of-text, which prevents a match to "Cost_of_hydro_power".
 
Find all objects with an identifier that starts with the prefix "Hydro_". The <code>^</code> character is the [[regular expression]] code for beginning-of-text, which prevents a match to "Cost_of_hydro_power".
:<code>#[[FindObjects]]("^Hydro_",[[Identifier]])</code>
+
:<code>#FindObjects("^Hydro_", Identifier)</code>
  
 
You can equivalently quote the attribute name, or compute it:
 
You can equivalently quote the attribute name, or compute it:
:<code>[[Var]] att := "Identifier" Do #FindObjects("^Hydro_", att)</code>
+
:<code>Local att := "Identifier" Do #FindObjects("^Hydro_", att)</code>
  
 
Find objects that have both the words "plant" and "animal" within its textual attributes. An object matches if each word appears in a different attribute, for example, "plant" in the [[Title]], and "animal" in the [[Description]]. Notice that when using a [[Set Functions]] to combine criteria, you don't de-reference the result of [[FindObjects]] before passing it to the set function.
 
Find objects that have both the words "plant" and "animal" within its textual attributes. An object matches if each word appears in a different attribute, for example, "plant" in the [[Title]], and "animal" in the [[Description]]. Notice that when using a [[Set Functions]] to combine criteria, you don't de-reference the result of [[FindObjects]] before passing it to the set function.
:<code>#[[SetUnion]]([[[FindObjects]]("plant"), [[FindObjects]]("animal")])</code>
+
:<code>#SetUnion([FindObjects("plant"), FindObjects("animal")])</code>
  
 
Find objects that have [[Units]] of "mph" or "miles per hour", which do not have a divide operator (/) in the [[Definition]].
 
Find objects that have [[Units]] of "mph" or "miles per hour", which do not have a divide operator (/) in the [[Definition]].
:<code>#[[SetDifference]]([[FindObjects]]("(mph)|(miles per hour)", Units), [[FindObjects]]("/", Definition))</code>
+
:<code>#SetDifference(FindObjects("(mph)|(miles per hour)", Units), FindObjects("/", Definition))</code>
  
 
Find objects in which "lumina" appears in a textual attribute without being capitalized (it is a proper noun, so should be capitalized). It uses the [[regular expression]] control <code>'\b</code> to match word-boundaries, so that words like "illumination" that contain the character sequence inside the word is not matched. The search is case-sensitive so that properly capitalized instances of "Lumina" are not included.
 
Find objects in which "lumina" appears in a textual attribute without being capitalized (it is a proper noun, so should be capitalized). It uses the [[regular expression]] control <code>'\b</code> to match word-boundaries, so that words like "illumination" that contain the character sequence inside the word is not matched. The search is case-sensitive so that properly capitalized instances of "Lumina" are not included.
:<code>#[[FindObjects]]( "\blumina\b", [[#caseSensitive|caseSensitive]]: True)</code>
+
:<code>#FindObjects("\blumina\b", caseSensitive: True)</code>
  
 
Find objects having the text "Power" in either the [[Identifier]] on [[Title]]. This uses named-calling syntax, but the positional syntax (with three parameters) would also work.
 
Find objects having the text "Power" in either the [[Identifier]] on [[Title]]. This uses named-calling syntax, but the positional syntax (with three parameters) would also work.
:<code>#[[FindObjects]](regExp: "Power", attribute: Identifier, Title)</code>
+
:<code>#FindObjects(regExp: "Power", attribute: Identifier, Title)</code>
  
 
Find objects having the text "Dynamic" in any textual attribute other than the [[Definition]].
 
Find objects having the text "Dynamic" in any textual attribute other than the [[Definition]].
:<code>#[[FindObjects]]("Dynamic", [[#excludeAttribute|excludeAttribute]]:Definition)</code>
+
:<code>#FindObjects("Dynamic", excludeAttribute]: Definition)</code>
  
 
The variable <code>Words</code> contains a vector of words, indexed by the index <code>Word_idx</code>. The variable <code>Attr_to_search</code> contains a list of attribute names, computed using [[Subset]]. Find objects having any of the indicated words in any of the indicated attributes. Only full words are matched (by use of the [[regular expression]] <code>'\b'), but the match is case insensitive. The full list of attributes from <code>Attr_to_search</code> is passed to the «attribute» parameter by using [[Repeated parameter forwarding]] (the <code>...</code>).  
 
The variable <code>Words</code> contains a vector of words, indexed by the index <code>Word_idx</code>. The variable <code>Attr_to_search</code> contains a list of attribute names, computed using [[Subset]]. Find objects having any of the indicated words in any of the indicated attributes. Only full words are matched (by use of the [[regular expression]] <code>'\b'), but the match is case insensitive. The full list of attributes from <code>Attr_to_search</code> is passed to the «attribute» parameter by using [[Repeated parameter forwarding]] (the <code>...</code>).  
:<code>#[[SetUnion]](FindObjects('\b' & Words & '\b', attribute: ...Attr_to_search), Word_idx)</code>
+
:<code>#SetUnion(FindObjects('\b' & Words & '\b', attribute: ...Attr_to_search), Word_idx)</code>
  
 
Building on the previous example, but passing <code>Attr_to_search</code> without [[Repeated parameter forwarding]], we end up with a list of results, one for each attribute, since array-abstraction kicks in on the list of attributes. So for example, if <code>Attr_to_search</code> has the value <code>["Title", "Description", "Help"]</code>, the result is an array of three elements, the first having objects in whose [[Title]] attribute contains one of the words, the second cell has objects whose [[Description]] contains one of the words, etc. An important point here is that we cannot de-reference the result, because the result is collection of sets. Dereferencing would attempt to combine  
 
Building on the previous example, but passing <code>Attr_to_search</code> without [[Repeated parameter forwarding]], we end up with a list of results, one for each attribute, since array-abstraction kicks in on the list of attributes. So for example, if <code>Attr_to_search</code> has the value <code>["Title", "Description", "Help"]</code>, the result is an array of three elements, the first having objects in whose [[Title]] attribute contains one of the words, the second cell has objects whose [[Description]] contains one of the words, etc. An important point here is that we cannot de-reference the result, because the result is collection of sets. Dereferencing would attempt to combine  
::<code>SetUnion(FindObjects(Words, attribute: Attr_to_search), Word_idx)</code>
+
:<code>SetUnion(FindObjects(Words, attribute: Attr_to_search), Word_idx)</code>
  
 
To find all objects with no [[Definition]], you will need to use the «value» parameter.
 
To find all objects with no [[Definition]], you will need to use the «value» parameter.
:<code>FindObjects([[#value|value]]:Null, [[#attribute|attribute]:Definition)</code>
+
:<code>FindObjects(value: Null, attribute: Definition)</code>
  
 
=== Objects of a certain type ===
 
=== Objects of a certain type ===
  
 
Any of these three variations can be used to find all [[User-defined functions]].
 
Any of these three variations can be used to find all [[User-defined functions]].
:<code>#[[FindObjects]]( class:Function )</code>
+
:<code>#FindObjects(class: Function)</code>
:<code>#[[FindObjects]]( class:"Function" )</code>
+
:<code>#FindObjects(class: "Function")</code>
:<code>#[[FindObjects]]( class: [[Handle]](Function) )</code>
+
:<code>#FindObjectsclass: Handle(Function))</code>
  
 
Find all non-linked libraries.
 
Find all non-linked libraries.
:<code>#[[FindObjects]]( class: "Library" )</code>
+
:<code>#FindObjects(class: "Library")</code>
  
 
Find all libraries, whether linked or non-linked.
 
Find all libraries, whether linked or non-linked.
:<code>#[[FindObjects]]( class: Library, LinkLibrary )</code>
+
:<code>#FindObjects(class: Library, LinkLibrary)</code>
  
 
Find all modules or libraries. In this example, <code>ModuleTypes</code> is a separate constant node in your model. Notice that [[Repeated Parameter Forwarding]] is used here to pass the full list of modules as a single call, without array-iterating over them.  
 
Find all modules or libraries. In this example, <code>ModuleTypes</code> is a separate constant node in your model. Notice that [[Repeated Parameter Forwarding]] is used here to pass the full list of modules as a single call, without array-iterating over them.  
 
<div id="ModuleTypes">
 
<div id="ModuleTypes">
:<code>Constant ModuleTypes := [ "Module", "LinkModule", "Model", "Library", "LinkLibrary", "Form" ] </code>
+
:<code>Constant ModuleTypes := ["Module", "LinkModule", "Model", "Library", "LinkLibrary", "Form"] </code>
 
</div>
 
</div>
:<code>#[[FindObjects]]( class: ...ModuleTypes )</code>
+
:<code>#FindObjects(class: ...ModuleTypes)</code>
 
You could also allow array-abstraction to iterate, returning the matches to each module type, and then combine the results using [[SetUnion]].
 
You could also allow array-abstraction to iterate, returning the matches to each module type, and then combine the results using [[SetUnion]].
:<code>#[[SetUnion]]( [[FindObjects]](class:ModuleTypes), ModuleTypes )</code>
+
:<code>#SetUnion(FindObjects(class: ModuleTypes), ModuleTypes)</code>
  
 
Find all built-in system functions or system variables that contain the characters "sample" in the [[Identifier]]. Note that built-in objects are normally excluded from searches unless you specify the class explicitly.
 
Find all built-in system functions or system variables that contain the characters "sample" in the [[Identifier]]. Note that built-in objects are normally excluded from searches unless you specify the class explicitly.
:<code>#[[FindObjects]]( "sample", Identifier, class: SysFunction, SysVar )</code>
+
:<code>#FindObjects("sample", Identifier, class: SysFunction, SysVar)</code>
  
 
Find all non-module objects in your model. This uses the <code>ModuleTypes</code> from a previous example a few lines above.
 
Find all non-module objects in your model. This uses the <code>ModuleTypes</code> from a previous example a few lines above.
:<code>#[[FindObjects]]( excludeClass: ...ModuleTypes )</code>
+
:<code>#FindObjects(excludeClass: ...ModuleTypes)</code>
  
 
=== Objects with a certain value ===
 
=== Objects with a certain value ===
  
 
Find all variables having a result value of 1.2 in any cell of the computed result. The search examines all mid- and sample- values that have been previously computed, but does not cause any variable to be computed in order to access its result. Any object having 1.2 in any cell of its result is returned.
 
Find all variables having a result value of 1.2 in any cell of the computed result. The search examines all mid- and sample- values that have been previously computed, but does not cause any variable to be computed in order to access its result. Any object having 1.2 in any cell of its result is returned.
:<code>#[[FindObjects]](value: 1.2)</code>
+
:<code>#FindObjects(value: 1.2)</code>
  
 
==== NaNs in the result ====
 
==== NaNs in the result ====
  
 
Find all variables having a [[NaN]] in any cell of the computed result. Take note that this only searches results that have been previously computed. It searches both mid-value and sample-value results. It is possible you might see a [[NaN]] a statistical view, such as for the [[SDeviation|standard deviation]] when there is fewer that 2 numbers in the sample, even though the [[sample]] contains no [[NaN]]s. In such a case, the object is not included, since the [[NaN]] must appear in the sample itself.
 
Find all variables having a [[NaN]] in any cell of the computed result. Take note that this only searches results that have been previously computed. It searches both mid-value and sample-value results. It is possible you might see a [[NaN]] a statistical view, such as for the [[SDeviation|standard deviation]] when there is fewer that 2 numbers in the sample, even though the [[sample]] contains no [[NaN]]s. In such a case, the object is not included, since the [[NaN]] must appear in the sample itself.
:<code>#[[FindObjects]]([[#value|value]]: NaN)</code>
+
:<code>#FindObjects(value: NaN)</code>
  
 
When searching for the origin of [[NaN]]s in your model, it can be useful to limit the search to variables upstream from the variable you are looking at with has [[NaN]]s in it. Suppose that variable is <code>X</code>. You must use the [[Handle]] function when passing <code>X</code>, otherwise you'd be passing the result of <code>X</code> to the «influences» parameter.
 
When searching for the origin of [[NaN]]s in your model, it can be useful to limit the search to variables upstream from the variable you are looking at with has [[NaN]]s in it. Suppose that variable is <code>X</code>. You must use the [[Handle]] function when passing <code>X</code>, otherwise you'd be passing the result of <code>X</code> to the «influences» parameter.
:<code>#[[FindObjects]](value: NaN, influences: Handle(X))</code>
+
:<code>#FindObjects(value: NaN, influences: Handle(X))</code>
  
 
=== Finding upstream or downstream variables ===
 
=== Finding upstream or downstream variables ===
  
 
Find all the objects (variables and [[user-defined functions]]) that influence <code>Revenue</code> directly or indirectly. You must use the [[Handle]] function to specify the variable (or you can specify its textual name), otherwise it will evaluate <code>Revenue</code> and try to use its result (which would cause an error, since it doesn't evaluate to a handle). The result does not include <code>X</code> itself, unless it does depend on itself through a [[Dynamic]] or [[Iterate]].
 
Find all the objects (variables and [[user-defined functions]]) that influence <code>Revenue</code> directly or indirectly. You must use the [[Handle]] function to specify the variable (or you can specify its textual name), otherwise it will evaluate <code>Revenue</code> and try to use its result (which would cause an error, since it doesn't evaluate to a handle). The result does not include <code>X</code> itself, unless it does depend on itself through a [[Dynamic]] or [[Iterate]].
:<code>#[[FindObjects]]( [[#influences|influences]]: Handle(Revenue))</code>
+
:<code>#FindObjects(influences: Handle(Revenue))</code>
  
Find all objects that are upstream of variable <code>Y/code>, but downstream from variable <code>X</code>.  
+
Find all objects that are upstream of variable <code>Y</code>, but downstream from variable <code>X</code>.  
:<code>#[[FindObjects]]([[#influences|influences]]: [[Handle]](Y), [[#influencedBy|influencedBy]]: Handle(X))</code>
+
:<code>#FindObjects(influences: Handle(Y), influencedBy: Handle(X))</code>
  
 
Find the objects that depend on <code>X</code> and influence <code>Y</code>, and include <code>X</code> and <code>Y</code> in the result.
 
Find the objects that depend on <code>X</code> and influence <code>Y</code>, and include <code>X</code> and <code>Y</code> in the result.
:<code>#[[FindObjects]]([[#influences|influences]]: Handle(Y), [[#influencedBy|influencedBy]]: [[Handle]](X), [[#inclusive|inclusive]]:true )</code>
+
:<code>#FindObjects(influences: Handle(Y), influencedBy: Handle(X), inclusive: true)</code>
  
 
Find all variables in the same [[Dynamic]] loop at <code>X</code>.
 
Find all variables in the same [[Dynamic]] loop at <code>X</code>.
<code>#[[FindObjects]]([[#influences|influences]]: Handle(X), [[#influencedBy|influencedBy]]: [[Handle]](X))</code>
+
<code>#FindObjects(influences: Handle(X), influencedBy: Handle(X))</code>
  
 
=== Finding objects that use a function or variable ===
 
=== Finding objects that use a function or variable ===
  
 
Find all variables that use the function [[DbQuery]]:
 
Find all variables that use the function [[DbQuery]]:
:<code>#FindObjects([[#outputOf|outputOf]]:"DbQuery")</code>
+
:<code>#FindObjects(outputOf: "DbQuery")</code>
The following also finds all variables and functions that use the function [[DbQuery]], but the variable containing this call to [[FindObject]] will also be included in the result.
+
The following also finds all variables and functions that use the function [[DbQuery]], but the variable containing this call to [[FindObjects]] will also be included in the result.
:<code>FindObjects([[#outputOf|outputOf]]:[[Handle]](DbQuery))</code>
+
:<code>FindObjects(outputOf: Handle(DbQuery))</code>
 +
 
 
The search <code>FindObjects("DbQuery")</code> would also find these variables, but it would also find objects where the text <code>"DbQuery"</code> appears in comments, quotes, or in textual attributes like [[Description]]. The «outputOf» search criteria limits the results to cases where an expression makes use of the indicated object.
 
The search <code>FindObjects("DbQuery")</code> would also find these variables, but it would also find objects where the text <code>"DbQuery"</code> appears in comments, quotes, or in textual attributes like [[Description]]. The «outputOf» search criteria limits the results to cases where an expression makes use of the indicated object.
  
 
Find all variables that are immediate children of <code>Gas_price</code> (e.g., that reference <code>Gas_Price</code> in their definition).
 
Find all variables that are immediate children of <code>Gas_price</code> (e.g., that reference <code>Gas_Price</code> in their definition).
:<code>FindObjects([[#outputOf|outputOf]]: Handle(Gas_price))</code>
+
:<code>FindObjects(outputOf: Handle(Gas_price))</code>
  
 
Find all variables in the same [[dynamic loop]] as <code>X</code> which have a [[Dynamic]] definition.
 
Find all variables in the same [[dynamic loop]] as <code>X</code> which have a [[Dynamic]] definition.
:<code>FindObjects([[#influences|influences]]:X, [[#influencedBy|influencedBy]]: X, [[#inclusive|inclusive]]: true, [[#outputOf|outputOf]]: Handle(Dynamic))</code>
+
:<code>FindObjects(influences: X, influencedBy: X, inclusive: true, outputOf: Handle(Dynamic))</code>
  
The inverse of «outputOf» is «inputOf». Find all immediate parents of X.
+
The inverse of «outputOf» is «inputOf». Find all immediate parents of <code>X</code>.
:<code>FindObjects( [[#inputOf|inputOf]]: X)</code>
+
:<code>FindObjects(inputOf: X)</code>
  
Find all the system functions or system variables that are used by the variable X.
+
Find all the system functions or system variables that are used by the variable <code>X</code>.
:<code>FindObjects([[#inputOf|inputOf]]: X, [[#class|class]]: SysVar, SysFunction)</code>
+
:<code>FindObjects(inputOf: X, class: SysVar, SysFunction)</code>
  
 
=== Finding objects by locations within module hierarchy ===
 
=== Finding objects by locations within module hierarchy ===
Line 204: Line 213:
 
:<code>#FindObjects(withinAny: Handle(Sensitivity_analysis), excludeClass: ...ModuleTypes)</code>
 
:<code>#FindObjects(withinAny: Handle(Sensitivity_analysis), excludeClass: ...ModuleTypes)</code>
  
Find all the parent and ancestor modules (not following aliased modules) of x.
+
Find all the parent and ancestor modules (not following aliased modules) of <code>x</code>.
 
:<code>#FindObjects(contains: Handle(x))</code>
 
:<code>#FindObjects(contains: Handle(x))</code>
Find all parent and ancestor modules, including module aliases and their parents, of x.
+
Find all parent and ancestor modules, including module aliases and their parents, of <code>x</code>.
 
:<code>#FindObjects(containsAny: Handle(x))</code>
 
:<code>#FindObjects(containsAny: Handle(x))</code>
  
Find the common modules of X and Y. In other words, those modules that have both X and Y somewhere within their module hierarchy. X and Y may be in different modules.
+
Find the common modules of <code>X</code> and <code>Y</code>. In other words, those modules that have both <code>X</code> and <code>Y</code> somewhere within their module hierarchy. <code>X</code> and <code>Y</code> may be in different modules.
 
:<code>#FindObjects(contains: X, Y)</code>
 
:<code>#FindObjects(contains: X, Y)</code>
  
Line 234: Line 243:
 
:<code>#SetUnion(FindObjects(hasUserInput: true, influences: Handle(Y)), FindObjects(isLiteral: true, influences: Handle(Y))</code>
 
:<code>#SetUnion(FindObjects(hasUserInput: true, influences: Handle(Y)), FindObjects(isLiteral: true, influences: Handle(Y))</code>
  
== Using with FoundSet ==
+
== FoundSet to tag nodes on a Diagram ==
[[FindObjects]] can be useful for tracing dependencies across modules. While debugging, you may want to find all the objects between <code>X</code> and <code>Y</code>, but because these two variables are in different modules, and the variables between them are in a variety of modules, it can be hard to see which variables are on the path of interest.  
+
 
 +
You can use the system variable <code>Sys_FoundSet</code> to identify results from FindObjects (or any set of objects) by tagging their nodes with a magnifying glass icon in their Diagrams, and in the Outline view. You can also step through the variable using  "Find Next" option from the Object menu, or press ''ctrl+G'', to step through the variables. This can be very helpful while debugging to trace how one variable influences another across several diagrams, for example:
 +
 
 +
:[[image:Found_Set_Sales_model_details.png|frame|center|The Found Set depicts all variables on the path(s) from <code>Demand_growth_rate</code> to <code>Dollar_sales_by_product</code> using magnifying glass icons.]]
 +
 
 +
<code>Sys_FoundSet</code> normally contains a list of the objects found from the last time you used the [[Find dialog]].  You can also assign a result from FindObjects to <code>Sys_FoundSet</code> in a Button [[OnClick]] attribute. For example,
  
To create a visual depiction on the influence diagram, you can assign the result of [[FindObjects]] to the system variable <code>Sys_FoundSet</code>. This is a system variable that normally contains the result of a "Find" (and which the "Find Next" menu command steps through). Once you assign the result of [[FindObjects]] to <code>Sys_FoundSet</code>, you can use "Find Next" (''Ctrl+G'') to visit each node on the path, although the order of visitation will be arbitrary. You can assign to this system variable either in a button [[OnClick]] event, on from the typescript window, but you cannot assign to it from a variable, since that would constitute a side-effect. So, for example, you would press ''F12'' to open the [[Typescript Window]], and type:
+
:<code>Sys_FoundSet := FindObjects(influencedBy: "Demand_growth_rate", influences: "Dollar_sales_by_prod", inclusive: true);</code>
  
:<code>(Sys_FoundSet := [[FindObjects]]( [[#influencedBy|influencedBy]]:"Demand_growth_rate", [[#influences|influences]]:"Dollar_sales_by_prod", [[#inclusive|inclusive]]:true) )</code>
+
To show the magnifying glass tags, you must also set the system variable <code>DepictFoundSetOnUI</code> to 1:
  
Next, you must set the system variable <code>DepictFoundSetOnUI</code> to enable the graphical depiction of the found set on the UI. Objects in the found set will appear in various places on the UI with a magnifying glass icon. In typescript:
+
:<code>DepictFoundSetOnUI := 1</code>
:<code>(DepictFoundSetOnUI := 1)</code>
 
  
:[[image:Found_Set_Sales_model_details.png|frame|center|The Found Set depicts all variables on the path(s) from <code>Demand_growth_rate</code> to <code>Dollar_sales_by_product</code> using magnifying glass icons.]]
+
(If you make these assignments in a [[Typescript Window]], you must enclose each assignment in parentheses, in line with [[Typescript]] syntax.)
  
 
==History==
 
==History==
Introduced in [[Analytica 4.7]].
+
Introduced in [[Analytica 5.0]].
  
 
== See Also ==
 
== See Also ==
 
* [[Meta-inference]]
 
* [[Meta-inference]]
 
* [[Regular Expressions]]
 
* [[Regular Expressions]]
 +
* [[SetUnion]]
 
* [[Set Functions]]
 
* [[Set Functions]]
 
* [[Handle]]
 
* [[Handle]]
 
* [[Reference]]
 
* [[Reference]]
 +
* [[DbQuery]]

Revision as of 18:08, 24 May 2021

new to Analytica 5.0

FindObjects is a powerful function that searches a model to find objects that match specified criteria. For example, FindObjects('$', Units) returns a set of variables whose 'Units' attribute contains '$'. Among the vast number of criteria you can specify are the search text, the attribute(s) to search and class(s) of object to search (or exclude), what values it contains, which modules to search, variables that influence or are influenced by a variable, or whether an object has user inputs or outputs. For more complex searches, you can combine its results using set operations.

FindObjects() returns a set

The result from FindObjects is a Set -- i.e. a reference to a list of handles to the objects found. So if you want the list of objects, you should preface the function name with the de-reference operator (#), e.g.:

#FindObjects("Cost", Identifier) → [Cost_of_gasoline, Cost_of_diesel, Levelized_cost]

This example returns a list of variables whose identifiers contain "Cost".

Since FindObjects() returns a set, you can use it directly in functions like SetUnion, SetDifference and SetIntersection to combine search criteria -- for example,

#SetUnion([FindObjects('$', Units), FindObjects('₤', Units)])

returns a list of all objects whose Units contain '$' or '₤'.

The function fully supports Intelligent Arrays, meaning it works if any parameter is an array. In that case the results will be an array of sets of search result. Each cell of the array will be a reference to a list that is the result of a distinct search. You cannot dereference the result when the result might be an array of searches, so you shouldn't apply the # operator, unless you know that it returns only a single set.

FindObjects(regExp, attribute..., excludeAttribute..., class..., excludeClass..., value, influences..., influencedBy..., inclusive, within..., withinAny..., contains..., containsAny..., hasUserInput, hasUserOutput, hasInput, hasOutput, isLiteral, outputOf..., inputOf..., caseSensitive)

FindObjects has a huge number of parameters, but all are optional. You should specify at least one parameter unless you want the set of all user-defined objects. It's simplest to use name-based calling syntax for all parameters except optionally the one or two, «regExp» and «attribute»,

Many parameters can be repeated (denoted by ... in the parameter list). For example, you can specify a list of classes and attributes. It returns the union of all objects that match. So,FindObjects('Possible', attribute: Title, Description, Class: Decision, Chance) returns any Decision and Chance objects that have a Title or Description that contains 'Possible'.

A variable using FindObjects() does not update automatically when relevant attributes change or objects are created or deleted. (Analytica's flow architecture (automatic consistency maintenance) propagates changes only from Definitions and Values to other Variables that depend on them, not from other Attributes.) That means you must explicitly cause FindObjects() to recompute if you want to reflect any changes to the objects it may search.

regExp

This first parameters specifies text to search for. It returns a list of objects containing any attribute (or specified attribute) that contains this text value. The match is case insensitive by default. This parameter may also be a regular expression (hence its name) containing wild-cards, special characters, and more for more complex matching.

attribute

By default, FindObjects searches every user-defined attribute of each object. Or you can use this parameters to specify one or more specific attributes in which to match the «searchText» or «value». The search result doesn't include information about which attribute matched.

caseSensitive

Set to True (1) or False (0) to control whether «regExp» is case-sensitive. By default, it is case-insensitive (False).

excludeAttribute

One or more attributes to be excluded from the match.

class

Specify one or more classes of object to search, such as Variable, Objective, Function, Module, or SysFunction. It returns objects of only the specified class(es). If not specified, it searches all user-defined object classes, but not classes of built-in objects, like SysFunction and SysVar. If you specify Any, it searches all object classes, both user and built-in.

excludeClass

One of more object classes to exclude.

value

An atomic value to find. It returns any computed variable that has a matching value as its atomic value or as a cell in its array or table value (deterministic Value or Probvalue). You can search for NaN or Null. It will not find a match unless the value has been computed.

outputOf

Find objects, usually, Variables, Functions, and Buttons, that use the object(s) listed in «outputOf». Use a handle to each object, or its identifier as a text value. Don't just use the variable's identifier directly, because it will try to evaluate it -- e.g.

FindObjects(outputOf: Handle(X), 'Y') not: FindObjects(outputOf: X, Y)

It finds Variables and Functions that mention the object(s) X in their Definitions. Unlike the simple attribute access Outputs OF X, it also finds any Button that uses X in its Onclick attribute or any variable that uses X in its OnChange or Check attribute. It even finds Objects that use a system function or system variable. In these ways, it is more general that the Outputs attribute.

inputOf

Finds objects that are used by the objects listed in «inputOf». As with «outputOf», you should provide a handle to each variable or other object (or its identifier as text) -- and "uses" covers OnClick, OnChange, and Check attributes.

influencedBy

Finds all downstream variables, functions and buttons that are influenced by the specified object(s), directly (as in their OutputOf, above), or indirectly, via other variables or functions. As with «outputOf», you should provide a handle to each variable or other object (or its identifier as text) and "influence" includes effects via OnClick, OnChange, and Check, as well as Definition attributes.

influences

Finds all upstream variables, functions and buttons that influence the specified object(s), directly (as in their InputsOf, above), or indirectly, via other variables or functions. As with «outputOf», you should provide a handle to each variable or other object (or its identifier as text) and "influence" includes effects via OnClick, OnChange, and Check, as well as Definition attributes.

inclusive

Boolean. By default FindObjects(influences: x) does not include x itself. When «inclusive» is true, it includesx in its result. This also applies to parameters «influencedBy», «within», «withinAny», «contains» and «containsAny».

within

When you specify one or more modules, it searches only objects within those modules (and their submodules).

withinAny

Same as «within», but it also includes objects that are inside the specified module(s) only as a result of a module alias being inside the module.

contains

Searches among modules that contain any of the objects specified in «contains».

containsAny

Same as «contains», except that it also includes modules that contain an alias that contains the indicates object(s).

hasUserInput

When true, it returns only objects that have a user input node. When false, it returns only objects that have no user input.

hasUserOutput

When true, it returns only objects that have a user output node. When false, it returns only objects that have no user output.

hasInput

When true, it returns only objects that depend on at least one other variable. When false, returns objects that have no Inputs.

hasOutput

When true, it returns objects that have at least one Output variable or function. When false, returns only objects with no Outputs.

isLiteral

When true, it returns objects that contain only literals (explicit numbers, text, etc.) or are defined as a table with only literals in the cells, but contain no expressions, and refer to no variables other than the Index variables for the table dimensions.

Examples

Objects matching specific text

Find all objects having the text "Bacteria" anywhere within any text attribute (including Identifier, Units, Title, Description, Definition, and User-defined attributes). The match is case insensitive.

#FindObjects("Bacteria")

Find all objects with an identifier that starts with the prefix "Hydro_". The ^ character is the regular expression code for beginning-of-text, which prevents a match to "Cost_of_hydro_power".

#FindObjects("^Hydro_", Identifier)

You can equivalently quote the attribute name, or compute it:

Local att := "Identifier" Do #FindObjects("^Hydro_", att)

Find objects that have both the words "plant" and "animal" within its textual attributes. An object matches if each word appears in a different attribute, for example, "plant" in the Title, and "animal" in the Description. Notice that when using a Set Functions to combine criteria, you don't de-reference the result of FindObjects before passing it to the set function.

#SetUnion([FindObjects("plant"), FindObjects("animal")])

Find objects that have Units of "mph" or "miles per hour", which do not have a divide operator (/) in the Definition.

#SetDifference(FindObjects("(mph)|(miles per hour)", Units), FindObjects("/", Definition))

Find objects in which "lumina" appears in a textual attribute without being capitalized (it is a proper noun, so should be capitalized). It uses the regular expression control '\b to match word-boundaries, so that words like "illumination" that contain the character sequence inside the word is not matched. The search is case-sensitive so that properly capitalized instances of "Lumina" are not included.

#FindObjects("\blumina\b", caseSensitive: True)

Find objects having the text "Power" in either the Identifier on Title. This uses named-calling syntax, but the positional syntax (with three parameters) would also work.

#FindObjects(regExp: "Power", attribute: Identifier, Title)

Find objects having the text "Dynamic" in any textual attribute other than the Definition.

#FindObjects("Dynamic", excludeAttribute]: Definition)

The variable Words contains a vector of words, indexed by the index Word_idx. The variable Attr_to_search contains a list of attribute names, computed using Subset. Find objects having any of the indicated words in any of the indicated attributes. Only full words are matched (by use of the regular expression '\b'), but the match is case insensitive. The full list of attributes from Attr_to_search is passed to the «attribute» parameter by using Repeated parameter forwarding (the ...).

#SetUnion(FindObjects('\b' & Words & '\b', attribute: ...Attr_to_search), Word_idx)

Building on the previous example, but passing Attr_to_search without Repeated parameter forwarding, we end up with a list of results, one for each attribute, since array-abstraction kicks in on the list of attributes. So for example, if Attr_to_search has the value ["Title", "Description", "Help"], the result is an array of three elements, the first having objects in whose Title attribute contains one of the words, the second cell has objects whose Description contains one of the words, etc. An important point here is that we cannot de-reference the result, because the result is collection of sets. Dereferencing would attempt to combine

SetUnion(FindObjects(Words, attribute: Attr_to_search), Word_idx)

To find all objects with no Definition, you will need to use the «value» parameter.

FindObjects(value: Null, attribute: Definition)

Objects of a certain type

Any of these three variations can be used to find all User-defined functions.

#FindObjects(class: Function)
#FindObjects(class: "Function")
#FindObjectsclass: Handle(Function))

Find all non-linked libraries.

#FindObjects(class: "Library")

Find all libraries, whether linked or non-linked.

#FindObjects(class: Library, LinkLibrary)

Find all modules or libraries. In this example, ModuleTypes is a separate constant node in your model. Notice that Repeated Parameter Forwarding is used here to pass the full list of modules as a single call, without array-iterating over them.

Constant ModuleTypes := ["Module", "LinkModule", "Model", "Library", "LinkLibrary", "Form"]
#FindObjects(class: ...ModuleTypes)

You could also allow array-abstraction to iterate, returning the matches to each module type, and then combine the results using SetUnion.

#SetUnion(FindObjects(class: ModuleTypes), ModuleTypes)

Find all built-in system functions or system variables that contain the characters "sample" in the Identifier. Note that built-in objects are normally excluded from searches unless you specify the class explicitly.

#FindObjects("sample", Identifier, class: SysFunction, SysVar)

Find all non-module objects in your model. This uses the ModuleTypes from a previous example a few lines above.

#FindObjects(excludeClass: ...ModuleTypes)

Objects with a certain value

Find all variables having a result value of 1.2 in any cell of the computed result. The search examines all mid- and sample- values that have been previously computed, but does not cause any variable to be computed in order to access its result. Any object having 1.2 in any cell of its result is returned.

#FindObjects(value: 1.2)

NaNs in the result

Find all variables having a NaN in any cell of the computed result. Take note that this only searches results that have been previously computed. It searches both mid-value and sample-value results. It is possible you might see a NaN a statistical view, such as for the standard deviation when there is fewer that 2 numbers in the sample, even though the sample contains no NaNs. In such a case, the object is not included, since the NaN must appear in the sample itself.

#FindObjects(value: NaN)

When searching for the origin of NaNs in your model, it can be useful to limit the search to variables upstream from the variable you are looking at with has NaNs in it. Suppose that variable is X. You must use the Handle function when passing X, otherwise you'd be passing the result of X to the «influences» parameter.

#FindObjects(value: NaN, influences: Handle(X))

Finding upstream or downstream variables

Find all the objects (variables and user-defined functions) that influence Revenue directly or indirectly. You must use the Handle function to specify the variable (or you can specify its textual name), otherwise it will evaluate Revenue and try to use its result (which would cause an error, since it doesn't evaluate to a handle). The result does not include X itself, unless it does depend on itself through a Dynamic or Iterate.

#FindObjects(influences: Handle(Revenue))

Find all objects that are upstream of variable Y, but downstream from variable X.

#FindObjects(influences: Handle(Y), influencedBy: Handle(X))

Find the objects that depend on X and influence Y, and include X and Y in the result.

#FindObjects(influences: Handle(Y), influencedBy: Handle(X), inclusive: true)

Find all variables in the same Dynamic loop at X. #FindObjects(influences: Handle(X), influencedBy: Handle(X))

Finding objects that use a function or variable

Find all variables that use the function DbQuery:

#FindObjects(outputOf: "DbQuery")

The following also finds all variables and functions that use the function DbQuery, but the variable containing this call to FindObjects will also be included in the result.

FindObjects(outputOf: Handle(DbQuery))

The search FindObjects("DbQuery") would also find these variables, but it would also find objects where the text "DbQuery" appears in comments, quotes, or in textual attributes like Description. The «outputOf» search criteria limits the results to cases where an expression makes use of the indicated object.

Find all variables that are immediate children of Gas_price (e.g., that reference Gas_Price in their definition).

FindObjects(outputOf: Handle(Gas_price))

Find all variables in the same dynamic loop as X which have a Dynamic definition.

FindObjects(influences: X, influencedBy: X, inclusive: true, outputOf: Handle(Dynamic))

The inverse of «outputOf» is «inputOf». Find all immediate parents of X.

FindObjects(inputOf: X)

Find all the system functions or system variables that are used by the variable X.

FindObjects(inputOf: X, class: SysVar, SysFunction)

Finding objects by locations within module hierarchy

Find all the non-module objects inside the module Sensitivity_analysis. This uses the constant ModuleTypes that was defined earlier in the examples. This result includes all objects that are inside any sub-module of Sensitivity_analysis, at any depth.

#FindObjects(within: Handle(Sensitivity_analysis), excludeClass: ...ModuleTypes)

Suppose there is a module named Power_generation which is not inside the Sensitivity_analysis module, but an alias of the Power_generation model has been created and placed with the Sensitivity_analysis module. The preceding search using «within» does not include the objects inside the alias module. Find all non-module objects inside Sensitivity_analysis, or any of its submodules or alias submodules, at any depth.

#FindObjects(withinAny: Handle(Sensitivity_analysis), excludeClass: ...ModuleTypes)

Find all the parent and ancestor modules (not following aliased modules) of x.

#FindObjects(contains: Handle(x))

Find all parent and ancestor modules, including module aliases and their parents, of x.

#FindObjects(containsAny: Handle(x))

Find the common modules of X and Y. In other words, those modules that have both X and Y somewhere within their module hierarchy. X and Y may be in different modules.

#FindObjects(contains: X, Y)

Finding model inputs or outputs

Which variable do you consider to be model inputs? The most obvious would be those variables having user input nodes. You can find these using.

#FindObjects(hasUserInput: true)

You might consider an input to be a node with no parents.

#FindObjects(hasInput: false)

but Tables have parents (the indexes), even if all the cells are numbers. So you might want the objects that have only literals in their definitions (text, numbers, null), including tables. This would exclude a table having expressions in their definition or in their table cells.

#FindObjects(isLiteral: true)

Or maybe in addition to these criteria, a variable is only an input when it is actually used by another object.

#FindObjects(isLiteral: true, hasOutput: true)

In a symmetrical fashion, an output might be a variable that has a user output node.

#FindObjects(hasUserOutput: false)

or that has no children of its own.

#FindObjects(hasOutput: false)

Find the inputs that influence the result of Y, using a concept that an input is either an object defined as a literal or table of literals, or is a variable with a user input node.

#SetUnion(FindObjects(hasUserInput: true, influences: Handle(Y)), FindObjects(isLiteral: true, influences: Handle(Y))

FoundSet to tag nodes on a Diagram

You can use the system variable Sys_FoundSet to identify results from FindObjects (or any set of objects) by tagging their nodes with a magnifying glass icon in their Diagrams, and in the Outline view. You can also step through the variable using "Find Next" option from the Object menu, or press ctrl+G, to step through the variables. This can be very helpful while debugging to trace how one variable influences another across several diagrams, for example:

The Found Set depicts all variables on the path(s) from Demand_growth_rate to Dollar_sales_by_product using magnifying glass icons.

Sys_FoundSet normally contains a list of the objects found from the last time you used the Find dialog. You can also assign a result from FindObjects to Sys_FoundSet in a Button OnClick attribute. For example,

Sys_FoundSet := FindObjects(influencedBy: "Demand_growth_rate", influences: "Dollar_sales_by_prod", inclusive: true);

To show the magnifying glass tags, you must also set the system variable DepictFoundSetOnUI to 1:

DepictFoundSetOnUI := 1

(If you make these assignments in a Typescript Window, you must enclose each assignment in parentheses, in line with Typescript syntax.)

History

Introduced in Analytica 5.0.

See Also

Comments


Marksmith

101 months ago
Score 0
Neat. I like how this function makes capturing a list of objects --in a module, ones with characteristics, ones with inputs, ones with outputs, ...-- so much smoother than finding text in (textual) Attributes of objects to construct lists of objects for Sensitivity Analyses, searching for nodes in a model with complicated hierarchy and exploring inputs.

You are not allowed to post comments.