FindObjects
new to Analytica 5.0
Function FindObjects(text, attribute) returns a set of handles to objects whose specified «attribute» (such as Title or Identifier) contains the specified «text». It has a vast number of optional parameters. You can specify whether the match is case sensitive (default is not)), which attributes and classes of object to includew o exclude from the search, and to search only objects that are inputs or outputs of a variable or contents of a module.
FindObjects() returns a set
The result from FindObjects is set (a reference to a list of handles to the objects found), so you should preface it with the de-reference operator (#), to get the list itself, 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 the result is 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 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 massive number of parameters, all of which 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»,
Many parameters allow repeated elements (denoted by ... in the parameter list). For example, you can specify a list of attributes or a list of Classes. It returns the union of matches -- all objects with any specified attribute that matches of any of the specified classes.
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
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.
caseSensitive
Controls whether «regExp» is case-sensitive. By default, it is case-insensitive.
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, 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.
excludeClass
One of more object classes to exclude.
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.
influences
A list of handles to, or identifiers 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.
influencedBy
A list of handles to, or identifiers of variables. Finds all objects downstream from all variables listed.
inclusive
Boolean. By default FindObjects(influences: x)
does not include x
itself. When «inclusive» is true, then x
is included. This also applies to parameteres «influencedBy», «within», «withinAny», «contains» and «containsAny».
within
When one or more modules is specified, only objects within the indicated modules are searched.
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.
contains
Searches among modules that contain all 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, returns objects that have an input node. When false, objects that have no input node.
hasUserOutput
When true, returns objects that have an output node. When false, objects that have no output node.
hasInput
When true, returns objects that depend on at least one other variable. When false, returns objects that have no dependency parents.
hasOutput
When true, returns objects influence at least one other variable. When false, returns objects with no dependents.
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.
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».
Examples
Objects matching specific text
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.
#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:
Var 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))
Using with FoundSet
FindObjects can be useful for tracing dependencies across modules. While debugging, you may want to find all the objects between X
and Y
, 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.
To create a visual depiction on the influence diagram, you can assign the result of FindObjects to the system variable Sys_FoundSet
. 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 Sys_FoundSet
, 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:
(Sys_FoundSet := FindObjects(influencedBy: "Demand_growth_rate", influences: "Dollar_sales_by_prod", inclusive: true))
Next, you must set the system variable DepictFoundSetOnUI
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:
(DepictFoundSetOnUI := 1)
History
Introduced in Analytica 5.0.
See Also
Enable comment auto-refresher
Marksmith