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".
#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.
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.
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.
Set to True (1) or False (0) to control whether «regExp» is case-sensitive. By default, it is case-insensitive (False).
One or more attributes to be excluded from the match.
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.
One of more object classes to exclude.
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.
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.
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.
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.
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.
Boolean. By default
FindObjects(influences: x) does not include
x itself. When «inclusive» is true, it includes
x in its result. This also applies to parameters «influencedBy», «within», «withinAny», «contains» and «containsAny».
When you specify one or more modules, it searches only objects within those modules (and their submodules).
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.
Searches among modules that contain any of the objects specified in «contains».
Same as «contains», except that it also includes modules that contain an alias that contains the indicates object(s).
When true, it returns only objects that have a user input node. When false, it returns only objects that have no user input.
When true, it returns only objects that have a user output node. When false, it returns only objects that have no user output.
When true, it returns only objects that depend on at least one other variable. When false, returns objects that have no Inputs.
When true, it returns objects that have at least one Output variable or function. When false, returns only objects with no Outputs.
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.
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 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".
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.
#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)
#FindObjects(regExp: "Power", attribute: Identifier, Title)
Find objects having the text "Dynamic" in any textual attribute other than the Definition.
#FindObjects("Dynamic", excludeAttribute]: Definition)
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.
Find all non-linked libraries.
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"]
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.
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.
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.
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.
Find all objects that are upstream of variable
Y, but downstream from variable
#FindObjects(influences: Handle(Y), influencedBy: Handle(X))
Find the objects that depend on
X and influence
Y, and include
Y in the result.
#FindObjects(influences: Handle(Y), influencedBy: Handle(X), inclusive: true)
Find all variables in the same Dynamic loop at
#FindObjects(influences: Handle(X), influencedBy: Handle(X))
Finding objects that use a function or variable
Find all variables that use the function DbQuery:
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(influences: X, influencedBy: X, inclusive: true, outputOf: Handle(Dynamic))
The inverse of «outputOf» is «inputOf». Find all immediate parents of
Find all the system functions or system variables that are used by the variable
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
Find all parent and ancestor modules, including module aliases and their parents, of
Find the common modules of
Y. In other words, those modules that have both
Y somewhere within their module hierarchy.
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.
You might consider an input to be a node with no parents.
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.
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.
or that has no children of its own.
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:
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
Introduced in Analytica 5.0.