 <?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.analytica.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Fredbrunt</id>
	<title>Analytica Docs - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.analytica.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Fredbrunt"/>
	<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php/Special:Contributions/Fredbrunt"/>
	<updated>2026-05-25T08:44:42Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.9</generator>
	<entry>
		<id>https://docs.analytica.com/index.php?title=File:AcceptanceTestFiles.png&amp;diff=63452</id>
		<title>File:AcceptanceTestFiles.png</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=File:AcceptanceTestFiles.png&amp;diff=63452"/>
		<updated>2025-11-19T03:56:58Z</updated>

		<summary type="html">&lt;p&gt;Fredbrunt: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Fredbrunt</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=CumMin_and_CumMax&amp;diff=62564</id>
		<title>CumMin and CumMax</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=CumMin_and_CumMax&amp;diff=62564"/>
		<updated>2025-06-03T06:11:34Z</updated>

		<summary type="html">&lt;p&gt;Fredbrunt: /* PassNull */ fixed minor error in example&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''New to [[Analytica 5.3]]''&lt;br /&gt;
&lt;br /&gt;
[[Category:Transforming functions]]&lt;br /&gt;
&lt;br /&gt;
{{ReleaseBar}}&lt;br /&gt;
&lt;br /&gt;
== CumMin(x, I'', passNull, reset{{Release|5.5||, window}}'') ==&lt;br /&gt;
== CumMax(x, I '', passNull, reset{{Release|5.5||, window}}'') ==&lt;br /&gt;
&lt;br /&gt;
Returns an array with each element being the minimum or maximum of all preceding elements of «X» along dimension «I» up to, and including, the corresponding element of «X».&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
:&amp;lt;code&amp;gt;I := &amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;1..7&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;X := &amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;Array(I, [5, 2, 1, 8, -3, 0, 4])&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;CumMin(X, I) &amp;amp;rarr;&amp;lt;/code&amp;gt; &lt;br /&gt;
::&amp;lt;code&amp;gt;[5, 2, 1, 1, -3, -3, -3]&amp;lt;/code&amp;gt;   {indexed by &amp;lt;code&amp;gt;I&amp;lt;/code&amp;gt;}&lt;br /&gt;
:&amp;lt;code&amp;gt;CumMax(X, I) &amp;amp;rarr;&amp;lt;/code&amp;gt; &lt;br /&gt;
::&amp;lt;code&amp;gt;[5, 5, 5, 8, 8, 8, 8]&amp;lt;/code&amp;gt;   {indexed by &amp;lt;code&amp;gt;I&amp;lt;/code&amp;gt;}&lt;br /&gt;
&lt;br /&gt;
== Optional Parameters ==&lt;br /&gt;
=== PassNull ===&lt;br /&gt;
«PassNull» is an optional boolean parameter that defaults to &amp;lt;code&amp;gt;False&amp;lt;/code&amp;gt;. When it is omitted or explicitly set to &amp;lt;code&amp;gt;False&amp;lt;/code&amp;gt;, [[CumProduct]] ignores [[Null]] values.  In that case they have essentially the same effect as a one, unless they happen to be the first value in «X», in which case they are passed since no numeric values are yet obtained.&lt;br /&gt;
&lt;br /&gt;
When «passNull» is explicitly set to true, then [[Null]] values are passed through as [[Null]] in the result.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt; J := 1..11&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;X2 := &amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;Array(J, [Null, Null, 4, 2, Null, Null, 2, -1, 3, 2, Null])&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;CumMin(X2, J) &amp;amp;rarr;&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;[Null, Null, 4, 2, 2, 2, 2, -1, -1, -1, -1]&amp;lt;/code&amp;gt;    { Indexed by &amp;lt;code&amp;gt;J&amp;lt;/code&amp;gt; }&lt;br /&gt;
:&amp;lt;code&amp;gt;CumMin(X2, J, passNull: false) &amp;amp;rarr;&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;[Null, Null, 4, 2, 2, 2, 2, -1, -1, -1, -1]&amp;lt;/code&amp;gt;    { Indexed by &amp;lt;code&amp;gt;J&amp;lt;/code&amp;gt; }&lt;br /&gt;
:&amp;lt;code&amp;gt;CumMin(X2, J, passNull: true) &amp;amp;rarr;&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;[Null, Null, 4, 2, Null, Null, 2, -1, -1, -1, Null]&amp;lt;/code&amp;gt;     { Indexed by &amp;lt;code&amp;gt;J&amp;lt;/code&amp;gt; }&lt;br /&gt;
:&amp;lt;code&amp;gt;CumMax(X2, J, passNull: true) &amp;amp;rarr;&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;[Null, Null, 4, 4, Null, Null, 4, 4, 4, 4, Null]&amp;lt;/code&amp;gt;     { Indexed by &amp;lt;code&amp;gt;J&amp;lt;/code&amp;gt; }&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
The optional «reset» parameter accepts an array of boolean values indexed by «I».  At the positions where «reset» is true, [[CumMin]] or [[CumMax]] starts over.  &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;I := &amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;[1, 2, 3, 4, 5, 6, 7]&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;X := &amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;Array(I, [5, 2, 1, 8, -3, 7, 5])&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;R := &amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;Array(I, [0, 0, 1, 0, 0, 1, 0])&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;CumMin(X, I, reset: R) &amp;amp;rarr;&amp;lt;/code&amp;gt; &lt;br /&gt;
::&amp;lt;code&amp;gt;[5, 2, 1, 1, -3, 7, 5]&amp;lt;/code&amp;gt;                { Indexed by &amp;lt;code&amp;gt;I&amp;lt;/code&amp;gt; }&lt;br /&gt;
:&amp;lt;code&amp;gt;CumMax(X, I, reset: R) &amp;amp;rarr;&amp;lt;/code&amp;gt; &lt;br /&gt;
::&amp;lt;code&amp;gt;[5, 5, 1, 8, 8, 7, 7]&amp;lt;/code&amp;gt;                { Indexed by &amp;lt;code&amp;gt;I&amp;lt;/code&amp;gt; }&lt;br /&gt;
&lt;br /&gt;
«Reset» can be used to restart the progressive min or max each time some state change occurs.  In such a scenario, the «reset» parameter is set to &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; at the first instant (along «I») that the system is in the new state.&lt;br /&gt;
&lt;br /&gt;
=== Window ===&lt;br /&gt;
''New to [[Analytica 6.0]]''&lt;br /&gt;
&lt;br /&gt;
When «window» is specified as a positive integer, does a windowed cum min or cum max. In other words, returns the minimum (or maximum) value among the most recent «window» points.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[Min]], [[Max]]&lt;br /&gt;
* [[Cumulate]], [[CumProduct]]&lt;br /&gt;
* [[Dynamic]]&lt;/div&gt;</summary>
		<author><name>Fredbrunt</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Product&amp;diff=62514</id>
		<title>Product</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Product&amp;diff=62514"/>
		<updated>2025-05-22T14:26:29Z</updated>

		<summary type="html">&lt;p&gt;Fredbrunt: /* Examples */ Minor fix to example con't&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Array-reducing functions]]&lt;br /&gt;
[[Category:Doc Status C]] &amp;lt;!-- For Lumina use, do not change --&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
== Product(X, I) ==&lt;br /&gt;
&lt;br /&gt;
Returns the product of all of the elements of «X», along the dimension indexed by «I».&lt;br /&gt;
&lt;br /&gt;
[[Syntax]]:&lt;br /&gt;
:[[Product]](X: Array[I]; I: Index)&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
:&amp;lt;code&amp;gt;Index I := 1..10&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Product(1 + 1/I, I) &amp;amp;rarr; 11&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[CumProduct]]&lt;br /&gt;
* [[ProductLog]]&lt;br /&gt;
* [[Sum]]&lt;br /&gt;
* [[Array-reducing functions]]&lt;/div&gt;</summary>
		<author><name>Fredbrunt</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Product&amp;diff=62513</id>
		<title>Product</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Product&amp;diff=62513"/>
		<updated>2025-05-22T05:29:50Z</updated>

		<summary type="html">&lt;p&gt;Fredbrunt: /* Examples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Array-reducing functions]]&lt;br /&gt;
[[Category:Doc Status C]] &amp;lt;!-- For Lumina use, do not change --&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
== Product(X, I) ==&lt;br /&gt;
&lt;br /&gt;
Returns the product of all of the elements of «X», along the dimension indexed by «I».&lt;br /&gt;
&lt;br /&gt;
[[Syntax]]:&lt;br /&gt;
:[[Product]](X: Array[I]; I: Index)&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
:&amp;lt;code&amp;gt;Index I := 1..10&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Product(1 + 1/I, J) &amp;amp;rarr; 11&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[CumProduct]]&lt;br /&gt;
* [[ProductLog]]&lt;br /&gt;
* [[Sum]]&lt;br /&gt;
* [[Array-reducing functions]]&lt;/div&gt;</summary>
		<author><name>Fredbrunt</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Subscript-Slice_Operator&amp;diff=62500</id>
		<title>Subscript-Slice Operator</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Subscript-Slice_Operator&amp;diff=62500"/>
		<updated>2025-05-08T07:11:33Z</updated>

		<summary type="html">&lt;p&gt;Fredbrunt: /* Subscripting and Meta-Inference */ Changing 'Var' to 'Local'&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:Operators]]&lt;br /&gt;
[[Category:Doc Status C]] &amp;lt;!-- For Lumina use, do not change --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
The '''subscript''' operation, in square brackets after an expression «X»,&lt;br /&gt;
:&amp;lt;code&amp;gt;X[I = v]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
returns the element of array «X» for which index «I» equals value «v». It's like subscripting in many other computer languages, but a lot more powerful because of Analytica's Intelligent Arrays features.&lt;br /&gt;
&lt;br /&gt;
If «X» has more indexes than «I», this expression returns the [[slice]] (or subarray) of «X» for which ''I = v''. The resulting [[slice]] is indexed by the other Index(es) of «X».&lt;br /&gt;
&lt;br /&gt;
Subscript also works if v is an array, returning an array of all the slices of «X» for which ''I = v''. The result is indexed by the Index(es) of «v», as well as any Index(es) of «X» other than «I». You can use this feature to subset, sort, or reindex an Array, as described below.&lt;br /&gt;
&lt;br /&gt;
The '''slice''' operator X[@I = n] returns the slice of array «X» for the nth element of index «I».  [[Slice]] is the same as [[Subscript]], except that you put '@', the '''positional''' operator, before the Index «I».  So it treats Index «I» as a list of ''positions'' -- i.e. integers ''1'' to ''m'', where ''m = Size(I)''.&lt;br /&gt;
&lt;br /&gt;
You can subscript or slice over multiple indexes together, for example:&lt;br /&gt;
:&amp;lt;code&amp;gt;X[I = v, J = u]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which returns the element (or slice) of «X» over indexes «I» and «J».&lt;br /&gt;
&lt;br /&gt;
Subscript operator can work over an expression as well as a variable name, for example:&lt;br /&gt;
:&amp;lt;code&amp;gt;Sum(Y, J)[K = 2]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gives the slice of the sum of &amp;lt;code&amp;gt;Y&amp;lt;/code&amp;gt; over index &amp;lt;code&amp;gt;J&amp;lt;/code&amp;gt; for which &amp;lt;code&amp;gt;K = 2&amp;lt;/code&amp;gt;. It is equivalent to:&lt;br /&gt;
:&amp;lt;code&amp;gt;Sum(Y[K = 2], J)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If no element of «I» matches the value of «v» for subscript, it returns [[Null]] and a warning message (unless turned you turn off that warning). &lt;br /&gt;
&lt;br /&gt;
== Naming Indexes ==&lt;br /&gt;
&lt;br /&gt;
In Analytica, you must name the Index(es) over which you are subscripting, e.g.&lt;br /&gt;
:&amp;lt;code&amp;gt;X[I = 1, J = 'B']&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Other computer languages don't expect names in subscripts. They require you to list the indexes in the sequence used in their internal array representation:&lt;br /&gt;
:&amp;lt;code&amp;gt;X[1, 'B']&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The advantages of identifying indexes by name, as in Analytica, include:&lt;br /&gt;
# you don't need to know or care about the sequence of the indexes in the array representation -- unlike spreadsheets, and most general languages, which need to you to know which index refers to rows, columns, or higher dimensions. In Analytica, it is your choice when displaying an array which index to show over the rows and columns; not something inherent in the underlying representation.&lt;br /&gt;
# you can list Index(es) in any sequence, ignoring any other Index(es) that the array may have. As you develop an Analytica model, or perform scenario or sensitivity analysis, it is common to add further indexes.  Expressions using subscripts with named indexes are robust to such changes in the model, unlike conventional languages in which they break.&lt;br /&gt;
&lt;br /&gt;
Naming indexes in subscripts is similar to the named parameter syntax available in Analytica for calling functions: You can specify names for each parameter and don't need to worry about their sequence or omitting unneeded optional parameters -- e.g.&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText(', ', text: X, caseInsensitive: True, repeat: True)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The difference is that naming indexes in subscripts is required, where naming parameters in function calls is optional as long as you insert all parameters in the standard sequence.&lt;br /&gt;
&lt;br /&gt;
== Implicit Indexing -- subscripting over an irrelevant index ==&lt;br /&gt;
&lt;br /&gt;
If you Subscript (or Slice) an array «X» over an Index «I» that is not actually an index of «X», it simply returns the value of «X» unchanged. This is with Analytica's fundamental principle of  of implicit indexing:  If «X» is not explicitly indexed by Index «I», it is assumed to have the same value for each value of «I». &lt;br /&gt;
&lt;br /&gt;
For example, suppose variable &amp;lt;code&amp;gt;Markup&amp;lt;/code&amp;gt; is the percentage mark-up applied by a retailer to each product line it sells. If it applies the same mark-up to all products, it can set &amp;lt;code&amp;gt;Markup&amp;lt;/code&amp;gt; to a single percentage. If it wants to apply different &amp;lt;code&amp;gt;Markup&amp;lt;/code&amp;gt;'s to different product Categories or at stores in different Locations, it can define &amp;lt;code&amp;gt;Markup&amp;lt;/code&amp;gt; as an Array indexed by &amp;lt;code&amp;gt;Categories&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Locations&amp;lt;/code&amp;gt;. If &amp;lt;code&amp;gt;Markup&amp;lt;/code&amp;gt; does not vary over time, then it need not be indexed by &amp;lt;code&amp;gt;Time&amp;lt;/code&amp;gt; (or &amp;lt;code&amp;gt;Month&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Year&amp;lt;/code&amp;gt;) -- i.e. &amp;lt;code&amp;gt;Markup[Year = 2014]&amp;lt;/code&amp;gt; would have the same value for any value of Year because it isn't indexed by Year.&lt;br /&gt;
&lt;br /&gt;
== Positional and Associational indexing ==&lt;br /&gt;
&lt;br /&gt;
The standard subscript operation, without the '@', uses ''associational'' indexing: It identifies the value of index «I» by association with the value or label of each element of the Index. The slice operator, with the '@', uses ''positional'' indexing. It identifies each slice by its position in index «I», an integer from ''1'' to ''m'', where ''m = Size(I)''.&lt;br /&gt;
&lt;br /&gt;
Usually, it is wisest to make sure that the values of an Index are unique, but occasionally you must use an Index that contains repeated values. If Index &amp;lt;code&amp;gt;Name&amp;lt;/code&amp;gt; contains the last name of all employees, some employees may have the same last name. In that case, subscripting by &amp;lt;code&amp;gt;Name&amp;lt;/code&amp;gt; may be ambiguous:&lt;br /&gt;
:&amp;lt;code&amp;gt;Salary[Name = 'Smith']&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will return the salary of the first person named &amp;lt;code&amp;gt;Smith&amp;lt;/code&amp;gt;. In such cases, you can use positional indexing to select a slice for the person you want. &lt;br /&gt;
:&amp;lt;code&amp;gt;Salary[@Name = 42]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This assumes you know the ID (number in the &amp;lt;code&amp;gt;Name&amp;lt;/code&amp;gt; index) for each person.&lt;br /&gt;
&lt;br /&gt;
For more, see [[Associative vs. Positional Indexing]].&lt;br /&gt;
&lt;br /&gt;
== Subscript(x, i, v) and Slice(x, i, v) functions ==&lt;br /&gt;
&lt;br /&gt;
The functions [[Subscript]](x, i, v) and [[Slice]](x, i, v) are exactly equivalent to ''x[i = v]'' and ''x[@i = v] respectively.&lt;br /&gt;
They exist mostly for forward compatibility from the earliest releases of Analytica that did not include the operator syntax.&lt;br /&gt;
&lt;br /&gt;
== Subscripts and Array Abstraction ==&lt;br /&gt;
&lt;br /&gt;
When «x» or «n» is atomic, the slice/subscript operations usually reduce the dimensionality of the array by one dimension (the exception being when the index is not a dimension of the original value).  However, in general, «x» or n can be arbitrary expressions, and the result of «x» or «n» may be array-valued.  In general, dimensions appearing in «x» or «n» will appear in the result, so the dimensionality may actually increase as a result of applying the slice or subscript operators.  &lt;br /&gt;
&lt;br /&gt;
As [[array abstraction]] operates over the «x» and «n» parameters, the [[slice]] and [[subscript]] operators offer extremely general and powerful lookup operators.  Fairly complex operations equivalent to re-indexing, VLookup operations in spreadsheets, outer-joins in relational databases, and others are achieved quite simply and directly using subscript or slice operations.  These operators are also used for sorting or re-ordering arrays, filtering rows, and other operations.  This flexibility relieves Analytica from having to have a plethora of lookup functions often found in many other languages.  However, mastering the full power of Slice and Subscript operators may take some time.&lt;br /&gt;
&lt;br /&gt;
=== Re-indexing ===&lt;br /&gt;
Re-indexing is a common operation -- replace one index of an array by another index.  If indexes &amp;lt;code&amp;gt;I&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;J&amp;lt;/code&amp;gt; have the same elements in the same order with no duplicates, which might arise if &amp;lt;code&amp;gt;J&amp;lt;/code&amp;gt; is defined as:&lt;br /&gt;
:&amp;lt;code&amp;gt;J := CopyIndex(I)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This simple expression re-indexes as you want, if array &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; is indexed by &amp;lt;code&amp;gt;I&amp;lt;/code&amp;gt;:&lt;br /&gt;
:&amp;lt;code&amp;gt;A[I = J]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result is identical to &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;, except that it is indexed by &amp;lt;code&amp;gt;J&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;I&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
You can do the same using the positional operator:&lt;br /&gt;
:&amp;lt;code&amp;gt;A[@I = @J]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The advantage of this is that it works if &amp;lt;code&amp;gt;I&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;J&amp;lt;/code&amp;gt; are the same length but have different elements, or if the indexes contain duplicate elements.&lt;br /&gt;
&lt;br /&gt;
Here is an example, to compute the outer-product of a vector, &amp;lt;code&amp;gt;V&amp;lt;/code&amp;gt; indexed by &amp;lt;code&amp;gt;I&amp;lt;/code&amp;gt; with its transpose:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Index J := CopyIndex(I)&amp;lt;/code&amp;gt;  -- creates &amp;lt;code&amp;gt;J&amp;lt;/code&amp;gt; with identical length and values to &amp;lt;code&amp;gt;I&amp;lt;/code&amp;gt;.&lt;br /&gt;
:&amp;lt;code&amp;gt;V * V[I = J]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result is the outer product, with dimensions &amp;lt;code&amp;gt;I&amp;lt;/code&amp;gt; x &amp;lt;code&amp;gt;J&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Re-ordering ===&lt;br /&gt;
&lt;br /&gt;
The slice and subscript operators can be used to re-order an array in various scenarios.  Often, you will have an index &amp;lt;code&amp;gt;J&amp;lt;/code&amp;gt;, which is a permutation of index &amp;lt;code&amp;gt;I&amp;lt;/code&amp;gt;.  In this case, a re-indexing re-orders the elements of &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;, using just &amp;lt;code&amp;gt;A[I = J]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A common example of this is sorting.  Suppose &amp;lt;code&amp;gt;Row&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Col&amp;lt;/code&amp;gt; are both indexes of array &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;, and you want to sort on the column &amp;lt;code&amp;gt;A[Col = 'ROI']&amp;lt;/code&amp;gt;.  Here you would create a new index, &amp;lt;code&amp;gt;SortedRow&amp;lt;/code&amp;gt;, defined as&lt;br /&gt;
:&amp;lt;code&amp;gt;SortIndex(A[Col = 'ROI'])&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and then compute the sorted array using &amp;lt;code&amp;gt;A[Row = SortedRow]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Another example of re-ordering is the reversing of elements.  In Analytica, the [[Dynamic]] function computes starting from the beginning of [[Time]].  In many dynamic programming applications, we would like to start from the final time point and work our way back.  Often the way this is done is by reversing the the array so that we can use [[Dynamic]], and then reversing the result once computed.  This is one example where reversing an array is useful.  To reverse an array, the Slice operator is the most convenient:&lt;br /&gt;
:&amp;lt;code&amp;gt; A[@I=size(I) - @I + 1]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It's often useful to shift an array left or right along a given index. The basic form of a shift-left or shift-right is &amp;lt;code&amp;gt;A[@I = @I - 1]&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;A[@I = @I + 1]&amp;lt;/code&amp;gt; respectively. See the &amp;quot;out of range conditions&amp;quot; section below for how to handle the rightmost or leftmost element of the result, which otherwise end us as [[Null]].&lt;br /&gt;
&lt;br /&gt;
=== Filtering ===&lt;br /&gt;
&lt;br /&gt;
Filtering extracts a subset of &amp;quot;rows&amp;quot; from an array along a given dimension.  If we want a subset of slices along dimension &amp;lt;code&amp;gt;I&amp;lt;/code&amp;gt;, we need to define a new index, say &amp;lt;code&amp;gt;I2&amp;lt;/code&amp;gt;, containing a subset of &amp;lt;code&amp;gt;I&amp;lt;/code&amp;gt;.  For example, to obtain the subset of people younger than 30, a subset of the &amp;lt;code&amp;gt;People&amp;lt;/code&amp;gt; index, we define the new index, &amp;lt;code&amp;gt;YoungPeople&amp;lt;/code&amp;gt;, and use it in the [[Subscript]]:&lt;br /&gt;
:&amp;lt;code&amp;gt;Index YoungPeople := Subset(PersonData[Trait = 'Age'] &amp;lt; 30)&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;PersonData[People = YoungPeople]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Multi-step lookup, outer-join, or VLookup ===&lt;br /&gt;
&lt;br /&gt;
We often need to combine two arrays with different indexes, where one array contains values associated with elements of the other array. This combination is called an &amp;quot;outer join&amp;quot; for databases or''' VLookup''' (or '''HLookup''') in Excel. For example, suppose we want to obtain the salary of each &amp;lt;code&amp;gt;Person&amp;lt;/code&amp;gt;, given the array, &amp;lt;code&amp;gt;Salary_by_profession&amp;lt;/code&amp;gt;, with the salary for each &amp;lt;code&amp;gt;Profession&amp;lt;/code&amp;gt; and another array, &amp;lt;code&amp;gt;Profession_by_person&amp;lt;/code&amp;gt;, with the &amp;lt;code&amp;gt;Profession&amp;lt;/code&amp;gt; for each &amp;lt;code&amp;gt;Person&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
:{| border=&amp;quot;0&amp;quot;&lt;br /&gt;
| &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Profession !! Salary_by_profession&lt;br /&gt;
|-&lt;br /&gt;
| 'Dock loader' || $45,000&lt;br /&gt;
|-&lt;br /&gt;
| 'Crane operator' || $75,000&lt;br /&gt;
|-&lt;br /&gt;
| 'Forklift driver' || $32,000&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
| &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; ||&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Person !! Profession_by_person&lt;br /&gt;
|-&lt;br /&gt;
| 'Joe Smith' || 'Crane operator'&lt;br /&gt;
|-&lt;br /&gt;
| 'Mark Jones' || 'Forklift driver'&lt;br /&gt;
|-&lt;br /&gt;
| 'Greg Johnson' || 'Forklift driver'&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In Analytica, we can compute the salary by person with this simple [[Subscript]] expression:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Salary_by_profession[Profession = Profession_by_person]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result is:&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Person !! Salary_by_person&lt;br /&gt;
|-&lt;br /&gt;
| 'Joe Smith' || $75,000&lt;br /&gt;
|-&lt;br /&gt;
| 'Mark Jones' || $32,000&lt;br /&gt;
|-&lt;br /&gt;
| 'Greg Johnson || $32,000&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== When a subscript is Out of Range ===&lt;br /&gt;
&lt;br /&gt;
If you evaluate&lt;br /&gt;
:&amp;lt;code&amp;gt;A[I = x]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
when x is not an element of I, or &lt;br /&gt;
:&amp;lt;code&amp;gt;A[@I = n]&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
when n is not a valid position of I (e.g., ''n &amp;lt; 0'' or ''n &amp;gt; size(I)''), the result is &amp;quot;out of range&amp;quot; and usually returns [[Null]]. If the [[Null]] will appear in the result, it usually gives an &amp;quot;Out of range&amp;quot; warning. You can switch off this warning in two ways: You can unset the default preference in [[Preferences|&amp;quot;Show Result Warnings&amp;quot; preference]],&lt;br /&gt;
or you can enclose the expression in the [[IgnoreWarnings]]() function&lt;br /&gt;
:&amp;lt;code&amp;gt;IgnoreWarnings(A[@I = @I - 1])&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is generally better to wrap the expression with the [[IgnoreWarnings]] function: It runs faster as a result of relieving Analytica from having to track whether the out-of-range condition impacts the final result.&lt;br /&gt;
&lt;br /&gt;
== Subscript Assignment ==&lt;br /&gt;
&lt;br /&gt;
You may assign a value to a Subscripted element of a local variable using either the subscript (or slice) operator on the left-hand side of the := operator. For example:&lt;br /&gt;
:&amp;lt;code&amp;gt;v[Time = 5] := 0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When using Subscript assignment, the variable being assigned to MUST be local, even if used from an [[OnChange]] expression (or Button [[script]]). (See [[Assignment Operator:: ::=#Don't change a global index used by a transient array|Assignment Operator :: ::]] for why you can't usually assign to a Global variable.)&lt;br /&gt;
&lt;br /&gt;
Subscript assignment does array abstraction in the usual ways.  In expressions &lt;br /&gt;
:&amp;lt;code&amp;gt;V[I = x]  := y&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;V[@I = n] := y&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
any of the parameters «V», «x», «n», and «y» may be arrays with one or multiple Indexes. If local variable «V» is not indexed by «I» before the assignment, it will be after the assignment. Any slices for which ''I &amp;lt;&amp;gt; x'' (or ''@I &amp;lt;&amp;gt; n'') will contain the same value(s) as «V» did before the assignment -- consistent with the Principle of Implicit Indexing. Only the assigned slice ''V[I = x]'' gets the new value, «y».&lt;br /&gt;
If «y» has an Index (or Indexes) not already in «V», «V» will gain that Index (those Indexes) during the assignment. Again, each slice of «V» for which ''I &amp;lt;&amp;gt; x'' will have the original values of «V» repeated over the new Index(es) of «y».&lt;br /&gt;
&lt;br /&gt;
For example, suppose «V» is indexed only by «I», but «y» contains the index «J».  Then after evaluating&lt;br /&gt;
:&amp;lt;code&amp;gt;V[I = x] := y&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
«V» will be indexed by both «I» and «J».  The slice corresponding to ''I = x'' will have a potentially different value for each element of «J», but the other slices along «I» will be constant across «J» (having the original value of «v»).&lt;br /&gt;
&lt;br /&gt;
== Subscripting and Meta-Inference ==&lt;br /&gt;
&lt;br /&gt;
[[Meta-Inference]] is an advanced Analytica programming topic concerning computation about the objects and structure of the model itself. For example, it may compute the number of input variables, or find the common inputs of two variables. Meta-inference must handle the situation when an index contains object identifiers or expressions as elements.  The default behavior of [[Subscript]] requires these variables and expressions to be evaluated, and for those that evaluate to scalars, both the scalar value and the original [[varTerm]] or expression are recognized by [[Subscript]].  This is demonstrated by the following example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable A := 5&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable B := 10&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Index I := [ A, B ]           { Global index, defined as List, with identifier A and B in each cell }&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable C := Table(I)(3, 4)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;C[I = 5] &amp;amp;rarr; 3&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;C[I = A] &amp;amp;rarr; 3&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;C[I = VarTerm(A)] &amp;amp;rarr; 3&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;IndexValue(I) &amp;amp;rarr; [A, B]        { These are [[VarTerm]]s -- handles to objects }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There is a distinct difference between the first two subscript examples and the third. &amp;lt;code&amp;gt; C[I = 5]&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;C[I = A]&amp;lt;/code&amp;gt; are performing associative lookup based on the evaluated result of the index elements, while &amp;lt;code&amp;gt;C[I = VarTerm(A)]&amp;lt;/code&amp;gt; is using the raw un-evaluated [[IndexValue]].  &lt;br /&gt;
&lt;br /&gt;
When your intention is to reason about the structure of the objects in the model, the default functionality of subscript has a couple undesirable aspects.  First, it forces the elements of the index to be evaluated.  If those computations are expensive, they must be carried out before your meta-inference can proceed, and if there are errors or warnings while evaluating, those errors appear.  Second, if some elements evaluate to [[varTerm]]s, there may be ambiguities.&lt;br /&gt;
 &lt;br /&gt;
The following example demonstrates these concerns.  The example collects the definition (e.g., for a report) of all the objects with definitions in module &amp;lt;code&amp;gt;Report_A&amp;lt;/code&amp;gt;.&lt;br /&gt;
  &lt;br /&gt;
:&amp;lt;code&amp;gt;Index allObjects := Contains of Report_A;&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Local v := allObjects;&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Local allTitles := Title of v;&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Local allDefns  := Definition of v;&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Index Objects_With_Defs := Subset(not IsUndef(allTitles));&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;allDefns[allObjects = Objects_with_Defs]&amp;lt;/code&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
When the subscript operation in the last line is evaluated, all the objects listed in the &amp;lt;code&amp;gt;Objects&amp;lt;/code&amp;gt; index will need to be fully evaluated.  If a variable in &amp;lt;code&amp;gt;Module Report_A&amp;lt;/code&amp;gt; contains an error, the error will appear when the last line is evaluated.  If a variable takes 5 hours to compute, this expression will trigger and wait for that computation, even though the result is not really needed here.&lt;br /&gt;
&lt;br /&gt;
To avoid these problems, you must tell Analytica to treat the &amp;lt;code&amp;gt;allObjects&amp;lt;/code&amp;gt; index as a meta-index, i.e., as an index containing literal expressions or identifiers, whose raw unevaluated values are to be used in associative lookup, but whose evaluated element values are not to be used.   This is done by changing the first line to:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;[[MetaIndex]] allObjects := Contains of Report_A;&amp;lt;/code&amp;gt;&lt;br /&gt;
:...&lt;br /&gt;
&lt;br /&gt;
For a global index object, to achieve this treatment, you must set the [[MetaOnly]] attribute to 1 (true), see [[MetaOnly]] for instructions. In the previous example, when the [[MetaOnly]] attribute set to true for Index &amp;lt;code&amp;gt;I&amp;lt;/code&amp;gt;, the previous expressions evaluate as &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;C[I = 5] &amp;amp;rarr; Null                { not found }&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;C[I = A] &amp;amp;rarr; Null                { not found }&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;C[I = VarTerm(A)] &amp;amp;rarr; 3&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With [[MetaOnly]] set, index elements containing system variables such as INF, [[Null]], True, False, Pi, etc., will not match to the underlying value, since these are actually system variable objects.  See [[MetaOnly]] for more details.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Subscript]] function&lt;br /&gt;
* [[Slice]] function&lt;br /&gt;
* [[Index Position Operator::@]]&lt;br /&gt;
* [[SortIndex]]&lt;br /&gt;
* [[Rank]]&lt;br /&gt;
* [[Subscript]]&lt;br /&gt;
* [[IgnoreWarnings]]&lt;br /&gt;
* [[Associative vs. Positional Indexing]]&lt;br /&gt;
* [[Assignment Operator:: ::=]]&lt;br /&gt;
* [[IdentPred]]&lt;/div&gt;</summary>
		<author><name>Fredbrunt</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Slice&amp;diff=62499</id>
		<title>Slice</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Slice&amp;diff=62499"/>
		<updated>2025-05-07T07:47:46Z</updated>

		<summary type="html">&lt;p&gt;Fredbrunt: /* Examples */ Fixed out of range example, before it wasn't returning null&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Functions that select part of an array]]&lt;br /&gt;
 &lt;br /&gt;
== Slice(A, I, n) ==&lt;br /&gt;
&lt;br /&gt;
Returns the «n»th slice of array «A» along index «I».&lt;br /&gt;
&lt;br /&gt;
The [[Slice]] function is so commonly used, as is its associational counterpart, the [[Subscript]] function, that a special shorthand notation is more often used in Analytica expressions.  &amp;lt;code&amp;gt;Slice(A, I, n)&amp;lt;/code&amp;gt; can be written as [[Subscript-Slice Operator|A[@I = n]]].&lt;br /&gt;
&lt;br /&gt;
== Slice(A, n) ==&lt;br /&gt;
&lt;br /&gt;
When «A» is one-dimensional, «I» can be omitted.  Use this syntax when you want to obtain the «n»th element of a list, but cannot name the index since it is implicit.&lt;br /&gt;
&lt;br /&gt;
== Library ==&lt;br /&gt;
&lt;br /&gt;
Array functions&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
:&amp;lt;code&amp;gt;Index I := [10, 20, 30, 40]&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Index J := ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Index K := 1..3&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable A := Table(J)(9, 2, 3, 4, 1, 9, 0, 3)&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable B := I + K&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Slice(A, J, 5) &amp;amp;rarr; 1&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Slice(A, J, 3..6) &amp;amp;rarr; [3, 4, 1, 9]&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Slice(A, J, K) &amp;amp;rarr; Array(J, [9, 2, 3])&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Slice(A, J, 9) &amp;amp;rarr; «null»   {with an out-of-range warning}&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Slice(A, I, 3) &amp;amp;rarr; Array(J, [9, 2, 3, 4, 1, 9, 0, 3])&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Slice(B, I, 3) &amp;amp;rarr; Array(K,[31, 32, 33])&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Slice(B, K, 3) &amp;amp;rarr; Array(I,[13, 23, 33, 43])&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Slice(4, J, 5) &amp;amp;rarr; 4&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[Arrays and Indexes]]&lt;br /&gt;
* [[Slice assignment]]&lt;br /&gt;
* [[Subscript-Slice Operator]]&lt;br /&gt;
* [[Subscript]]&lt;br /&gt;
* [[Subscript and slice of a subarray]]&lt;br /&gt;
* [[Table Splicing]]&lt;/div&gt;</summary>
		<author><name>Fredbrunt</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Mod&amp;diff=62489</id>
		<title>Mod</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Mod&amp;diff=62489"/>
		<updated>2025-04-29T03:03:36Z</updated>

		<summary type="html">&lt;p&gt;Fredbrunt: /* IsInteger */ Change incorrect &amp;quot;==&amp;quot; operator to &amp;quot;=&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:Math Functions]]&lt;br /&gt;
[[Category:Doc Status C]] &amp;lt;!-- For Lumina use, do not change --&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
==Mod(x, y'', pos'')==&lt;br /&gt;
&lt;br /&gt;
The remainder (modulus) of «x» / «y».&lt;br /&gt;
&lt;br /&gt;
The sign of the result of &amp;lt;code&amp;gt;Mod(x,y)&amp;lt;/code&amp;gt; is the same as the sign of «x» -- i.e., if «x» is negative, then so is the result. The sign of «y» does not impact the sign of the result. This variation is the same convention used by the corresponding operator in C/C++ (ISO 1999), C#, Java, PHP, Visual Basic, AMPL and many other languages. Some languages, including MATLAB, Lisp, Fortran, and Ada, have two different modulo operators, with one corresponding to this convention. The modulo operator in a few other languages, including Mathematica, R and Excel, do not follow this convention (these use the sign of the denominator).&lt;br /&gt;
&lt;br /&gt;
You can specify «pos» as true to force the result to be non-negative, in the range &amp;lt;code&amp;gt;0 &amp;amp;le; Mod(x,y) &amp;lt; Abs(y)&amp;lt;/code&amp;gt;. As «x» increases through all negative and positive numbers, the result cycles through this range.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Mod(x,1)&amp;lt;/code&amp;gt; extracts the fractional portion of a number.&lt;br /&gt;
&lt;br /&gt;
==Examples ==&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Mod(20,7) &amp;amp;rarr; 6&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Mod(-20,7) &amp;amp;rarr; -6&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Mod(-20,-7) &amp;amp;rarr; -6&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Mod(20,-7) &amp;amp;rarr; 6&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Mod(-20,7,pos: true) &amp;amp;rarr; 1&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Mod(Pi,1) &amp;amp;rarr; 0.141592653589793&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Special uses ==&lt;br /&gt;
&lt;br /&gt;
=== IsOdd and IsEven ===&lt;br /&gt;
&lt;br /&gt;
To test whether an integer &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; is odd use &amp;lt;code&amp;gt;Mod(x, 2) = 1&amp;lt;/code&amp;gt;, and similarly, to test whether an integer is even use &amp;lt;code&amp;gt;Mod(x, 2) = 0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== IsInteger ===&lt;br /&gt;
&lt;br /&gt;
To test whether a number &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; is an integer, use &amp;lt;code&amp;gt;Mod(x,1) = 0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The fractional part of a number  ===&lt;br /&gt;
:&amp;lt;code&amp;gt;[[Mod]]( Pi, 1)&amp;lt;/code&amp;gt; &amp;amp;rarr; 0.141592653589793&lt;br /&gt;
:&amp;lt;code&amp;gt;[[Mod]]( -Pi,1)&amp;lt;/code&amp;gt; &amp;amp;rarr; -0.141592653589793&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Time part of a date-time number ===&lt;br /&gt;
&lt;br /&gt;
(''new in [[Analytica 6.0]]'')  When you have a date-time number, &amp;lt;code&amp;gt;[[Mod]](d,1)&amp;lt;/code&amp;gt; returns the time part and returns it as a date-time number instead of a float.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
* [[Abs]]&lt;br /&gt;
* [[GCD]]&lt;br /&gt;
* [[IsNumber]]&lt;br /&gt;
* [[Array Abstraction]]&lt;br /&gt;
* [[Math functions]]&lt;/div&gt;</summary>
		<author><name>Fredbrunt</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Mod&amp;diff=62488</id>
		<title>Mod</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Mod&amp;diff=62488"/>
		<updated>2025-04-29T03:03:15Z</updated>

		<summary type="html">&lt;p&gt;Fredbrunt: /* IsOdd and IsEven */ Change incorrect &amp;quot;==&amp;quot; operator to &amp;quot;=&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:Math Functions]]&lt;br /&gt;
[[Category:Doc Status C]] &amp;lt;!-- For Lumina use, do not change --&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
==Mod(x, y'', pos'')==&lt;br /&gt;
&lt;br /&gt;
The remainder (modulus) of «x» / «y».&lt;br /&gt;
&lt;br /&gt;
The sign of the result of &amp;lt;code&amp;gt;Mod(x,y)&amp;lt;/code&amp;gt; is the same as the sign of «x» -- i.e., if «x» is negative, then so is the result. The sign of «y» does not impact the sign of the result. This variation is the same convention used by the corresponding operator in C/C++ (ISO 1999), C#, Java, PHP, Visual Basic, AMPL and many other languages. Some languages, including MATLAB, Lisp, Fortran, and Ada, have two different modulo operators, with one corresponding to this convention. The modulo operator in a few other languages, including Mathematica, R and Excel, do not follow this convention (these use the sign of the denominator).&lt;br /&gt;
&lt;br /&gt;
You can specify «pos» as true to force the result to be non-negative, in the range &amp;lt;code&amp;gt;0 &amp;amp;le; Mod(x,y) &amp;lt; Abs(y)&amp;lt;/code&amp;gt;. As «x» increases through all negative and positive numbers, the result cycles through this range.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Mod(x,1)&amp;lt;/code&amp;gt; extracts the fractional portion of a number.&lt;br /&gt;
&lt;br /&gt;
==Examples ==&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Mod(20,7) &amp;amp;rarr; 6&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Mod(-20,7) &amp;amp;rarr; -6&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Mod(-20,-7) &amp;amp;rarr; -6&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Mod(20,-7) &amp;amp;rarr; 6&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Mod(-20,7,pos: true) &amp;amp;rarr; 1&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Mod(Pi,1) &amp;amp;rarr; 0.141592653589793&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Special uses ==&lt;br /&gt;
&lt;br /&gt;
=== IsOdd and IsEven ===&lt;br /&gt;
&lt;br /&gt;
To test whether an integer &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; is odd use &amp;lt;code&amp;gt;Mod(x, 2) = 1&amp;lt;/code&amp;gt;, and similarly, to test whether an integer is even use &amp;lt;code&amp;gt;Mod(x, 2) = 0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== IsInteger ===&lt;br /&gt;
&lt;br /&gt;
To test whether a number &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; is an integer, use &amp;lt;code&amp;gt;Mod(x,1) == 0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The fractional part of a number  ===&lt;br /&gt;
:&amp;lt;code&amp;gt;[[Mod]]( Pi, 1)&amp;lt;/code&amp;gt; &amp;amp;rarr; 0.141592653589793&lt;br /&gt;
:&amp;lt;code&amp;gt;[[Mod]]( -Pi,1)&amp;lt;/code&amp;gt; &amp;amp;rarr; -0.141592653589793&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Time part of a date-time number ===&lt;br /&gt;
&lt;br /&gt;
(''new in [[Analytica 6.0]]'')  When you have a date-time number, &amp;lt;code&amp;gt;[[Mod]](d,1)&amp;lt;/code&amp;gt; returns the time part and returns it as a date-time number instead of a float.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
* [[Abs]]&lt;br /&gt;
* [[GCD]]&lt;br /&gt;
* [[IsNumber]]&lt;br /&gt;
* [[Array Abstraction]]&lt;br /&gt;
* [[Math functions]]&lt;/div&gt;</summary>
		<author><name>Fredbrunt</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Ceil&amp;diff=62475</id>
		<title>Ceil</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Ceil&amp;diff=62475"/>
		<updated>2025-04-23T05:29:55Z</updated>

		<summary type="html">&lt;p&gt;Fredbrunt: /* Ceil(x, digits, dateUnit) */ fixed type, change comma to period&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:Math Functions]]&lt;br /&gt;
[[Category:Doc Status C]] &amp;lt;!-- For Lumina use, do not change --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Ceil(x'', digits, dateUnit'') ==&lt;br /&gt;
&lt;br /&gt;
[[Ceil]](x) returns the smallest integer that is greater than or equal to «x».&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Ceil(174.001) &amp;amp;rarr; 175&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Ceil(-89.95) &amp;amp;rarr; -89&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the optional «digits» parameter is given, cuts the number off at «digits» to the right of the decimal, returning the smallest multiple of 10&amp;lt;sup&amp;gt;-«digits»&amp;lt;/sup&amp;gt; that is equal to or larger than «x».&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Ceil( 3.141592, 2) &amp;amp;rarr;  3.150000&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Ceil(-3.141592, 2) &amp;amp;rarr; -3.140000&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Ceil( 3.141592, 5) &amp;amp;rarr;  3.141600&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
«digits» may also be negative, in which case the least significant -«digits» digits will be '0':&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Ceil(123456.789, -1) &amp;amp;rarr; 123460.00&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Ceil(123456.789, -4) &amp;amp;rarr; 130000.00&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you specify the «dateUnit» parameter, [[Ceil]] rounds a date-time number upward to the earliest date-time at the «dateUnit» increment that is equal to or comes after the date-time specified in «x».  For example, you can round up to the beginning of the following year, quarter, or month, or to the beginning (meaning midnight) of the next weekday, day, or up to the next hour, minute or second.  The value you pass to «dateUnit» must be one of the following: 'Y', 'year', 'Q', 'quarter', 'M', 'month', 'WD', 'weekday', 'D', 'day', 'h', 'hour', 'm', 'minute', 's', or 'second'.  Note that 'M' (for Month) and 'm' (for minute) are case sensitive.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Ceil(MakeDate(2010, 8, 8), dateUnit: 'Y') &amp;amp;rarr; 2011-Jan-1&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Ceil(MakeDate(2010, 8, 8), dateUnit: 'Q') &amp;amp;rarr; 2010-Oct-1&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Ceil(MakeDate(2010, 8, 8), dateUnit: 'M') &amp;amp;rarr; 2010-Sep-1&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Ceil(MakeDate(2010, 8, 1), dateUnit: 'M') &amp;amp;rarr; 2010-Aug-1&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Ceil(MakeDate(2010, 8, 1)+MakeTime(0, 0, 1), dateUnit: 'M') &amp;amp;rarr; 2010-Sep-1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice in the last example that if we are even one second past midnight of Aug 1st, it rounds to the beginning of the next month.&lt;br /&gt;
&lt;br /&gt;
== Number Format ==&lt;br /&gt;
The [[Ceil]], [[Round]] and [[Floor]] functions all cut a number off to the indicated number of decimal places, but note that this is separate from the number format used to display the number.  The number format setting controls how many digits are shown when displaying numbers, such as in an edit or result table.  For example, after rounding to 4 decimal places, a number may be 2.3456, but if your number format is set to fixed point with 2 digits, this would display as 2.35.&lt;br /&gt;
&lt;br /&gt;
To see the full effect of the [[Ceil]] function, set the number format to a large number of digits.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[Floor]]()&lt;br /&gt;
* [[Round]]()&lt;br /&gt;
* [[MakeDate]]()&lt;br /&gt;
* [[MakeTime]]()&lt;br /&gt;
* [[Sequence]]()&lt;br /&gt;
* [[DateAdd]]()&lt;br /&gt;
* [[DatePart]]()&lt;/div&gt;</summary>
		<author><name>Fredbrunt</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Operators&amp;diff=62474</id>
		<title>Operators</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Operators&amp;diff=62474"/>
		<updated>2025-04-21T04:37:19Z</updated>

		<summary type="html">&lt;p&gt;Fredbrunt: /* Scoping operator (::) */ Fixing example which is MISSING the scoping operator&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt;Analytica User Guide &amp;gt; Expressions &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
An infix '''''operator '''''is a symbol, such as a plus sign (&amp;lt;code&amp;gt;1 + 2&amp;lt;/code&amp;gt;) or product (&amp;lt;code&amp;gt;10*2&amp;lt;/code&amp;gt;), that operates on the values before and after it. A prefix operator, such as unary minus (&amp;lt;code&amp;gt;-100&amp;lt;/code&amp;gt;) operates only on the value after it. Analytica includes these fairly standard opera tors, including arithmetic, comparison, and logical operators:&lt;br /&gt;
&lt;br /&gt;
=== Arithmetic operators ===&lt;br /&gt;
The arithmetic operators apply to [[numbers]] and produce numbers:&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Operator&lt;br /&gt;
!Meaning&lt;br /&gt;
!Examples&lt;br /&gt;
|-&lt;br /&gt;
|x+y&lt;br /&gt;
|plus&lt;br /&gt;
|&amp;lt;math&amp;gt;3 + 2 → 5&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|x - y&lt;br /&gt;
|binary minus&lt;br /&gt;
|&amp;lt;math&amp;gt;3 - 2 → 1&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;-x&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|unary minus&lt;br /&gt;
|&amp;lt;math&amp;gt;-2 → -2&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|x*y&lt;br /&gt;
|product&lt;br /&gt;
|&amp;lt;math&amp;gt;3*2 → 6&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|x/3 or x÷y&lt;br /&gt;
|division&lt;br /&gt;
|&amp;lt;math&amp;gt;3/2 (= \frac{3}{2}) → 1.5&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|x^y&lt;br /&gt;
|to the power of&lt;br /&gt;
|&amp;lt;math&amp;gt;3^2 = 3^2 → 9&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;4^.5 = 4^{\frac{1}{2}} → 2&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Text concatenation ===&lt;br /&gt;
&lt;br /&gt;
The text concatenation operator, &amp;lt;code&amp;gt;&amp;amp;&amp;lt;/code&amp;gt; joins the sequence of characters from each parameter to form a text result. If either parameter is not already text, then the value is ''coerced'' to text using the number format for the object containing the expression. If you use the operator in a [[user-defined function]] then the function's number format is used.&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Operator&lt;br /&gt;
!Meaning&lt;br /&gt;
!Examples&lt;br /&gt;
|-&lt;br /&gt;
|a &amp;amp; b&lt;br /&gt;
|concatenate&lt;br /&gt;
|&amp;lt;code&amp;gt;'foo' &amp;amp; 'bar' → 'foobar'&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;'pi=' &amp;amp; Pi → 'pi=3.142'&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;(1/5) &amp;amp; (7^2) → '0.249' &amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The last two examples shown may be different when the current object's number format is different at the time the expression is evaluated. For example, when Fixed Point, 3 digits with trailing zeroes is used, &lt;br /&gt;
:&amp;lt;code&amp;gt;'pi=' &amp;amp; Pi → 'pi=3.14'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;(1/5) &amp;amp; (7^2) → '0.2049.00' &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When coercing numbers to text, you can instead use the [[NumberToText]] function, so that the number format actually used is explicit in the expression.&lt;br /&gt;
:&amp;lt;code&amp;gt;'pi=' &amp;amp; [[NumberToText]](Pi, 'Suffix', digits:15) → 'pi=3.14159265358979'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comparison operators ===&lt;br /&gt;
&lt;br /&gt;
Comparison operators apply to [[numbers]] and [[text values]] and produce [[Boolean or truth values|Boolean values]].&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Operator&lt;br /&gt;
!Meaning&lt;br /&gt;
!Examples &lt;br /&gt;
!→ (1 = true, 0 = false)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;&lt;br /&gt;
|less than&lt;br /&gt;
|&amp;lt;code&amp;gt;      2 &amp;lt; 2     &amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;   'A' &amp;lt; 'B'     &amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;→ 0&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;→ 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;=&lt;br /&gt;
|less than or equal to&lt;br /&gt;
|&amp;lt;code&amp;gt;     2 &amp;lt;= 2    &amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;'ab' &amp;lt;= 'ab'   &amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;→ 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;→ 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|=&lt;br /&gt;
|equal to&lt;br /&gt;
|&amp;lt;code&amp;gt;  100 = 101     &amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt; 'AB' = 'ab'    &amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;→ 0&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;→ 0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt;=&lt;br /&gt;
|greater than or equal to&lt;br /&gt;
|&amp;lt;code&amp;gt; 100 &amp;gt;= 1     &amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;'ab'&amp;gt; = 'cd'    &amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;→ 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;→ 0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt;&lt;br /&gt;
|greater than&lt;br /&gt;
|&amp;lt;code&amp;gt;   1 &amp;gt; 2      &amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;  'A' &amp;gt; 'a'     &amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;→ 0&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;→ 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;&amp;gt;&lt;br /&gt;
|not equal to&lt;br /&gt;
|&amp;lt;code&amp;gt;1 &amp;lt;&amp;gt; 2     &amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;'A' &amp;lt;&amp;gt; 'B' &amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;→ 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;→ 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Alphabetic ordering of text values ===&lt;br /&gt;
&lt;br /&gt;
You can apply the comparison operators, &amp;lt;.  &amp;gt;, &amp;gt;=, &amp;lt;=, or sorting functions, [[SortIndex]](d, i), [[Sort]](d, i) and [[Rank]](), to [[Text values|text values]]. They generally use alphabetical order as in a dictionary, so:&lt;br /&gt;
:&amp;lt;code&amp;gt;'Analytica' &amp;lt; 'Excel' &amp;amp;rarr; 1 (True)&amp;lt;/code&amp;gt;&lt;br /&gt;
These operators and functions are normally case sensitive, so uppercase letters precede lowercase letters:&lt;br /&gt;
:&amp;lt;code&amp;gt;'Analytica' &amp;gt; 'excel' &amp;amp;rarr; 0 (False)&amp;lt;/code&amp;gt;&lt;br /&gt;
If you want alphabetic ordering to ignore case, use [[TextUpperCase]]() or [[TextLowerCase]]() to convert all letters to the same case.&lt;br /&gt;
:&amp;lt;code&amp;gt;TextUpperCase('Analytica') &amp;lt; TextUpperCase('excel') &amp;amp;rarr; 1 (True)&amp;lt;/code&amp;gt;&lt;br /&gt;
In functions, [[SortIndex]](d, i), [[Sort]](d, i) and [[Rank]](), you can set their optional parameter «caseInsensitive» to True if you want them to ignore case.   &lt;br /&gt;
&lt;br /&gt;
Usually, digits precede letters:&lt;br /&gt;
:&amp;lt;code&amp;gt;'9' &amp;lt; 'A' &amp;amp;rarr; 1 (True)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The collation order of characters is region-specific collation, according to your language and country. It is determined by the &amp;lt;code&amp;gt;TextLocale&amp;lt;/code&amp;gt; system variable. If you want to see or change the collation order, bring up the [[Object window]] for &amp;lt;code&amp;gt;TextLocale&amp;lt;/code&amp;gt; by selecting it from the [[Definition menu|Definition]] &amp;amp;rarr; [[Definition menu (more)#System Variables submenu|System Variables submenu]], with nothing selected and while in edit mode.&lt;br /&gt;
&lt;br /&gt;
In general, the ordering of text may be different from the ordering implied by the numeric ASCII codes of the characters. For example, &amp;lt;code&amp;gt;'de' &amp;lt; 'dé' &amp;lt; 'df'&amp;lt;/code&amp;gt;, whereas the ASCII code for &amp;lt;code&amp;gt;'é'&amp;lt;/code&amp;gt; comes after the ASCII code for &amp;lt;code&amp;gt;'f'&amp;lt;/code&amp;gt;. If you want text comparisons to use simple ASCII ordering, you can set '''TextLocale''' to be &amp;lt;code&amp;gt;ANSI&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
When two [[text values]] do not contain identical character sequences, they are considered to be unequal, even if they represent the exact same text. This can happen in Unicode with combining characters. For example, an accented 'é' can be either &amp;lt;code&amp;gt;Chr(233)&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Chr(769)&amp;amp;'e'&amp;lt;/code&amp;gt;, where the Unicode &amp;lt;code&amp;gt;Chr(769)&amp;lt;/code&amp;gt; is the combining acute accent, which modifies the character that follows. Although these alternate representations of &amp;lt;code&amp;gt;'é'&amp;lt;/code&amp;gt; are non-equal, they will have the same inequality comparisons with all other text, as if they are as closely adjacent in the sort order as is possible.&lt;br /&gt;
&lt;br /&gt;
=== Logical operators ===&lt;br /&gt;
&lt;br /&gt;
Logical operators apply to [[Boolean or truth values|Boolean values]] and produce Boolean values.&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Operator&lt;br /&gt;
!Meaning&lt;br /&gt;
!Examples&lt;br /&gt;
!&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;''b1'' AND ''b2''&amp;lt;/code&amp;gt;&lt;br /&gt;
|true if both ''&amp;lt;code&amp;gt;b1&amp;lt;/code&amp;gt;'' and ''&amp;lt;code&amp;gt;b2&amp;lt;/code&amp;gt;'' are true,&lt;br /&gt;
otherwise false&lt;br /&gt;
|&amp;lt;code&amp;gt;5 &amp;gt; 0 AND 5 &amp;gt; 10&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;amp;rarr;&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;False&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;''b1'' OR ''b2''&amp;lt;/code&amp;gt;&lt;br /&gt;
|true if ''&amp;lt;code&amp;gt;b1&amp;lt;/code&amp;gt;'' or ''&amp;lt;code&amp;gt;b2&amp;lt;/code&amp;gt;'' or both are true,&lt;br /&gt;
otherwise false&lt;br /&gt;
|&amp;lt;code&amp;gt;5 &amp;gt; 0 OR 5 &amp;gt; 10&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;amp;rarr;&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;NOT ''b''&amp;lt;/code&amp;gt;&lt;br /&gt;
|true if ''&amp;lt;code&amp;gt;b&amp;lt;/code&amp;gt;'' is false, &lt;br /&gt;
otherwise false&lt;br /&gt;
|&amp;lt;code&amp;gt;NOT (5 &amp;gt; 0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;amp;rarr;&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;False&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Scoping operator (::) ===&lt;br /&gt;
&lt;br /&gt;
It is possible that a model created in a previous release might contain a variable or function with the same identifier as a new built-in variable or function. In this situation, an identifier name appearing in an expression might be ambiguous.&lt;br /&gt;
&lt;br /&gt;
Prepending &amp;lt;code&amp;gt;::&amp;lt;/code&amp;gt; to the name of a built-in function causes the reference to always refer to the built-in function. Otherwise, the identifier refers to the user’s variable or function. With this convention, existing models are not changed by the introduction of new built-in functions.&lt;br /&gt;
&lt;br /&gt;
'''Example''': Suppose a model from an older release of Analytica contains the user-defined function &amp;lt;code&amp;gt;Irr(Values, I)&amp;lt;/code&amp;gt;. Then:&lt;br /&gt;
:&amp;lt;code&amp;gt;Irr(Payments, Time)&amp;lt;/code&amp;gt;  User’s &amp;lt;code&amp;gt;Irr&amp;lt;/code&amp;gt; function&lt;br /&gt;
::&amp;lt;code&amp;gt;::Irr(Payments, Time)&amp;lt;/code&amp;gt;  The built-in function&lt;br /&gt;
&lt;br /&gt;
===Operator binding precedence===&lt;br /&gt;
&lt;br /&gt;
Analytica uses a standard precedence hierarchy resolves potential ambiguity when evaluating operators in expressions with multiple operators.  For example,&lt;br /&gt;
:&amp;lt;code&amp;gt;1/2*3 - 3^2 + 4&amp;lt;/code&amp;gt;&lt;br /&gt;
is interpreted as:&lt;br /&gt;
:&amp;lt;code&amp;gt;(((1/2)*3) - (3^2)) + 4&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It binds arithmetic operators before comparison operators and comparison operators before logical operators, and all of these before IF...THEN...ELSE ... and other language constructs, so:&lt;br /&gt;
&amp;lt;code&amp;gt;IF d + e &amp;lt; f^g OR a AND b &amp;gt; c THEN x ELSE y + z&amp;lt;/code&amp;gt;&lt;br /&gt;
is interpreted as:&lt;br /&gt;
:&amp;lt;code&amp;gt;IF (((d + e) &amp;lt; (f^g)) OR (a AND (b &amp;gt; c))) THEN x ELSE (y + z)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The binding precedence for operators, from most tightly bound to least tightly bound, is:&lt;br /&gt;
&lt;br /&gt;
# parentheses ()&lt;br /&gt;
# [[Function_calls_and_parameters|function calls]]&lt;br /&gt;
# [[Namespaces|::]]    (namespace operator)&lt;br /&gt;
# [[Index_Position_Operator%3A%3A@|@I]], [[Using_References#Reference_Operator:_.5CA|\A]], [[Using_References#.5C.5BI.2C_J.5DA|\[I]A]], [[Using_References#Dereference_Operator:_.23R|#R]].&lt;br /&gt;
# [[Index..Do#Dot_Operator:_A.I|A.I]]&lt;br /&gt;
# [[COM_Integration#The_Invoke_Method_operator|obj-&amp;gt;member]]  ([[COM Integration]])&lt;br /&gt;
# [[Not]]&lt;br /&gt;
# [[Subscript-Slice_Operator|A[I = x]]]&lt;br /&gt;
# [[Attrib of Obj]]&lt;br /&gt;
# [[Exponentiation_of_negative_numbers|^]]&lt;br /&gt;
# - (unary, negative)&lt;br /&gt;
# &amp;lt;nowiki&amp;gt;*, &amp;lt;/nowiki&amp;gt;/&lt;br /&gt;
# +, - (binary, minus)&lt;br /&gt;
# [[Sequence_Operator|m..n]]&lt;br /&gt;
# [[Comparison_Operators|&amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;=, =, &amp;lt;&amp;gt;]]&lt;br /&gt;
# [[And]]&lt;br /&gt;
# [[Or]]&lt;br /&gt;
# [[Text_Concatenation_Operator%3A_%26|&amp;amp;]] (text concatenation)&lt;br /&gt;
# [[Assignment_Operator_%3A%3D|:=]]&lt;br /&gt;
# [[If-Then-Else]], [[Ifonly-Then-Else]], [[Ifall-Then-Else]]&lt;br /&gt;
# Sequence of statements separated by semicolons, sequence of elements or parameters separated by commas&lt;br /&gt;
&lt;br /&gt;
Within each level of this hierarchy, the operators bind from left to right (left associative). For example,&lt;br /&gt;
:&amp;lt;code&amp;gt;1/2*3&amp;lt;/code&amp;gt;&lt;br /&gt;
is interpreted as:&lt;br /&gt;
:&amp;lt;code&amp;gt;(1/2)*3&amp;lt;/code&amp;gt;&lt;br /&gt;
not as&lt;br /&gt;
:&amp;lt;code&amp;gt;1/(2*3)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
* [[Comparison Operators]]&lt;br /&gt;
* [[Logical Operators]]&lt;br /&gt;
* [[Math functions]]&lt;br /&gt;
* [[Text functions]]&lt;br /&gt;
* [[Boolean or truth values]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Text values / {{PAGENAME}} / IF a THEN b ELSE c&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Fredbrunt</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Date_functions&amp;diff=62465</id>
		<title>Date functions</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Date_functions&amp;diff=62465"/>
		<updated>2025-04-12T12:40:25Z</updated>

		<summary type="html">&lt;p&gt;Fredbrunt: Reverted edits by Fredbrunt (talk) to last revision by Lchrisman&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Analytica User Guide]]&lt;br /&gt;
[[Category:Date and Time Functions]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt;Analytica User Guide &amp;gt; Text, Date, Math, and Financial Functions &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
These functions work with [[Date_and_Time_Values|date and time numbers]] — that is, the integer portion is number of days since the ''date origin'', usually Jan 1, 1904, and the fractional portion is the fraction of a day elapsed since midnight. See [[Date formats|Date numbers and the date origin]]. A date number displays as a date if you select a date format using the '''Number format''' dialog from the '''Result''' menu.&lt;br /&gt;
&lt;br /&gt;
[[MakeDate]]() generates a date number from the year, month, and day. [[DatePart]]() extracts the year, month, day, or other information from a date number. [[DateAdd]]() adds a number of days, weeks, months, or years to a date. [[Today]]() returns today’s date. {{Assista||Built-in functions that work with dates and times include: Ceil, DateAdd, DatePart, Floor, IsDateTime, MakeDate, MakeTime, ParseDate, Round, Sequence, Sleep, Today and YearFrac}}{{Assista|key|List of functions that operate on date and time numbers}}&lt;br /&gt;
&lt;br /&gt;
==MakeDate(year, month, day)==&lt;br /&gt;
Gives the date value for the date with given «year», «month», and «day». If omitted, «month» and «day» default to 1. Parameters must be positive integers.&lt;br /&gt;
&lt;br /&gt;
See also [[MakeDate]]().&lt;br /&gt;
&lt;br /&gt;
'''Examples:''' &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;MakeDate(2007, 5, 15) &amp;amp;rarr; 15-May-2007&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt; MakeDate(2000) &amp;amp;rarr; 1-Jan-2000&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Library:''' [[Special_Functions_library|Special Functions]]&lt;br /&gt;
&lt;br /&gt;
==MakeTime(h, m, s)==&lt;br /&gt;
Gives the fraction of a day elapsed since midnight for the given hour, minute and second. The hour, «h», is typically between 0 and 23 inclusive (but can be greater than 23 when encoding a duration of more than one day). Minutes «m» and seconds «s» must be between 0 and 59 inclusive.&lt;br /&gt;
&lt;br /&gt;
See also [[MakeTime]]().&lt;br /&gt;
&lt;br /&gt;
'''Examples:''' &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;MakeTime(12, 0, 0) &amp;amp;rarr; 0.5&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;MakeTime(15, 30, 0) &amp;amp;rarr; 0.6458 {3:30:00 pm}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Library:''' Special Functions&lt;br /&gt;
&lt;br /&gt;
==DatePart(date, part)==&lt;br /&gt;
Given a date-time value «date», [[DatePart]]() returns the year, month, day, hour, minute, or seconds as a number, according to the value of «part», which must be an uppercase character:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;Y&amp;lt;/code&amp;gt; gives the four digit year as a number, such as 2006.&lt;br /&gt;
* &amp;lt;code&amp;gt;Q&amp;lt;/code&amp;gt; gives the quarter as a number between 1 and 4.&lt;br /&gt;
* &amp;lt;code&amp;gt;M&amp;lt;/code&amp;gt; gives the month as a number between 1 and 12.&lt;br /&gt;
* &amp;lt;code&amp;gt;D&amp;lt;/code&amp;gt; gives the day as number between 1 and 31.&lt;br /&gt;
* &amp;lt;code&amp;gt;W&amp;lt;/code&amp;gt; gives the day of the week as a number from 1 (Sunday) to 7 (Saturday).&lt;br /&gt;
* &amp;lt;code&amp;gt;H&amp;lt;/code&amp;gt; gives the hour on a 24-hour clock (0 to 23).&lt;br /&gt;
* &amp;lt;code&amp;gt;h&amp;lt;/code&amp;gt; gives the hour on a 12-hour close (1 to 12).&lt;br /&gt;
* &amp;lt;code&amp;gt;m&amp;lt;/code&amp;gt; gives the minutes (0 to 59).&lt;br /&gt;
* &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; gives the seconds (0 to 59.99).&lt;br /&gt;
&lt;br /&gt;
Other date options for «part» are: &amp;lt;code&amp;gt;YY &amp;amp;rarr; '06', MM &amp;amp;rarr;'01', MMM &amp;amp;rarr; 'Jan', MMMM &amp;amp;rarr; 'January', DD &amp;amp;rarr; '09', ddd &amp;amp;rarr; '1st', dddd &amp;amp;rarr; 'first', Dddd &amp;amp;rarr; 'First', www &amp;amp;rarr; 'Mon', wwww &amp;amp;rarr; 'Monday'&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;q &amp;amp;rarr; 1 to 4&amp;lt;/code&amp;gt; for number of quarter of the year.&lt;br /&gt;
&lt;br /&gt;
Other time options for «part» are: &amp;lt;code&amp;gt;HH &amp;amp;rarr; '15', hh &amp;amp;rarr; '03', mm &amp;amp;rarr;'05'&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;ss &amp;amp;rarr;'00'&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[DatePart]]() can also weeks or weekdays elapsed since the date origin or in the current year.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;wd&amp;lt;/code&amp;gt; (or &amp;lt;code&amp;gt;wd+&amp;lt;/code&amp;gt;) gives the number of weekdays since the date origin including the indicated day.&lt;br /&gt;
* &amp;lt;code&amp;gt;wd-&amp;lt;/code&amp;gt; gives the number of weekdays since the date origin not including the indicated day.&lt;br /&gt;
* &amp;lt;code&amp;gt;#d&amp;lt;/code&amp;gt; gives the day number in the current year&lt;br /&gt;
*  &amp;lt;code&amp;gt;#w&amp;lt;/code&amp;gt; gives the week number in the current year (the week starting on Sunday)&lt;br /&gt;
* &amp;lt;code&amp;gt;#wm&amp;lt;/code&amp;gt; gives the week number in the current year (the week starting on Monday)&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;#w&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;#wm&amp;lt;/code&amp;gt; options consider the week containing Jan 1 to be week 1. Options &amp;lt;code&amp;gt;e#w&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;e#wm&amp;lt;/code&amp;gt; return the European standard in which &amp;lt;code&amp;gt;week1&amp;lt;/code&amp;gt; is the first week containing at least 3 days.&lt;br /&gt;
&lt;br /&gt;
'''Examples:''' &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;DatePart(MakeDate(2006, 2, 28), 'D') &amp;amp;rarr; 28&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This makes a sequence of all weekdays between &amp;lt;code&amp;gt;Date1&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Date2&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Index J := Date1 .. Date2;&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Subset(DatePart(J, &amp;quot;W&amp;quot;) &amp;gt;= 2 AND DatePart(J, &amp;quot;W&amp;quot;) &amp;lt;= 6)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This computes the number of weekdays between two dates, including both endpoints:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;DatePart(date2, 'wd+') - DatePart(date1, 'wd-')&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Library:''' Special Functions&lt;br /&gt;
&lt;br /&gt;
==DateAdd(date, n, unit)==&lt;br /&gt;
Given a date value «date», it returns a date value offset by «n» years, months, days, weekdays, hours, minutes or seconds, according to whether «unit» is &amp;lt;code&amp;gt;Y, Q, M, D, WD, h, m&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. If «n» is negative, it subtracts units from the date.&lt;br /&gt;
&lt;br /&gt;
'''Examples:''' &lt;br /&gt;
&lt;br /&gt;
[[DateAdd]]() is especially useful for generating a sequence of dates, e.g., weeks, months, or quarters, for a time index:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;DateAdd(MakeDate(2006, 1, 1), 0 .. 12, &amp;quot;M&amp;quot;) &amp;amp;rarr; [&amp;quot;1 Jan 2006&amp;quot;, &amp;quot;1 Feb 2006&amp;quot;, &amp;quot;1 Mar 2006&amp;quot;, ... &amp;quot;1 Jan 2007&amp;quot;]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If an offset would appear to go past the end of a month, it returns the last day of the month:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;DateAdd(MakeDate(2004, 2, 29), 1, 'Y' ) &amp;amp;rarr; 2005-Feb-28&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;DateAdd(MakeDate(2006, 10, 31), 1, 'M' ) &amp;amp;rarr; 2006-Nov-30&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since the dates &amp;lt;code&amp;gt;2005-Feb-29&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;2006-Nov-31&amp;lt;/code&amp;gt; don’t exist, it gives the last day of the preceding month.&lt;br /&gt;
&lt;br /&gt;
Adding a day offset, &amp;lt;code&amp;gt;DateAdd(date, n, &amp;quot;D&amp;quot;)&amp;lt;/code&amp;gt;, is equivalent to &amp;lt;code&amp;gt;date + n&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;DateAdd(date, n, &amp;quot;WD&amp;quot;)&amp;lt;/code&amp;gt; adds the specified number of weekdays to the first weekday equal to or falling after &amp;lt;code&amp;gt;date&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Library:''' Special Functions&lt;br /&gt;
&lt;br /&gt;
==Today(''withTime, utc'')==&lt;br /&gt;
Returns the current date (or optionally date and time) as a date number — the number of days since the date origin, usually Jan 1, 1904. Unlike other functions, it gives a different value depending on what day (and time) it is evaluated. It is most often called with no parameters, [[Today]](), in which case the result is an integer representing the date in your local time zone. Including the optional parameter «withTime», &amp;lt;code&amp;gt;Today(withTime: True)&amp;lt;/code&amp;gt; returns the current time of day in the fractional part. &amp;lt;code&amp;gt;Today(withTime: true, utc: True)&amp;lt;/code&amp;gt; with the optional «utc» parameter, turns the coordinated universal date-time rather than the local date-time.&lt;br /&gt;
&lt;br /&gt;
Since variables usually cache (retain) their value after computing it, the date could become out of date if the Analytica session extends over midnight. But, it will be correct again when you restart the model.&lt;br /&gt;
&lt;br /&gt;
'''Library:''' Special Functions&lt;br /&gt;
&lt;br /&gt;
==ParseDate(date, ''badVal'')==&lt;br /&gt;
[[ParseDate]]() parses a textual date or time into a numeric value representing the number of days elapsed since the date origin. The parsing occurs independent of the number format setting for the variable being evaluated. The second optional parameter, «badVal», specifies the return value when «date» is not textual or cannot be parsed as a date. When omitted, «badVal» defaults to [[Null]].&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;ParseDate(&amp;quot;July 22, 2009&amp;quot;) &amp;amp;rarr; 2009-Jul-22 {38554}&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;ParseDate(&amp;quot;38554&amp;quot;) &amp;amp;rarr; «null»&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;ParseDate(&amp;quot;3:00 pm&amp;quot;) &amp;amp;rarr; 0.625&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;ParseDate(&amp;quot;7/22/2009 15:00:00&amp;quot;) &amp;amp;rarr; 2009-Jul-22 3:00pm {38554.625}&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Var x := [&amp;quot;hello&amp;quot;, &amp;quot;7-22-2009&amp;quot;] Do ParseDate(x, x) &amp;amp;rarr; [&amp;quot;hello&amp;quot;, 38554]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''Note:''' The results in this example assume the default date origin of 1-Jan-1904 and that Windows is set to United States regional settings.''&lt;br /&gt;
&lt;br /&gt;
==Sequence(start, end, dateUnit, step)==&lt;br /&gt;
The [[Functions_that_create_indexes#m_.._n|Sequence function]] can be used to create a sequence of dates or date-times. A date or time sequence is created when «start» and «end» are date-time numbers, or when the «dateUnit» parameter is specified. The «dateUnit» parameter can be any of &amp;lt;code&amp;gt;&amp;quot;Y&amp;quot;, &amp;quot;Q&amp;quot;, &amp;quot;M&amp;quot;, &amp;quot;D&amp;quot;, &amp;quot;WD&amp;quot;, &amp;quot;h&amp;quot;, &amp;quot;m&amp;quot;&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;&amp;quot;s&amp;quot;&amp;lt;/code&amp;gt;. Note that options &amp;lt;code&amp;gt;&amp;quot;Y&amp;quot;, &amp;quot;Q&amp;quot;, &amp;quot;M&amp;quot;&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;&amp;quot;WD&amp;quot;&amp;lt;/code&amp;gt; result in increments that have date-aware spacings, but in which the increment measured in days actually varies, due to variations in the lengths of months, the positions of weekends, and the presence of leap years.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Sequence(9-Aug-2012, 15-Aug-2012, dateUnit: &amp;quot;WD&amp;quot;) &amp;amp;rarr; [9-Aug-2012, 10-Aug-2012, 13-Aug-2012, 14-Aug-2012, 15-Aug-2012]&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Sequence(1-Jan-2012, 1-Jan-2013, dateUnit: &amp;quot;Q&amp;quot;) &amp;amp;rarr; [1-Jan-2012, 1-Apr-2012, 1-Jul-2012, 1-Oct-2012, 1-Jan-2013]&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Sequence(1-Jan-2012, 1-May-2012, dateUnit: &amp;quot;M&amp;quot;) &amp;amp;rarr; [1-Jan-2012, 1-Feb-2012, 1-Mar-2012, 1-Apr-2012, 1-May-2013]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The «step» parameter can also be specified, for example, to step in increments of 2 months. When specified with a «dateUnit» increment, «step» must be an integer value. If it is not an integer, it is rounded down.&lt;br /&gt;
&lt;br /&gt;
See also [[Sequence]]().&lt;br /&gt;
&lt;br /&gt;
==Ceil(x, dateUnit:...), Floor(x, dateUnit:...), Round(x, dateUnit:...)==&lt;br /&gt;
These rounding functions (described in [[Math functions]]) can be used to round dates or times to the nearest date unit (i.e., nearest year, month, day, weekday, hour, minute or second) by specifying the optional «dateUnit» parameter. The date unit can be one of the following values: &amp;lt;code&amp;gt;&amp;quot;Y&amp;quot;, &amp;quot;Q&amp;quot;, &amp;quot;M&amp;quot;, &amp;quot;D&amp;quot;, &amp;quot;WD&amp;quot;, &amp;quot;h&amp;quot;, &amp;quot;m&amp;quot;&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;&amp;quot;s&amp;quot;&amp;lt;/code&amp;gt;. To specify «dateUnit», you should use a named-parameter syntax.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Ceil(11-Aug-2012, dateUnit: [&amp;quot;Y&amp;quot;, &amp;quot;Q&amp;quot;, &amp;quot;WD&amp;quot;, &amp;quot;Q&amp;quot;]) &amp;amp;rarr; [1-Jan-2013, 1-Oct-2012, 1-Sep-2012, 13-Aug-2012]&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Floor(11-Aug-2012, dateUnit: [&amp;quot;Y&amp;quot;, &amp;quot;Q&amp;quot;, &amp;quot;WD&amp;quot;, &amp;quot;Q&amp;quot;]) &amp;amp;rarr; [1-Jan-2012, 1-Jul-2012, 1-Aug-2012, 10-Aug-2012]&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Round(11-Aug-2012, dateUnit:  [&amp;quot;Y&amp;quot;, &amp;quot;Q&amp;quot;, &amp;quot;WD&amp;quot;, &amp;quot;Q&amp;quot;]) &amp;amp;rarr; [1-Jan-2013, 1-Jul-2012, 1-Aug-2012, 10-Aug-2012]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See more at [[Ceil]](), [[Floor]]() and [[Round]]().&lt;br /&gt;
&lt;br /&gt;
== Sleep( ''seconds, untilTime'' ) ==&lt;br /&gt;
(''New in [[Analytica 5.0]]'') Pauses the computation either for «seconds» seconds, or until the date-time «untilTime» is reached, or both. Also forces pending redraw events to be processed when the function is called. See [[Sleep]] for details and examples.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2;-moz-column-count:2;-webkit-column-count:2&amp;quot;&amp;gt;&lt;br /&gt;
* [[Date Functions]]&lt;br /&gt;
* [[Date formats]]&lt;br /&gt;
* [[Date and Time Values]]&lt;br /&gt;
* [[Special Handling of Date Values]]&lt;br /&gt;
* [[MakeDate]]()&lt;br /&gt;
* [[MakeTime]]()&lt;br /&gt;
* [[DatePart]]()&lt;br /&gt;
* [[DateAdd]]()&lt;br /&gt;
* [[Today]]()&lt;br /&gt;
* [[ParseDate]]()&lt;br /&gt;
* [[Sequence]]()&lt;br /&gt;
* [[Ceil]]()&lt;br /&gt;
* [[Floor]]()&lt;br /&gt;
* [[Round]]()&lt;br /&gt;
* [[Sleep]]()&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Text functions / {{PAGENAME}} / Advanced math functions&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Fredbrunt</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Date_functions&amp;diff=62464</id>
		<title>Date functions</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Date_functions&amp;diff=62464"/>
		<updated>2025-04-12T12:35:49Z</updated>

		<summary type="html">&lt;p&gt;Fredbrunt: /* Sequence(start, end, dateUnit, step) */  fixed sequence example&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Analytica User Guide]]&lt;br /&gt;
[[Category:Date and Time Functions]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt;Analytica User Guide &amp;gt; Text, Date, Math, and Financial Functions &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
These functions work with [[Date_and_Time_Values|date and time numbers]] — that is, the integer portion is number of days since the ''date origin'', usually Jan 1, 1904, and the fractional portion is the fraction of a day elapsed since midnight. See [[Date formats|Date numbers and the date origin]]. A date number displays as a date if you select a date format using the '''Number format''' dialog from the '''Result''' menu.&lt;br /&gt;
&lt;br /&gt;
[[MakeDate]]() generates a date number from the year, month, and day. [[DatePart]]() extracts the year, month, day, or other information from a date number. [[DateAdd]]() adds a number of days, weeks, months, or years to a date. [[Today]]() returns today’s date. {{Assista||Built-in functions that work with dates and times include: Ceil, DateAdd, DatePart, Floor, IsDateTime, MakeDate, MakeTime, ParseDate, Round, Sequence, Sleep, Today and YearFrac}}{{Assista|key|List of functions that operate on date and time numbers}}&lt;br /&gt;
&lt;br /&gt;
==MakeDate(year, month, day)==&lt;br /&gt;
Gives the date value for the date with given «year», «month», and «day». If omitted, «month» and «day» default to 1. Parameters must be positive integers.&lt;br /&gt;
&lt;br /&gt;
See also [[MakeDate]]().&lt;br /&gt;
&lt;br /&gt;
'''Examples:''' &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;MakeDate(2007, 5, 15) &amp;amp;rarr; 15-May-2007&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt; MakeDate(2000) &amp;amp;rarr; 1-Jan-2000&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Library:''' [[Special_Functions_library|Special Functions]]&lt;br /&gt;
&lt;br /&gt;
==MakeTime(h, m, s)==&lt;br /&gt;
Gives the fraction of a day elapsed since midnight for the given hour, minute and second. The hour, «h», is typically between 0 and 23 inclusive (but can be greater than 23 when encoding a duration of more than one day). Minutes «m» and seconds «s» must be between 0 and 59 inclusive.&lt;br /&gt;
&lt;br /&gt;
See also [[MakeTime]]().&lt;br /&gt;
&lt;br /&gt;
'''Examples:''' &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;MakeTime(12, 0, 0) &amp;amp;rarr; 0.5&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;MakeTime(15, 30, 0) &amp;amp;rarr; 0.6458 {3:30:00 pm}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Library:''' Special Functions&lt;br /&gt;
&lt;br /&gt;
==DatePart(date, part)==&lt;br /&gt;
Given a date-time value «date», [[DatePart]]() returns the year, month, day, hour, minute, or seconds as a number, according to the value of «part», which must be an uppercase character:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;Y&amp;lt;/code&amp;gt; gives the four digit year as a number, such as 2006.&lt;br /&gt;
* &amp;lt;code&amp;gt;Q&amp;lt;/code&amp;gt; gives the quarter as a number between 1 and 4.&lt;br /&gt;
* &amp;lt;code&amp;gt;M&amp;lt;/code&amp;gt; gives the month as a number between 1 and 12.&lt;br /&gt;
* &amp;lt;code&amp;gt;D&amp;lt;/code&amp;gt; gives the day as number between 1 and 31.&lt;br /&gt;
* &amp;lt;code&amp;gt;W&amp;lt;/code&amp;gt; gives the day of the week as a number from 1 (Sunday) to 7 (Saturday).&lt;br /&gt;
* &amp;lt;code&amp;gt;H&amp;lt;/code&amp;gt; gives the hour on a 24-hour clock (0 to 23).&lt;br /&gt;
* &amp;lt;code&amp;gt;h&amp;lt;/code&amp;gt; gives the hour on a 12-hour close (1 to 12).&lt;br /&gt;
* &amp;lt;code&amp;gt;m&amp;lt;/code&amp;gt; gives the minutes (0 to 59).&lt;br /&gt;
* &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; gives the seconds (0 to 59.99).&lt;br /&gt;
&lt;br /&gt;
Other date options for «part» are: &amp;lt;code&amp;gt;YY &amp;amp;rarr; '06', MM &amp;amp;rarr;'01', MMM &amp;amp;rarr; 'Jan', MMMM &amp;amp;rarr; 'January', DD &amp;amp;rarr; '09', ddd &amp;amp;rarr; '1st', dddd &amp;amp;rarr; 'first', Dddd &amp;amp;rarr; 'First', www &amp;amp;rarr; 'Mon', wwww &amp;amp;rarr; 'Monday'&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;q &amp;amp;rarr; 1 to 4&amp;lt;/code&amp;gt; for number of quarter of the year.&lt;br /&gt;
&lt;br /&gt;
Other time options for «part» are: &amp;lt;code&amp;gt;HH &amp;amp;rarr; '15', hh &amp;amp;rarr; '03', mm &amp;amp;rarr;'05'&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;ss &amp;amp;rarr;'00'&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[DatePart]]() can also weeks or weekdays elapsed since the date origin or in the current year.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;wd&amp;lt;/code&amp;gt; (or &amp;lt;code&amp;gt;wd+&amp;lt;/code&amp;gt;) gives the number of weekdays since the date origin including the indicated day.&lt;br /&gt;
* &amp;lt;code&amp;gt;wd-&amp;lt;/code&amp;gt; gives the number of weekdays since the date origin not including the indicated day.&lt;br /&gt;
* &amp;lt;code&amp;gt;#d&amp;lt;/code&amp;gt; gives the day number in the current year&lt;br /&gt;
*  &amp;lt;code&amp;gt;#w&amp;lt;/code&amp;gt; gives the week number in the current year (the week starting on Sunday)&lt;br /&gt;
* &amp;lt;code&amp;gt;#wm&amp;lt;/code&amp;gt; gives the week number in the current year (the week starting on Monday)&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;#w&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;#wm&amp;lt;/code&amp;gt; options consider the week containing Jan 1 to be week 1. Options &amp;lt;code&amp;gt;e#w&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;e#wm&amp;lt;/code&amp;gt; return the European standard in which &amp;lt;code&amp;gt;week1&amp;lt;/code&amp;gt; is the first week containing at least 3 days.&lt;br /&gt;
&lt;br /&gt;
'''Examples:''' &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;DatePart(MakeDate(2006, 2, 28), 'D') &amp;amp;rarr; 28&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This makes a sequence of all weekdays between &amp;lt;code&amp;gt;Date1&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Date2&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Index J := Date1 .. Date2;&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Subset(DatePart(J, &amp;quot;W&amp;quot;) &amp;gt;= 2 AND DatePart(J, &amp;quot;W&amp;quot;) &amp;lt;= 6)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This computes the number of weekdays between two dates, including both endpoints:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;DatePart(date2, 'wd+') - DatePart(date1, 'wd-')&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Library:''' Special Functions&lt;br /&gt;
&lt;br /&gt;
==DateAdd(date, n, unit)==&lt;br /&gt;
Given a date value «date», it returns a date value offset by «n» years, months, days, weekdays, hours, minutes or seconds, according to whether «unit» is &amp;lt;code&amp;gt;Y, Q, M, D, WD, h, m&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. If «n» is negative, it subtracts units from the date.&lt;br /&gt;
&lt;br /&gt;
'''Examples:''' &lt;br /&gt;
&lt;br /&gt;
[[DateAdd]]() is especially useful for generating a sequence of dates, e.g., weeks, months, or quarters, for a time index:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;DateAdd(MakeDate(2006, 1, 1), 0 .. 12, &amp;quot;M&amp;quot;) &amp;amp;rarr; [&amp;quot;1 Jan 2006&amp;quot;, &amp;quot;1 Feb 2006&amp;quot;, &amp;quot;1 Mar 2006&amp;quot;, ... &amp;quot;1 Jan 2007&amp;quot;]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If an offset would appear to go past the end of a month, it returns the last day of the month:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;DateAdd(MakeDate(2004, 2, 29), 1, 'Y' ) &amp;amp;rarr; 2005-Feb-28&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;DateAdd(MakeDate(2006, 10, 31), 1, 'M' ) &amp;amp;rarr; 2006-Nov-30&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since the dates &amp;lt;code&amp;gt;2005-Feb-29&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;2006-Nov-31&amp;lt;/code&amp;gt; don’t exist, it gives the last day of the preceding month.&lt;br /&gt;
&lt;br /&gt;
Adding a day offset, &amp;lt;code&amp;gt;DateAdd(date, n, &amp;quot;D&amp;quot;)&amp;lt;/code&amp;gt;, is equivalent to &amp;lt;code&amp;gt;date + n&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;DateAdd(date, n, &amp;quot;WD&amp;quot;)&amp;lt;/code&amp;gt; adds the specified number of weekdays to the first weekday equal to or falling after &amp;lt;code&amp;gt;date&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Library:''' Special Functions&lt;br /&gt;
&lt;br /&gt;
==Today(''withTime, utc'')==&lt;br /&gt;
Returns the current date (or optionally date and time) as a date number — the number of days since the date origin, usually Jan 1, 1904. Unlike other functions, it gives a different value depending on what day (and time) it is evaluated. It is most often called with no parameters, [[Today]](), in which case the result is an integer representing the date in your local time zone. Including the optional parameter «withTime», &amp;lt;code&amp;gt;Today(withTime: True)&amp;lt;/code&amp;gt; returns the current time of day in the fractional part. &amp;lt;code&amp;gt;Today(withTime: true, utc: True)&amp;lt;/code&amp;gt; with the optional «utc» parameter, turns the coordinated universal date-time rather than the local date-time.&lt;br /&gt;
&lt;br /&gt;
Since variables usually cache (retain) their value after computing it, the date could become out of date if the Analytica session extends over midnight. But, it will be correct again when you restart the model.&lt;br /&gt;
&lt;br /&gt;
'''Library:''' Special Functions&lt;br /&gt;
&lt;br /&gt;
==ParseDate(date, ''badVal'')==&lt;br /&gt;
[[ParseDate]]() parses a textual date or time into a numeric value representing the number of days elapsed since the date origin. The parsing occurs independent of the number format setting for the variable being evaluated. The second optional parameter, «badVal», specifies the return value when «date» is not textual or cannot be parsed as a date. When omitted, «badVal» defaults to [[Null]].&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;ParseDate(&amp;quot;July 22, 2009&amp;quot;) &amp;amp;rarr; 2009-Jul-22 {38554}&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;ParseDate(&amp;quot;38554&amp;quot;) &amp;amp;rarr; «null»&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;ParseDate(&amp;quot;3:00 pm&amp;quot;) &amp;amp;rarr; 0.625&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;ParseDate(&amp;quot;7/22/2009 15:00:00&amp;quot;) &amp;amp;rarr; 2009-Jul-22 3:00pm {38554.625}&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Var x := [&amp;quot;hello&amp;quot;, &amp;quot;7-22-2009&amp;quot;] Do ParseDate(x, x) &amp;amp;rarr; [&amp;quot;hello&amp;quot;, 38554]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''Note:''' The results in this example assume the default date origin of 1-Jan-1904 and that Windows is set to United States regional settings.''&lt;br /&gt;
&lt;br /&gt;
==Sequence(start, end, dateUnit, step)==&lt;br /&gt;
The [[Functions_that_create_indexes#m_.._n|Sequence function]] can be used to create a sequence of dates or date-times. A date or time sequence is created when «start» and «end» are date-time numbers, or when the «dateUnit» parameter is specified. The «dateUnit» parameter can be any of &amp;lt;code&amp;gt;&amp;quot;Y&amp;quot;, &amp;quot;Q&amp;quot;, &amp;quot;M&amp;quot;, &amp;quot;D&amp;quot;, &amp;quot;WD&amp;quot;, &amp;quot;h&amp;quot;, &amp;quot;m&amp;quot;&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;&amp;quot;s&amp;quot;&amp;lt;/code&amp;gt;. Note that options &amp;lt;code&amp;gt;&amp;quot;Y&amp;quot;, &amp;quot;Q&amp;quot;, &amp;quot;M&amp;quot;&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;&amp;quot;WD&amp;quot;&amp;lt;/code&amp;gt; result in increments that have date-aware spacings, but in which the increment measured in days actually varies, due to variations in the lengths of months, the positions of weekends, and the presence of leap years.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Sequence(9-Aug-2012, 15-Aug-2012, dateUnit: &amp;quot;WD&amp;quot;) &amp;amp;rarr; [9-Aug-2012, 10-Aug-2012, 11-Aug-2012, 12-Aug-2012, 13-Aug-2012, 14-Aug-2012, 15-Aug-2012]&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Sequence(1-Jan-2012, 1-Jan-2013, dateUnit: &amp;quot;Q&amp;quot;) &amp;amp;rarr; [1-Jan-2012, 1-Apr-2012, 1-Jul-2012, 1-Oct-2012, 1-Jan-2013]&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Sequence(1-Jan-2012, 1-May-2012, dateUnit: &amp;quot;M&amp;quot;) &amp;amp;rarr; [1-Jan-2012, 1-Feb-2012, 1-Mar-2012, 1-Apr-2012, 1-May-2013]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The «step» parameter can also be specified, for example, to step in increments of 2 months. When specified with a «dateUnit» increment, «step» must be an integer value. If it is not an integer, it is rounded down.&lt;br /&gt;
&lt;br /&gt;
See also [[Sequence]]().&lt;br /&gt;
&lt;br /&gt;
==Ceil(x, dateUnit:...), Floor(x, dateUnit:...), Round(x, dateUnit:...)==&lt;br /&gt;
These rounding functions (described in [[Math functions]]) can be used to round dates or times to the nearest date unit (i.e., nearest year, month, day, weekday, hour, minute or second) by specifying the optional «dateUnit» parameter. The date unit can be one of the following values: &amp;lt;code&amp;gt;&amp;quot;Y&amp;quot;, &amp;quot;Q&amp;quot;, &amp;quot;M&amp;quot;, &amp;quot;D&amp;quot;, &amp;quot;WD&amp;quot;, &amp;quot;h&amp;quot;, &amp;quot;m&amp;quot;&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;&amp;quot;s&amp;quot;&amp;lt;/code&amp;gt;. To specify «dateUnit», you should use a named-parameter syntax.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Ceil(11-Aug-2012, dateUnit: [&amp;quot;Y&amp;quot;, &amp;quot;Q&amp;quot;, &amp;quot;WD&amp;quot;, &amp;quot;Q&amp;quot;]) &amp;amp;rarr; [1-Jan-2013, 1-Oct-2012, 1-Sep-2012, 13-Aug-2012]&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Floor(11-Aug-2012, dateUnit: [&amp;quot;Y&amp;quot;, &amp;quot;Q&amp;quot;, &amp;quot;WD&amp;quot;, &amp;quot;Q&amp;quot;]) &amp;amp;rarr; [1-Jan-2012, 1-Jul-2012, 1-Aug-2012, 10-Aug-2012]&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Round(11-Aug-2012, dateUnit:  [&amp;quot;Y&amp;quot;, &amp;quot;Q&amp;quot;, &amp;quot;WD&amp;quot;, &amp;quot;Q&amp;quot;]) &amp;amp;rarr; [1-Jan-2013, 1-Jul-2012, 1-Aug-2012, 10-Aug-2012]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See more at [[Ceil]](), [[Floor]]() and [[Round]]().&lt;br /&gt;
&lt;br /&gt;
== Sleep( ''seconds, untilTime'' ) ==&lt;br /&gt;
(''New in [[Analytica 5.0]]'') Pauses the computation either for «seconds» seconds, or until the date-time «untilTime» is reached, or both. Also forces pending redraw events to be processed when the function is called. See [[Sleep]] for details and examples.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2;-moz-column-count:2;-webkit-column-count:2&amp;quot;&amp;gt;&lt;br /&gt;
* [[Date Functions]]&lt;br /&gt;
* [[Date formats]]&lt;br /&gt;
* [[Date and Time Values]]&lt;br /&gt;
* [[Special Handling of Date Values]]&lt;br /&gt;
* [[MakeDate]]()&lt;br /&gt;
* [[MakeTime]]()&lt;br /&gt;
* [[DatePart]]()&lt;br /&gt;
* [[DateAdd]]()&lt;br /&gt;
* [[Today]]()&lt;br /&gt;
* [[ParseDate]]()&lt;br /&gt;
* [[Sequence]]()&lt;br /&gt;
* [[Ceil]]()&lt;br /&gt;
* [[Floor]]()&lt;br /&gt;
* [[Round]]()&lt;br /&gt;
* [[Sleep]]()&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Text functions / {{PAGENAME}} / Advanced math functions&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Fredbrunt</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Text_functions&amp;diff=62463</id>
		<title>Text functions</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Text_functions&amp;diff=62463"/>
		<updated>2025-04-12T02:45:25Z</updated>

		<summary type="html">&lt;p&gt;Fredbrunt: /* NumberToText(x, format) */ Removed space from within number so it match DTA result&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Analytica User Guide]]&lt;br /&gt;
[[Category: Text Functions]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt;Analytica User Guide &amp;gt; Text, Date, Math, and Financial Functions &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These functions work with [[text values]] (sometimes known as strings), available in the built-in Text library.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Asc(t)==&lt;br /&gt;
&lt;br /&gt;
Returns the numeric character code of the first character in text value «t». This is occasionally useful, for example to understand the alphabetic ordering of text values. Unicode characters may have values greater that 255.&lt;br /&gt;
&lt;br /&gt;
:Asc('d') &amp;amp;rarr; 100&lt;br /&gt;
:Asc('δ') &amp;amp;rarr; 948    { or, in hex, 0x3b4 }&lt;br /&gt;
&lt;br /&gt;
See also [[Asc]](t).&lt;br /&gt;
&lt;br /&gt;
==Chr(n)==&lt;br /&gt;
Returns the character corresponding to the numeric unicode code «n». [[Chr]]() and [[Asc]]() are inverses of each other, for example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Chr(65) &amp;amp;rarr; 'A', Asc(Chr(65)) &amp;amp;rarr; 65&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Asc('A') &amp;amp;rarr; 65, Chr(Asc('A')) &amp;amp;rarr; 'A'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Chr]]() is useful for creating characters that cannot easily be typed, such as ''Tab'', which is &amp;lt;code&amp;gt;Chr(9)&amp;lt;/code&amp;gt; and ''carriage return (CR)'', which is &amp;lt;code&amp;gt;Chr(13)&amp;lt;/code&amp;gt;. For example, if you read in a text file, &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, you can use&lt;br /&gt;
&amp;lt;code&amp;gt;[[SplitText]](x, Chr(13))&amp;lt;/code&amp;gt; to generate an array of lines from a multiline text file.&lt;br /&gt;
&lt;br /&gt;
==TextLength(t)==&lt;br /&gt;
Returns the number of characters in text «t».&lt;br /&gt;
&lt;br /&gt;
See also [[TextLength]]().&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;TextLength('supercalifragilisticexpialidocious') &amp;amp;rarr; 34&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==SelectText(t, m, n)==&lt;br /&gt;
Returns text containing the «m»'th through the «n»'th character of text «t» (where the first character is «m»=1). If you omit «n» it returns characters from the «m»'th through the end of «t».&lt;br /&gt;
&lt;br /&gt;
See also [[SelectText]]().&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;SelectText('One or two', 1, 3) &amp;amp;rarr; 'One'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;SelectText('One or two', 8) &amp;amp;rarr; 'two'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==FindInText(substr, text, ''start, caseInsensitive, re, return, subpattern, repeat, repeatSubpattern, repeatIndex'')==&lt;br /&gt;
Returns the position of the first occurrence of «substr» within «text», as the number of characters to the first character of text. If it can't find «substr» in text, it returns 0.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable People := 'Amy, Betty, Carla'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('Amy', People) &amp;amp;rarr; 1&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('Betty', People) &amp;amp;rarr; 6&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('Fred', People) &amp;amp;rarr; 0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Optional parameters ===&lt;br /&gt;
&lt;br /&gt;
==== CaseInsensitive ====&lt;br /&gt;
[[FindInText]]() is case-sensitive unless the optional parameter «caseInsensitive» is true:&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('amy', People) &amp;amp;rarr; 0&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('amy', People, caseInsensitive: true) &amp;amp;rarr; 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Start ====&lt;br /&gt;
The optional third parameter, «start», specifies the position to start searching at, for example, if you want to find a second occurrence of «substr» after you have found the first one.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('i','Supercalifragilisticexpialidocious') &amp;amp;rarr; 9&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('i','Supercalifragilisticexpialidocious', 10) &amp;amp;rarr; 14&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Repeat, RepeatIndex ====&lt;br /&gt;
Normally [[FindInText]]() returns information on the first match, but by using any of the three optional repeat parameters can be used to find all matches in text. When it finds multiple matches, the result is an array. If you specify&amp;lt;code&amp;gt;repeat: true&amp;lt;/code&amp;gt;, the resulthas a local index named &amp;lt;code&amp;gt;.Repeat&amp;lt;/code&amp;gt; with elements &amp;lt;code&amp;gt;1..n&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Alternatively, you can specify a preexisting index as «repeatIndex» parameter. If that index has ''n'' elements, it returns only the first ''n'' matches. &lt;br /&gt;
&lt;br /&gt;
This example parses XML text, returning an array of ages with a local index named «.Name», where the labels of the local index are the names of each person:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('&amp;lt;person.*?name = &amp;quot;(?&amp;lt;name&amp;gt;(.*?))&amp;quot;.*?&amp;gt;.*?' &amp;amp; '&amp;lt;age&amp;gt;(?&amp;lt;age&amp;gt;.*?)&amp;lt;/age&amp;gt;.*?' &amp;amp; '&amp;lt;/person&amp;gt;', xmlText, re: true, return: 'S', repeatSubpattern: 'name', subpattern: 'age')&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Re (Regular expression), Return, and Subpattern ====&lt;br /&gt;
&lt;br /&gt;
If you set optional parameter, «re», to &amp;lt;code&amp;gt;True,&amp;lt;/code&amp;gt;it interprets «substr» as a ''regular expression''. The regular expression language is widely used (not just in Analytica) to specify match criteria for text. It offers &amp;quot;wild cards&amp;quot; that match any letter, digit, or other character, identify separate words, and a lot more. See [[Regular expression]]s for details.&lt;br /&gt;
&lt;br /&gt;
Parentheses within a regular expression denote subpatterns, numbered in a depth first fashion. Subpatterns can also be named using the regular expression format “&amp;lt;code&amp;gt;(?&amp;lt;name&amp;gt;...)&amp;lt;/code&amp;gt;”. You can the match information for any subpattern by specifying the subpattern number or subpattern name in the optional «subpattern» parameter.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('d.*T', 'FindInText', re:1) &amp;amp;rarr; 4&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('d.*T', 'FindInText', re: 1, return:['L', 'S']) &amp;amp;rarr; [4, 'dInT']&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('(\d\d\d)-(\d\d\d\d)', '650-212-1212', re:1, return:'S',  subpattern:[0, 1, 2]) &amp;amp;rarr; ['212-1212', ’212’, ’1212’]&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('a*(?&amp;lt;bcd&amp;gt;b+(c+)(d*))','zyabdaabbcccfd', re:1, subpattern:['bcd', 0, 1, 2, 3]) &amp;amp;rarr; [8, 6, 8, 10, 13]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The «return» parameter alters what is returned, according to what letter you provide as the parameter:&lt;br /&gt;
&lt;br /&gt;
* ‘P’ (or ‘Position’): The position of the matching text or subpattern (default)&lt;br /&gt;
* ‘L’ (or ‘Length’): The length of the matching text or subpattern.&lt;br /&gt;
* 'S’ (or ‘Subpattern’): The text matched the regular expression or subpattern.&lt;br /&gt;
* ‘#’ (or ‘#Subpatterns’): The number of subpatterns in the regular expression.&lt;br /&gt;
&lt;br /&gt;
==TextTrim(t, ''leftOnly, rightOnly, trimChars'')==&lt;br /&gt;
Removes leading and trailing spaces from the text «t». &lt;br /&gt;
:&amp;lt;code&amp;gt;TextTrim(' Hello World ') &amp;amp;rarr; 'Hello World'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set optional parameter  «leftOnly» to True to remove only preceding spaces,  or set «rightOnly» to True to remove only followingspaces:&lt;br /&gt;
:&amp;lt;code&amp;gt;TextTrim(' Hello World ', leftOnly: True) &amp;amp;rarr; 'Hello World'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextTrim(' Hello World ', rightOnly: True) &amp;amp;rarr; ' Hello World'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To remove characters other than spaces, specify those characters in a text for  the optional «trimChars» parameter:&lt;br /&gt;
:&amp;lt;code&amp;gt;TextTrim(' [One, Two, Three] ', trimChars: ' []') &amp;amp;rarr; 'One, Two, Three'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==TextReplace(text, pattern, substr, ''all, caseInsensitive, re'')==&lt;br /&gt;
Returns text with the first occurrence of «pattern» replaced by «substr».&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;TextReplace('StringReplace, StringLength', 'String', 'Text') &amp;amp;rarr; 'TextReplace, StringLength'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If «all» is &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt;, it returns «text» with ''all'' occurrences of text «pattern» replaced by «subst».&lt;br /&gt;
:&amp;lt;code&amp;gt;TextReplace('StringReplace, StringLength', 'String', 'Text', All: True) &amp;amp;rarr; 'TextReplace, TextLength'&amp;lt;/code&amp;gt;&lt;br /&gt;
Matches are case-sensitive unless «caseInsensitive» is &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Re (Regular expression) ====&lt;br /&gt;
When the optional «re» parameter is &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt;, it treats «pattern» as a [[regular expression]]. In this mode, it replaces the character sequence &amp;lt;code&amp;gt;\0&amp;lt;/code&amp;gt; in «subst» by the matching text, and it replaces &amp;lt;code&amp;gt;\1, \2, ..., \9&amp;lt;/code&amp;gt;  by the subtext matched by the corresponding numbered subpattern in the regular expression. The character sequence &amp;lt;code&amp;gt;''&amp;lt;name&amp;gt;''&amp;lt;/code&amp;gt; in «subst» is replaced by the subtext matched to the indicated named subpattern.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;code&amp;gt;TextReplace('Hello world', '\w+', '«\0»', all:True, re: True) &amp;amp;rarr; '«Hello» «world»'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextReplace('Hello world', '(.{1, 7}).*', '\1…', re: True) &amp;amp;rarr; 'Hello w…'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextReplace(text: 'swap first and last', pattern: '(?&amp;lt;first&amp;gt;\w+)(?&amp;lt;mid&amp;gt;.*)(?&amp;lt;last&amp;gt;\b\w+)', subst:'&amp;lt;last&amp;gt;&amp;lt;mid&amp;gt;&amp;lt;first&amp;gt;', re: True) &amp;amp;rarr; 'last first and swap’&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextReplace('swap first and last', '(\w)(\w*)(\w)', '\3\2\1', re: 1, all: 1 ) &amp;amp;rarr; 'pwas tirsf dna tasl'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Joining Text: a &amp;amp; b==&lt;br /&gt;
The [[Text_Concatenation_Operator%3A_%26|&amp;amp;]] operator joins (concatenates) two text values to form a single text value, for example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;'What is the' &amp;amp; ' number' &amp;amp; '?' &amp;amp;rarr; 'What is the number?'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one or both operands are numbers, it converts them to text using the number format of the variable whose definition contains this function call (or the default suffix format if none is set), for example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;'The number is ' &amp;amp; 10^8 &amp;amp;rarr; 'The number is 100M'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is also useful for converting (or “coercing”) numbers to text. The [[NumberToText]] function is also useful for converting numbers to text when you want to specify the number format explicitly.&lt;br /&gt;
&lt;br /&gt;
The result of concatenation of text with the special value [[Null]] changed in the [[Analytica 5.0]] release:&lt;br /&gt;
:&amp;lt;code&amp;gt;'The value is ' &amp;amp; Null &amp;amp;rarr; 'The value is Null'&amp;lt;/code&amp;gt;  &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;''{in [[Analytica 5.0]] and later}''&lt;br /&gt;
:&amp;lt;code&amp;gt;'The value is ' &amp;amp; Null &amp;amp;rarr; «null»&amp;lt;/code&amp;gt; &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;''{in [[Analytica 4.6]] and earlier}''&lt;br /&gt;
&lt;br /&gt;
==JoinText(a, i, ''separator, finalSeparator, default, textForNull'')==&lt;br /&gt;
Returns the elements of array «a» joined together into a single text value over index «i». If elements of «a» are numeric, [[JoinText]]() first converts them to text using the number format settings for the variable whose definition contains this function call. For example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;I := ['A', 'B', 'C']&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(I, I) &amp;amp;rarr; 'ABC'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;A := Array(I, ['VW', 'Honda', 'BMW'])&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;B := Array(I, ['one', Null, 'two'])&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(A, I) &amp;amp;rarr; 'VWHondaBMW'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the optional parameter «separator» is specified, it is inserted as a separator between successive elements, for example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(A, I, ', ') &amp;amp;rarr; 'VW, Honda, BMW'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The optional parameter «finalSeparator», if present, specifies a different separator between the second-to-last and last elements of «a».&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(A, I, '; ', '; and ') &amp;amp;rarr; 'VW; Honda; and BMW'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Null values in «a» are ignored unless the optional parameter «textForNull» is specified.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(B, I, ', ') &amp;amp;rarr; 'one, two'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(B, I, ', ', textForNull: '') &amp;amp;rarr; 'one, , two'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(B, I, ',  ' , textForNull: 'NULL') &amp;amp;rarr; 'one, NULL, two'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The optional «default» parameter is returned when all values are ignored, or «a» has a zero length.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText([Null, Null, Null], default: Null) &amp;amp;rarr; «null»&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==SplitText(text, separator, ''caseInsensitive, re'')==&lt;br /&gt;
Returns a list of text values formed by splitting the elements of text value text at each occurrence of separator «separator». For example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;SplitText('VW, Honda, BMW', ', ') &amp;amp;rarr; ['VW', 'Honda', 'BMW']&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[SplitText]]() is the inverse of [[JoinText]](), if you use the same separators. For example:&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;code&amp;gt;Var x := SplitText('Humpty Dumpty sat on a wall.', ' ') &amp;amp;rarr; ['Humpty', 'Dumpty', 'sat', 'on', 'a', 'wall.']&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(x,  , ' ') &amp;amp;rarr; 'Humpty Dumpty sat on a wall.'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When «separator» contains letters, setting «caseInsensitive» to &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; matches in a lower/uppercase-insensitive manner. When the «re» parameter is &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt;, separator is interpreted as a Perl-compatible [[regular expression]].&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;code&amp;gt;Variable s := 'Yes, Virginia. There is a Santa Claus!'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;SplitText(s, '[\s, \.!]+', re: 1) &amp;amp;rarr; ['Yes', 'Virginia', 'There', 'is', 'a', 'Santa', 'Claus', '']&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;SplitText(TextTrim(s, trimChars: ' , .!'), '[\s, \.!]+', re:1) &amp;amp;rarr; ['Yes', 'Virginia', 'There', 'is', 'a', 'Santa', 'Claus']&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tip title=&amp;quot;Tip&amp;gt; With [[SplitText]](), «text» must be a single text value, not an array. Otherwise, it might generate an array of arrays of different length. See [[Ensuring Array Abstraction|Functions expecting atomic parameters]] on what to do if you want apply it to an array.&lt;br /&gt;
&amp;lt;/Tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==TextLowerCase(t)==&lt;br /&gt;
[[TextLowerCase]]() returns the text «t» with all letters as lowercase. For example:&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;code&amp;gt;TextLowerCase('What does XML mean?') &amp;amp;rarr;  'what does xml mean?'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==TextUpperCase(t)==&lt;br /&gt;
[[TextUpperCase]]() returns the text «t» with all letters as uppercase. For example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;TextUpperCase('What does XML mean?') &amp;amp;rarr; 'WHAT DOES XML MEAN?'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==TextSentenceCase(Text, ''preserveUC'')==&lt;br /&gt;
[[TextSentenceCase]]() returns the text «t» with the first character (if a letter) as uppercase, and any other letters as lowercase. For example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;TextSentenceCase('mary ann FRED Maylene') &amp;amp;rarr;  'Mary ann fred maylene'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextSentenceCase(SplitText('mary ann FRED Maylene', ' ')) &amp;amp;rarr; ['Mary', 'Ann', 'Fred', 'Maylene']&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextSentenceCase('they are Fred and Maylene', true) &amp;amp;rarr; 'They are Fred and Maylene'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==NumberToText(x, format)==&lt;br /&gt;
&lt;br /&gt;
NumberToText() converts number «x» to text using the specified «format». It provides all the settings and options available in the [[Number formats]] dialog for displaying a number (including a date number). &lt;br /&gt;
&lt;br /&gt;
Possible values for «format» are: &amp;lt;code&amp;gt;'Suffix', 'Exponential', 'Fixed Point', 'Integer', 'Percent', 'Date', 'Boolean'&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;'Hexadecimal'&amp;lt;/code&amp;gt;. You can just use the first letter of a format to keep it brief:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(3.45M, ['S', 'E', 'F', 'I', 'H']) &amp;amp;rarr; ['3.45M', '3.45.e+006', '3450000', '3450000', '0x34a490']&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(0.0012, ['S', 'E', 'F', 'P']) &amp;amp;rarr; ['1.2m', '1.2e-003', '0', 0.12%']&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NumberToText() offers these optional parameters:&lt;br /&gt;
&lt;br /&gt;
*«digits» specifies the precision for Suffix and Exponential formats, and the digits to the right of the decimal for Fixed Point and Percent formats, for example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(Pi, 'Suffix', digits: 5) &amp;amp;rarr; '3.1416'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(Pi, 'Fixed Point', digits: 5) &amp;amp;rarr; '3.14159'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(Pi, 'Percent', digits: 5) &amp;amp;rarr; '314.15927%'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* «showZeros» forces the inclusion of trailing zeros:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(1/4, 'Percent', digits: 2, showZeros: True) &amp;amp;rarr; '25.00%'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set «thousandsSeparators» to &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; to separate digits into groups of three:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(7^12,'I',  thousandsSeparators: True) &amp;amp;rarr; '13,841,287,201'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* «currency» specifies a template with the currency symbol and its placement relative to the number and the minus sign.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(-372, 'F', currency: ['-£#', 'US$-#', '#£-', '($#)']) &amp;amp;rarr; ['-£372', 'US$-372', '372£-', '($372)']&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* «dateFormat» provides a date format template for converting [[date numbers]] to text:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(Today(), dateFormat: 'yyyy MMMM dd (wwww)') &amp;amp;rarr; '2013 July 01 (Monday)'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* «fullPrecision»: Set this to true, to include all digits to ensure that the full precision of the number.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(Pi, fullPrecision: True) &amp;amp;rarr; '3.141592653589793'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ParseNumber(text, ''badVal'') ==&lt;br /&gt;
&lt;br /&gt;
Parses a text value into a number. (For dates, use [[ParseDate]]()). The result is independent of the number format setting. Values that are already numeric are returned. If the number is unparseable, it returns &amp;lt;code&amp;gt;Null&amp;lt;/code&amp;gt;, unless you specify a different value to the optional parameter «badVal».&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;code&amp;gt;ParseNumber('12.43K') &amp;amp;rarr; 12.43K&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;ParseNumber('hello') &amp;amp;rarr; «null»&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;ParseNumber(14.3) &amp;amp;rarr; 14.3&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 If you use &amp;lt;code&amp;gt;ParseNumber(x, x)&amp;lt;/code&amp;gt; it will simply return any unparseable text values in «x» as the original text value:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;VAR x := ['3, 214', 14, 'foo'] DO ParseNumber(x, x) &amp;amp;rarr; [ 3214, 14, 'foo']&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==TextCharacterEncode(type,text)==&lt;br /&gt;
(''New to [[Analytica 5.0]]'' ) Transforms «text» into an alternative text encoding specified by «type». The text can be ''URL encoded'' for inclusion in a URL or ''URL decoded'', ''XML encoded'', put into one of the four normalized unicode forms, or converted to or from a UTF-8 encoding. See [[TextCharacterEncode]]. &lt;br /&gt;
:&amp;lt;code&amp;gt;TextCharacterEncode('UTF-8', 'γσh') &amp;amp;rarr; 'Î³Ïh'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextCharacterDecode('-UTF-8','Î³Ïh') &amp;amp;rarr; 'γσh'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextCharacterEncode('URL','3:4 = 3/4 &amp;amp; 1/2 = 0.5') &amp;amp;rarr; '3%3A4+%3D+3%2F4+%26+1%2F2+%3D+0.5'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TextDistance(t1,t2) ==&lt;br /&gt;
(''New to [[Analytica 5.0]]'' ) Returns a distance measure indicating how different two text values are. The result is the number of edit steps (substitutions, deletions, insertions, etc.) are required to transform «t1» into «t2». Many optional parameters can be used to specify which editing operations are allowed (see [[TextDistance]]()), allowing various standard distance measures including Levenshtein distance, Demerau-Levenshtein distance, Hamming distance, and Longest common subsequence among others.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;[[TextDistance]](&amp;quot;portland&amp;quot;, &amp;quot;orlando&amp;quot;) &amp;amp;rarr; 3&amp;lt;/code&amp;gt;&lt;br /&gt;
::Note: &amp;lt;code&amp;gt;&amp;quot;portland&amp;quot; &amp;amp;rarr; &amp;quot;ortland&amp;quot; &amp;amp;rarr; &amp;quot;orland&amp;quot; &amp;amp;rarr; &amp;quot;orlando&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Data file parsing and creation functions == &lt;br /&gt;
When you exchange data with other applications (which in generally requires the [[Analytica Enterprise]] edition or better), you may need to parse the data, or put your data into a given format. Commonly used formats include CSV (which stands for Comma Separated Values, but includes other separators such as tabs), XML and JSON. The following functions can be used to parse or create data in these formats:&lt;br /&gt;
* [[ParseCSV]] and [[MakeCSV]]&lt;br /&gt;
* [[ParseJSON]] and [[MakeJSON]]&lt;br /&gt;
* The Microsoft XML DOM parser. See [[Example_Models#Extracting_Data_from_an_XML_file|Parsing an XML file]]. This uses [[COM Integration]] and requires the [[Analytica Enterprise]] edition.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;[[ParseCSV]]( [[ReadTextFile]]( &amp;quot;MyData.csv&amp;quot; ) )&amp;lt;/code&amp;gt; &amp;amp;rarr; { 2-D array indexed by local indexes &amp;lt;code&amp;gt;.Column&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;.Row&amp;lt;/code&amp;gt;}&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2;-moz-column-count:2;-webkit-column-count:2&amp;quot;&amp;gt;&lt;br /&gt;
* [[Regular Expressions]]&lt;br /&gt;
* [[Asc]]()&lt;br /&gt;
* [[Chr]]()&lt;br /&gt;
* [[TextLength]]()&lt;br /&gt;
* [[SelectText]]()&lt;br /&gt;
* [[ FindInText]]()&lt;br /&gt;
* [[TextTrim]]()&lt;br /&gt;
* [[TextReplace]]()&lt;br /&gt;
* [[Text Concatenation Operator: &amp;amp;]]&lt;br /&gt;
* [[JoinText]]()&lt;br /&gt;
* [[SplitText]]()&lt;br /&gt;
* [[TextLowerCase]]()&lt;br /&gt;
* [[TextUpperCase]]()&lt;br /&gt;
* [[TextSentenceCase]]()&lt;br /&gt;
* [[NumberToText]]()&lt;br /&gt;
* [[TextDistance]]()&lt;br /&gt;
* [[TextCharacterEncode]]()&lt;br /&gt;
* [[Numbers and text]]&lt;br /&gt;
* [[Converting Numbers to Text]]&lt;br /&gt;
* [[ParseNumber]]()&lt;br /&gt;
* [[Model File Character Encoding]]&lt;br /&gt;
* [[Read and write text files]]&lt;br /&gt;
* [[Files and Editing]]&lt;br /&gt;
* [[Multiple formats in one table]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Text, Date, Math, and Financial Functions / {{PAGENAME}} / Date functions&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Fredbrunt</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Text_functions&amp;diff=62458</id>
		<title>Text functions</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Text_functions&amp;diff=62458"/>
		<updated>2025-04-10T05:06:40Z</updated>

		<summary type="html">&lt;p&gt;Fredbrunt: /* JoinText(a, i, separator, finalSeparator, default, textForNull) */  Fixed example array values&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Analytica User Guide]]&lt;br /&gt;
[[Category: Text Functions]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt;Analytica User Guide &amp;gt; Text, Date, Math, and Financial Functions &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These functions work with [[text values]] (sometimes known as strings), available in the built-in Text library.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Asc(t)==&lt;br /&gt;
&lt;br /&gt;
Returns the numeric character code of the first character in text value «t». This is occasionally useful, for example to understand the alphabetic ordering of text values. Unicode characters may have values greater that 255.&lt;br /&gt;
&lt;br /&gt;
:Asc('d') &amp;amp;rarr; 100&lt;br /&gt;
:Asc('δ') &amp;amp;rarr; 948    { or, in hex, 0x3b4 }&lt;br /&gt;
&lt;br /&gt;
See also [[Asc]](t).&lt;br /&gt;
&lt;br /&gt;
==Chr(n)==&lt;br /&gt;
Returns the character corresponding to the numeric unicode code «n». [[Chr]]() and [[Asc]]() are inverses of each other, for example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Chr(65) &amp;amp;rarr; 'A', Asc(Chr(65)) &amp;amp;rarr; 65&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Asc('A') &amp;amp;rarr; 65, Chr(Asc('A')) &amp;amp;rarr; 'A'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Chr]]() is useful for creating characters that cannot easily be typed, such as ''Tab'', which is &amp;lt;code&amp;gt;Chr(9)&amp;lt;/code&amp;gt; and ''carriage return (CR)'', which is &amp;lt;code&amp;gt;Chr(13)&amp;lt;/code&amp;gt;. For example, if you read in a text file, &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, you can use&lt;br /&gt;
&amp;lt;code&amp;gt;[[SplitText]](x, Chr(13))&amp;lt;/code&amp;gt; to generate an array of lines from a multiline text file.&lt;br /&gt;
&lt;br /&gt;
==TextLength(t)==&lt;br /&gt;
Returns the number of characters in text «t».&lt;br /&gt;
&lt;br /&gt;
See also [[TextLength]]().&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;TextLength('supercalifragilisticexpialidocious') &amp;amp;rarr; 34&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==SelectText(t, m, n)==&lt;br /&gt;
Returns text containing the «m»'th through the «n»'th character of text «t» (where the first character is «m»=1). If you omit «n» it returns characters from the «m»'th through the end of «t».&lt;br /&gt;
&lt;br /&gt;
See also [[SelectText]]().&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;SelectText('One or two', 1, 3) &amp;amp;rarr; 'One'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;SelectText('One or two', 8) &amp;amp;rarr; 'two'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==FindInText(substr, text, ''start, caseInsensitive, re, return, subpattern, repeat, repeatSubpattern, repeatIndex'')==&lt;br /&gt;
Returns the position of the first occurrence of «substr» within «text», as the number of characters to the first character of text. If it can't find «substr» in text, it returns 0.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable People := 'Amy, Betty, Carla'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('Amy', People) &amp;amp;rarr; 1&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('Betty', People) &amp;amp;rarr; 6&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('Fred', People) &amp;amp;rarr; 0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Optional parameters ===&lt;br /&gt;
&lt;br /&gt;
==== CaseInsensitive ====&lt;br /&gt;
[[FindInText]]() is case-sensitive unless the optional parameter «caseInsensitive» is true:&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('amy', People) &amp;amp;rarr; 0&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('amy', People, caseInsensitive: true) &amp;amp;rarr; 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Start ====&lt;br /&gt;
The optional third parameter, «start», specifies the position to start searching at, for example, if you want to find a second occurrence of «substr» after you have found the first one.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('i','Supercalifragilisticexpialidocious') &amp;amp;rarr; 9&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('i','Supercalifragilisticexpialidocious', 10) &amp;amp;rarr; 14&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Repeat, RepeatIndex ====&lt;br /&gt;
Normally [[FindInText]]() returns information on the first match, but by using any of the three optional repeat parameters can be used to find all matches in text. When it finds multiple matches, the result is an array. If you specify&amp;lt;code&amp;gt;repeat: true&amp;lt;/code&amp;gt;, the resulthas a local index named &amp;lt;code&amp;gt;.Repeat&amp;lt;/code&amp;gt; with elements &amp;lt;code&amp;gt;1..n&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Alternatively, you can specify a preexisting index as «repeatIndex» parameter. If that index has ''n'' elements, it returns only the first ''n'' matches. &lt;br /&gt;
&lt;br /&gt;
This example parses XML text, returning an array of ages with a local index named «.Name», where the labels of the local index are the names of each person:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('&amp;lt;person.*?name = &amp;quot;(?&amp;lt;name&amp;gt;(.*?))&amp;quot;.*?&amp;gt;.*?' &amp;amp; '&amp;lt;age&amp;gt;(?&amp;lt;age&amp;gt;.*?)&amp;lt;/age&amp;gt;.*?' &amp;amp; '&amp;lt;/person&amp;gt;', xmlText, re: true, return: 'S', repeatSubpattern: 'name', subpattern: 'age')&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Re (Regular expression), Return, and Subpattern ====&lt;br /&gt;
&lt;br /&gt;
If you set optional parameter, «re», to &amp;lt;code&amp;gt;True,&amp;lt;/code&amp;gt;it interprets «substr» as a ''regular expression''. The regular expression language is widely used (not just in Analytica) to specify match criteria for text. It offers &amp;quot;wild cards&amp;quot; that match any letter, digit, or other character, identify separate words, and a lot more. See [[Regular expression]]s for details.&lt;br /&gt;
&lt;br /&gt;
Parentheses within a regular expression denote subpatterns, numbered in a depth first fashion. Subpatterns can also be named using the regular expression format “&amp;lt;code&amp;gt;(?&amp;lt;name&amp;gt;...)&amp;lt;/code&amp;gt;”. You can the match information for any subpattern by specifying the subpattern number or subpattern name in the optional «subpattern» parameter.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('d.*T', 'FindInText', re:1) &amp;amp;rarr; 4&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('d.*T', 'FindInText', re: 1, return:['L', 'S']) &amp;amp;rarr; [4, 'dInT']&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('(\d\d\d)-(\d\d\d\d)', '650-212-1212', re:1, return:'S',  subpattern:[0, 1, 2]) &amp;amp;rarr; ['212-1212', ’212’, ’1212’]&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('a*(?&amp;lt;bcd&amp;gt;b+(c+)(d*))','zyabdaabbcccfd', re:1, subpattern:['bcd', 0, 1, 2, 3]) &amp;amp;rarr; [8, 6, 8, 10, 13]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The «return» parameter alters what is returned, according to what letter you provide as the parameter:&lt;br /&gt;
&lt;br /&gt;
* ‘P’ (or ‘Position’): The position of the matching text or subpattern (default)&lt;br /&gt;
* ‘L’ (or ‘Length’): The length of the matching text or subpattern.&lt;br /&gt;
* 'S’ (or ‘Subpattern’): The text matched the regular expression or subpattern.&lt;br /&gt;
* ‘#’ (or ‘#Subpatterns’): The number of subpatterns in the regular expression.&lt;br /&gt;
&lt;br /&gt;
==TextTrim(t, ''leftOnly, rightOnly, trimChars'')==&lt;br /&gt;
Removes leading and trailing spaces from the text «t». &lt;br /&gt;
:&amp;lt;code&amp;gt;TextTrim(' Hello World ') &amp;amp;rarr; 'Hello World'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set optional parameter  «leftOnly» to True to remove only preceding spaces,  or set «rightOnly» to True to remove only followingspaces:&lt;br /&gt;
:&amp;lt;code&amp;gt;TextTrim(' Hello World ', leftOnly: True) &amp;amp;rarr; 'Hello World'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextTrim(' Hello World ', rightOnly: True) &amp;amp;rarr; ' Hello World'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To remove characters other than spaces, specify those characters in a text for  the optional «trimChars» parameter:&lt;br /&gt;
:&amp;lt;code&amp;gt;TextTrim(' [One, Two, Three] ', trimChars: ' []') &amp;amp;rarr; 'One, Two, Three'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==TextReplace(text, pattern, substr, ''all, caseInsensitive, re'')==&lt;br /&gt;
Returns text with the first occurrence of «pattern» replaced by «substr».&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;TextReplace('StringReplace, StringLength', 'String', 'Text') &amp;amp;rarr; 'TextReplace, StringLength'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If «all» is &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt;, it returns «text» with ''all'' occurrences of text «pattern» replaced by «subst».&lt;br /&gt;
:&amp;lt;code&amp;gt;TextReplace('StringReplace, StringLength', 'String', 'Text', All: True) &amp;amp;rarr; 'TextReplace, TextLength'&amp;lt;/code&amp;gt;&lt;br /&gt;
Matches are case-sensitive unless «caseInsensitive» is &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Re (Regular expression) ====&lt;br /&gt;
When the optional «re» parameter is &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt;, it treats «pattern» as a [[regular expression]]. In this mode, it replaces the character sequence &amp;lt;code&amp;gt;\0&amp;lt;/code&amp;gt; in «subst» by the matching text, and it replaces &amp;lt;code&amp;gt;\1, \2, ..., \9&amp;lt;/code&amp;gt;  by the subtext matched by the corresponding numbered subpattern in the regular expression. The character sequence &amp;lt;code&amp;gt;''&amp;lt;name&amp;gt;''&amp;lt;/code&amp;gt; in «subst» is replaced by the subtext matched to the indicated named subpattern.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;code&amp;gt;TextReplace('Hello world', '\w+', '«\0»', all:True, re: True) &amp;amp;rarr; '«Hello» «world»'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextReplace('Hello world', '(.{1, 7}).*', '\1…', re: True) &amp;amp;rarr; 'Hello w…'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextReplace(text: 'swap first and last', pattern: '(?&amp;lt;first&amp;gt;\w+)(?&amp;lt;mid&amp;gt;.*)(?&amp;lt;last&amp;gt;\b\w+)', subst:'&amp;lt;last&amp;gt;&amp;lt;mid&amp;gt;&amp;lt;first&amp;gt;', re: True) &amp;amp;rarr; 'last first and swap’&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextReplace('swap first and last', '(\w)(\w*)(\w)', '\3\2\1', re: 1, all: 1 ) &amp;amp;rarr; 'pwas tirsf dna tasl'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Joining Text: a &amp;amp; b==&lt;br /&gt;
The [[Text_Concatenation_Operator%3A_%26|&amp;amp;]] operator joins (concatenates) two text values to form a single text value, for example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;'What is the' &amp;amp; ' number' &amp;amp; '?' &amp;amp;rarr; 'What is the number?'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one or both operands are numbers, it converts them to text using the number format of the variable whose definition contains this function call (or the default suffix format if none is set), for example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;'The number is ' &amp;amp; 10^8 &amp;amp;rarr; 'The number is 100M'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is also useful for converting (or “coercing”) numbers to text. The [[NumberToText]] function is also useful for converting numbers to text when you want to specify the number format explicitly.&lt;br /&gt;
&lt;br /&gt;
The result of concatenation of text with the special value [[Null]] changed in the [[Analytica 5.0]] release:&lt;br /&gt;
:&amp;lt;code&amp;gt;'The value is ' &amp;amp; Null &amp;amp;rarr; 'The value is Null'&amp;lt;/code&amp;gt;  &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;''{in [[Analytica 5.0]] and later}''&lt;br /&gt;
:&amp;lt;code&amp;gt;'The value is ' &amp;amp; Null &amp;amp;rarr; «null»&amp;lt;/code&amp;gt; &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;''{in [[Analytica 4.6]] and earlier}''&lt;br /&gt;
&lt;br /&gt;
==JoinText(a, i, ''separator, finalSeparator, default, textForNull'')==&lt;br /&gt;
Returns the elements of array «a» joined together into a single text value over index «i». If elements of «a» are numeric, [[JoinText]]() first converts them to text using the number format settings for the variable whose definition contains this function call. For example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;I := ['A', 'B', 'C']&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(I, I) &amp;amp;rarr; 'ABC'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;A := Array(I, ['VW', 'Honda', 'BMW'])&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;B := Array(I, ['one', Null, 'two'])&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(A, I) &amp;amp;rarr; 'VWHondaBMW'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the optional parameter «separator» is specified, it is inserted as a separator between successive elements, for example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(A, I, ', ') &amp;amp;rarr; 'VW, Honda, BMW'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The optional parameter «finalSeparator», if present, specifies a different separator between the second-to-last and last elements of «a».&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(A, I, '; ', '; and ') &amp;amp;rarr; 'VW; Honda; and BMW'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Null values in «a» are ignored unless the optional parameter «textForNull» is specified.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(B, I, ', ') &amp;amp;rarr; 'one, two'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(B, I, ', ', textForNull: '') &amp;amp;rarr; 'one, , two'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(B, I, ',  ' , textForNull: 'NULL') &amp;amp;rarr; 'one, NULL, two'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The optional «default» parameter is returned when all values are ignored, or «a» has a zero length.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText([Null, Null, Null], default: Null) &amp;amp;rarr; «null»&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==SplitText(text, separator, ''caseInsensitive, re'')==&lt;br /&gt;
Returns a list of text values formed by splitting the elements of text value text at each occurrence of separator «separator». For example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;SplitText('VW, Honda, BMW', ', ') &amp;amp;rarr; ['VW', 'Honda', 'BMW']&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[SplitText]]() is the inverse of [[JoinText]](), if you use the same separators. For example:&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;code&amp;gt;Var x := SplitText('Humpty Dumpty sat on a wall.', ' ') &amp;amp;rarr; ['Humpty', 'Dumpty', 'sat', 'on', 'a', 'wall.']&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(x,  , ' ') &amp;amp;rarr; 'Humpty Dumpty sat on a wall.'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When «separator» contains letters, setting «caseInsensitive» to &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; matches in a lower/uppercase-insensitive manner. When the «re» parameter is &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt;, separator is interpreted as a Perl-compatible [[regular expression]].&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;code&amp;gt;Variable s := 'Yes, Virginia. There is a Santa Claus!'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;SplitText(s, '[\s, \.!]+', re: 1) &amp;amp;rarr; ['Yes', 'Virginia', 'There', 'is', 'a', 'Santa', 'Claus', '']&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;SplitText(TextTrim(s, trimChars: ' , .!'), '[\s, \.!]+', re:1) &amp;amp;rarr; ['Yes', 'Virginia', 'There', 'is', 'a', 'Santa', 'Claus']&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tip title=&amp;quot;Tip&amp;gt; With [[SplitText]](), «text» must be a single text value, not an array. Otherwise, it might generate an array of arrays of different length. See [[Ensuring Array Abstraction|Functions expecting atomic parameters]] on what to do if you want apply it to an array.&lt;br /&gt;
&amp;lt;/Tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==TextLowerCase(t)==&lt;br /&gt;
[[TextLowerCase]]() returns the text «t» with all letters as lowercase. For example:&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;code&amp;gt;TextLowerCase('What does XML mean?') &amp;amp;rarr;  'what does xml mean?'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==TextUpperCase(t)==&lt;br /&gt;
[[TextUpperCase]]() returns the text «t» with all letters as uppercase. For example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;TextUpperCase('What does XML mean?') &amp;amp;rarr; 'WHAT DOES XML MEAN?'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==TextSentenceCase(Text, ''preserveUC'')==&lt;br /&gt;
[[TextSentenceCase]]() returns the text «t» with the first character (if a letter) as uppercase, and any other letters as lowercase. For example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;TextSentenceCase('mary ann FRED Maylene') &amp;amp;rarr;  'Mary ann fred maylene'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextSentenceCase(SplitText('mary ann FRED Maylene', ' ')) &amp;amp;rarr; ['Mary', 'Ann', 'Fred', 'Maylene']&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextSentenceCase('they are Fred and Maylene', true) &amp;amp;rarr; 'They are Fred and Maylene'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==NumberToText(x, format)==&lt;br /&gt;
&lt;br /&gt;
NumberToText() converts number «x» to text using the specified «format». It provides all the settings and options available in the [[Number formats]] dialog for displaying a number (including a date number). &lt;br /&gt;
&lt;br /&gt;
Possible values for «format» are: &amp;lt;code&amp;gt;'Suffix', 'Exponential', 'Fixed Point', 'Integer', 'Percent', 'Date', 'Boolean'&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;'Hexadecimal'&amp;lt;/code&amp;gt;. You can just use the first letter of a format to keep it brief:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(3.45M, ['S', 'E', 'F', 'I', 'H']) &amp;amp;rarr; ['3.45M', '3.45.e+006', '3450000', '3450000', '0x34a490']&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(0.0012, ['S', 'E', 'F', 'P']) &amp;amp;rarr; ['1.2m', '1.2e-003', '0', 0.12%']&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NumberToText() offers these optional parameters:&lt;br /&gt;
&lt;br /&gt;
*«digits» specifies the precision for Suffix and Exponential formats, and the digits to the right of the decimal for Fixed Point and Percent formats, for example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(Pi, 'Suffix', digits: 5) &amp;amp;rarr; '3.1416'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(Pi, 'Fixed Point', digits: 5) &amp;amp;rarr; '3.14159'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(Pi, 'Percent', digits: 5) &amp;amp;rarr; '314.15927%'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* «showZeros» forces the inclusion of trailing zeros:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(1/4, 'Percent', digits: 2, showZeros: True) &amp;amp;rarr; '25.00%'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set «thousandsSeparators» to &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; to separate digits into groups of three:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(7^12,'I',  thousandsSeparators: True) &amp;amp;rarr; '13,841, 287, 201'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* «currency» specifies a template with the currency symbol and its placement relative to the number and the minus sign.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(-372, 'F', currency: ['-£#', 'US$-#', '#£-', '($#)']) &amp;amp;rarr; ['-£372', 'US$-372', '372£-', '($372)']&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* «dateFormat» provides a date format template for converting [[date numbers]] to text:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(Today(), dateFormat: 'yyyy MMMM dd (wwww)') &amp;amp;rarr; '2013 July 01 (Monday)'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* «fullPrecision»: Set this to true, to include all digits to ensure that the full precision of the number.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(Pi, fullPrecision: True) &amp;amp;rarr; '3.141592653589793'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ParseNumber(text, ''badVal'') ==&lt;br /&gt;
&lt;br /&gt;
Parses a text value into a number. (For dates, use [[ParseDate]]()). The result is independent of the number format setting. Values that are already numeric are returned. If the number is unparseable, it returns &amp;lt;code&amp;gt;Null&amp;lt;/code&amp;gt;, unless you specify a different value to the optional parameter «badVal».&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;code&amp;gt;ParseNumber('12.43K') &amp;amp;rarr; 12.43K&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;ParseNumber('hello') &amp;amp;rarr; «null»&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;ParseNumber(14.3) &amp;amp;rarr; 14.3&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 If you use &amp;lt;code&amp;gt;ParseNumber(x, x)&amp;lt;/code&amp;gt; it will simply return any unparseable text values in «x» as the original text value:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;VAR x := ['3, 214', 14, 'foo'] DO ParseNumber(x, x) &amp;amp;rarr; [ 3214, 14, 'foo']&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==TextCharacterEncode(type,text)==&lt;br /&gt;
(''New to [[Analytica 5.0]]'' ) Transforms «text» into an alternative text encoding specified by «type». The text can be ''URL encoded'' for inclusion in a URL or ''URL decoded'', ''XML encoded'', put into one of the four normalized unicode forms, or converted to or from a UTF-8 encoding. See [[TextCharacterEncode]]. &lt;br /&gt;
:&amp;lt;code&amp;gt;TextCharacterEncode('UTF-8', 'γσh') &amp;amp;rarr; 'Î³Ïh'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextCharacterDecode('-UTF-8','Î³Ïh') &amp;amp;rarr; 'γσh'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextCharacterEncode('URL','3:4 = 3/4 &amp;amp; 1/2 = 0.5') &amp;amp;rarr; '3%3A4+%3D+3%2F4+%26+1%2F2+%3D+0.5'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TextDistance(t1,t2) ==&lt;br /&gt;
(''New to [[Analytica 5.0]]'' ) Returns a distance measure indicating how different two text values are. The result is the number of edit steps (substitutions, deletions, insertions, etc.) are required to transform «t1» into «t2». Many optional parameters can be used to specify which editing operations are allowed (see [[TextDistance]]()), allowing various standard distance measures including Levenshtein distance, Demerau-Levenshtein distance, Hamming distance, and Longest common subsequence among others.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;[[TextDistance]](&amp;quot;portland&amp;quot;, &amp;quot;orlando&amp;quot;) &amp;amp;rarr; 3&amp;lt;/code&amp;gt;&lt;br /&gt;
::Note: &amp;lt;code&amp;gt;&amp;quot;portland&amp;quot; &amp;amp;rarr; &amp;quot;ortland&amp;quot; &amp;amp;rarr; &amp;quot;orland&amp;quot; &amp;amp;rarr; &amp;quot;orlando&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Data file parsing and creation functions == &lt;br /&gt;
When you exchange data with other applications (which in generally requires the [[Analytica Enterprise]] edition or better), you may need to parse the data, or put your data into a given format. Commonly used formats include CSV (which stands for Comma Separated Values, but includes other separators such as tabs), XML and JSON. The following functions can be used to parse or create data in these formats:&lt;br /&gt;
* [[ParseCSV]] and [[MakeCSV]]&lt;br /&gt;
* [[ParseJSON]] and [[MakeJSON]]&lt;br /&gt;
* The Microsoft XML DOM parser. See [[Example_Models#Extracting_Data_from_an_XML_file|Parsing an XML file]]. This uses [[COM Integration]] and requires the [[Analytica Enterprise]] edition.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;[[ParseCSV]]( [[ReadTextFile]]( &amp;quot;MyData.csv&amp;quot; ) )&amp;lt;/code&amp;gt; &amp;amp;rarr; { 2-D array indexed by local indexes &amp;lt;code&amp;gt;.Column&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;.Row&amp;lt;/code&amp;gt;}&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2;-moz-column-count:2;-webkit-column-count:2&amp;quot;&amp;gt;&lt;br /&gt;
* [[Regular Expressions]]&lt;br /&gt;
* [[Asc]]()&lt;br /&gt;
* [[Chr]]()&lt;br /&gt;
* [[TextLength]]()&lt;br /&gt;
* [[SelectText]]()&lt;br /&gt;
* [[ FindInText]]()&lt;br /&gt;
* [[TextTrim]]()&lt;br /&gt;
* [[TextReplace]]()&lt;br /&gt;
* [[Text Concatenation Operator: &amp;amp;]]&lt;br /&gt;
* [[JoinText]]()&lt;br /&gt;
* [[SplitText]]()&lt;br /&gt;
* [[TextLowerCase]]()&lt;br /&gt;
* [[TextUpperCase]]()&lt;br /&gt;
* [[TextSentenceCase]]()&lt;br /&gt;
* [[NumberToText]]()&lt;br /&gt;
* [[TextDistance]]()&lt;br /&gt;
* [[TextCharacterEncode]]()&lt;br /&gt;
* [[Numbers and text]]&lt;br /&gt;
* [[Converting Numbers to Text]]&lt;br /&gt;
* [[ParseNumber]]()&lt;br /&gt;
* [[Model File Character Encoding]]&lt;br /&gt;
* [[Read and write text files]]&lt;br /&gt;
* [[Files and Editing]]&lt;br /&gt;
* [[Multiple formats in one table]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Text, Date, Math, and Financial Functions / {{PAGENAME}} / Date functions&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Fredbrunt</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Text_functions&amp;diff=62456</id>
		<title>Text functions</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Text_functions&amp;diff=62456"/>
		<updated>2025-04-08T04:39:16Z</updated>

		<summary type="html">&lt;p&gt;Fredbrunt: /* JoinText(a, i, separator, finalSeparator, default, textForNull) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Analytica User Guide]]&lt;br /&gt;
[[Category: Text Functions]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt;Analytica User Guide &amp;gt; Text, Date, Math, and Financial Functions &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These functions work with [[text values]] (sometimes known as strings), available in the built-in Text library.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Asc(t)==&lt;br /&gt;
&lt;br /&gt;
Returns the numeric character code of the first character in text value «t». This is occasionally useful, for example to understand the alphabetic ordering of text values. Unicode characters may have values greater that 255.&lt;br /&gt;
&lt;br /&gt;
:Asc('d') &amp;amp;rarr; 100&lt;br /&gt;
:Asc('δ') &amp;amp;rarr; 948    { or, in hex, 0x3b4 }&lt;br /&gt;
&lt;br /&gt;
See also [[Asc]](t).&lt;br /&gt;
&lt;br /&gt;
==Chr(n)==&lt;br /&gt;
Returns the character corresponding to the numeric unicode code «n». [[Chr]]() and [[Asc]]() are inverses of each other, for example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Chr(65) &amp;amp;rarr; 'A', Asc(Chr(65)) &amp;amp;rarr; 65&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Asc('A') &amp;amp;rarr; 65, Chr(Asc('A')) &amp;amp;rarr; 'A'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Chr]]() is useful for creating characters that cannot easily be typed, such as ''Tab'', which is &amp;lt;code&amp;gt;Chr(9)&amp;lt;/code&amp;gt; and ''carriage return (CR)'', which is &amp;lt;code&amp;gt;Chr(13)&amp;lt;/code&amp;gt;. For example, if you read in a text file, &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, you can use&lt;br /&gt;
&amp;lt;code&amp;gt;[[SplitText]](x, Chr(13))&amp;lt;/code&amp;gt; to generate an array of lines from a multiline text file.&lt;br /&gt;
&lt;br /&gt;
==TextLength(t)==&lt;br /&gt;
Returns the number of characters in text «t».&lt;br /&gt;
&lt;br /&gt;
See also [[TextLength]]().&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;TextLength('supercalifragilisticexpialidocious') &amp;amp;rarr; 34&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==SelectText(t, m, n)==&lt;br /&gt;
Returns text containing the «m»'th through the «n»'th character of text «t» (where the first character is «m»=1). If you omit «n» it returns characters from the «m»'th through the end of «t».&lt;br /&gt;
&lt;br /&gt;
See also [[SelectText]]().&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;SelectText('One or two', 1, 3) &amp;amp;rarr; 'One'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;SelectText('One or two', 8) &amp;amp;rarr; 'two'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==FindInText(substr, text, ''start, caseInsensitive, re, return, subpattern, repeat, repeatSubpattern, repeatIndex'')==&lt;br /&gt;
Returns the position of the first occurrence of «substr» within «text», as the number of characters to the first character of text. If it can't find «substr» in text, it returns 0.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable People := 'Amy, Betty, Carla'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('Amy', People) &amp;amp;rarr; 1&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('Betty', People) &amp;amp;rarr; 6&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('Fred', People) &amp;amp;rarr; 0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Optional parameters ===&lt;br /&gt;
&lt;br /&gt;
==== CaseInsensitive ====&lt;br /&gt;
[[FindInText]]() is case-sensitive unless the optional parameter «caseInsensitive» is true:&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('amy', People) &amp;amp;rarr; 0&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('amy', People, caseInsensitive: true) &amp;amp;rarr; 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Start ====&lt;br /&gt;
The optional third parameter, «start», specifies the position to start searching at, for example, if you want to find a second occurrence of «substr» after you have found the first one.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('i','Supercalifragilisticexpialidocious') &amp;amp;rarr; 9&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('i','Supercalifragilisticexpialidocious', 10) &amp;amp;rarr; 14&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Repeat, RepeatIndex ====&lt;br /&gt;
Normally [[FindInText]]() returns information on the first match, but by using any of the three optional repeat parameters can be used to find all matches in text. When it finds multiple matches, the result is an array. If you specify&amp;lt;code&amp;gt;repeat: true&amp;lt;/code&amp;gt;, the resulthas a local index named &amp;lt;code&amp;gt;.Repeat&amp;lt;/code&amp;gt; with elements &amp;lt;code&amp;gt;1..n&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Alternatively, you can specify a preexisting index as «repeatIndex» parameter. If that index has ''n'' elements, it returns only the first ''n'' matches. &lt;br /&gt;
&lt;br /&gt;
This example parses XML text, returning an array of ages with a local index named «.Name», where the labels of the local index are the names of each person:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('&amp;lt;person.*?name = &amp;quot;(?&amp;lt;name&amp;gt;(.*?))&amp;quot;.*?&amp;gt;.*?' &amp;amp; '&amp;lt;age&amp;gt;(?&amp;lt;age&amp;gt;.*?)&amp;lt;/age&amp;gt;.*?' &amp;amp; '&amp;lt;/person&amp;gt;', xmlText, re: true, return: 'S', repeatSubpattern: 'name', subpattern: 'age')&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Re (Regular expression), Return, and Subpattern ====&lt;br /&gt;
&lt;br /&gt;
If you set optional parameter, «re», to &amp;lt;code&amp;gt;True,&amp;lt;/code&amp;gt;it interprets «substr» as a ''regular expression''. The regular expression language is widely used (not just in Analytica) to specify match criteria for text. It offers &amp;quot;wild cards&amp;quot; that match any letter, digit, or other character, identify separate words, and a lot more. See [[Regular expression]]s for details.&lt;br /&gt;
&lt;br /&gt;
Parentheses within a regular expression denote subpatterns, numbered in a depth first fashion. Subpatterns can also be named using the regular expression format “&amp;lt;code&amp;gt;(?&amp;lt;name&amp;gt;...)&amp;lt;/code&amp;gt;”. You can the match information for any subpattern by specifying the subpattern number or subpattern name in the optional «subpattern» parameter.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('d.*T', 'FindInText', re:1) &amp;amp;rarr; 4&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('d.*T', 'FindInText', re: 1, return:['L', 'S']) &amp;amp;rarr; [4, 'dInT']&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('(\d\d\d)-(\d\d\d\d)', '650-212-1212', re:1, return:'S',  subpattern:[0, 1, 2]) &amp;amp;rarr; ['212-1212', ’212’, ’1212’]&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('a*(?&amp;lt;bcd&amp;gt;b+(c+)(d*))','zyabdaabbcccfd', re:1, subpattern:['bcd', 0, 1, 2, 3]) &amp;amp;rarr; [8, 6, 8, 10, 13]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The «return» parameter alters what is returned, according to what letter you provide as the parameter:&lt;br /&gt;
&lt;br /&gt;
* ‘P’ (or ‘Position’): The position of the matching text or subpattern (default)&lt;br /&gt;
* ‘L’ (or ‘Length’): The length of the matching text or subpattern.&lt;br /&gt;
* 'S’ (or ‘Subpattern’): The text matched the regular expression or subpattern.&lt;br /&gt;
* ‘#’ (or ‘#Subpatterns’): The number of subpatterns in the regular expression.&lt;br /&gt;
&lt;br /&gt;
==TextTrim(t, ''leftOnly, rightOnly, trimChars'')==&lt;br /&gt;
Removes leading and trailing spaces from the text «t». &lt;br /&gt;
:&amp;lt;code&amp;gt;TextTrim(' Hello World ') &amp;amp;rarr; 'Hello World'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set optional parameter  «leftOnly» to True to remove only preceding spaces,  or set «rightOnly» to True to remove only followingspaces:&lt;br /&gt;
:&amp;lt;code&amp;gt;TextTrim(' Hello World ', leftOnly: True) &amp;amp;rarr; 'Hello World'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextTrim(' Hello World ', rightOnly: True) &amp;amp;rarr; ' Hello World'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To remove characters other than spaces, specify those characters in a text for  the optional «trimChars» parameter:&lt;br /&gt;
:&amp;lt;code&amp;gt;TextTrim(' [One, Two, Three] ', trimChars: ' []') &amp;amp;rarr; 'One, Two, Three'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==TextReplace(text, pattern, substr, ''all, caseInsensitive, re'')==&lt;br /&gt;
Returns text with the first occurrence of «pattern» replaced by «substr».&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;TextReplace('StringReplace, StringLength', 'String', 'Text') &amp;amp;rarr; 'TextReplace, StringLength'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If «all» is &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt;, it returns «text» with ''all'' occurrences of text «pattern» replaced by «subst».&lt;br /&gt;
:&amp;lt;code&amp;gt;TextReplace('StringReplace, StringLength', 'String', 'Text', All: True) &amp;amp;rarr; 'TextReplace, TextLength'&amp;lt;/code&amp;gt;&lt;br /&gt;
Matches are case-sensitive unless «caseInsensitive» is &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Re (Regular expression) ====&lt;br /&gt;
When the optional «re» parameter is &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt;, it treats «pattern» as a [[regular expression]]. In this mode, it replaces the character sequence &amp;lt;code&amp;gt;\0&amp;lt;/code&amp;gt; in «subst» by the matching text, and it replaces &amp;lt;code&amp;gt;\1, \2, ..., \9&amp;lt;/code&amp;gt;  by the subtext matched by the corresponding numbered subpattern in the regular expression. The character sequence &amp;lt;code&amp;gt;''&amp;lt;name&amp;gt;''&amp;lt;/code&amp;gt; in «subst» is replaced by the subtext matched to the indicated named subpattern.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;code&amp;gt;TextReplace('Hello world', '\w+', '«\0»', all:True, re: True) &amp;amp;rarr; '«Hello» «world»'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextReplace('Hello world', '(.{1, 7}).*', '\1…', re: True) &amp;amp;rarr; 'Hello w…'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextReplace(text: 'swap first and last', pattern: '(?&amp;lt;first&amp;gt;\w+)(?&amp;lt;mid&amp;gt;.*)(?&amp;lt;last&amp;gt;\b\w+)', subst:'&amp;lt;last&amp;gt;&amp;lt;mid&amp;gt;&amp;lt;first&amp;gt;', re: True) &amp;amp;rarr; 'last first and swap’&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextReplace('swap first and last', '(\w)(\w*)(\w)', '\3\2\1', re: 1, all: 1 ) &amp;amp;rarr; 'pwas tirsf dna tasl'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Joining Text: a &amp;amp; b==&lt;br /&gt;
The [[Text_Concatenation_Operator%3A_%26|&amp;amp;]] operator joins (concatenates) two text values to form a single text value, for example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;'What is the' &amp;amp; ' number' &amp;amp; '?' &amp;amp;rarr; 'What is the number?'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one or both operands are numbers, it converts them to text using the number format of the variable whose definition contains this function call (or the default suffix format if none is set), for example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;'The number is ' &amp;amp; 10^8 &amp;amp;rarr; 'The number is 100M'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is also useful for converting (or “coercing”) numbers to text. The [[NumberToText]] function is also useful for converting numbers to text when you want to specify the number format explicitly.&lt;br /&gt;
&lt;br /&gt;
The result of concatenation of text with the special value [[Null]] changed in the [[Analytica 5.0]] release:&lt;br /&gt;
:&amp;lt;code&amp;gt;'The value is ' &amp;amp; Null &amp;amp;rarr; 'The value is Null'&amp;lt;/code&amp;gt;  &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;''{in [[Analytica 5.0]] and later}''&lt;br /&gt;
:&amp;lt;code&amp;gt;'The value is ' &amp;amp; Null &amp;amp;rarr; «null»&amp;lt;/code&amp;gt; &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;''{in [[Analytica 4.6]] and earlier}''&lt;br /&gt;
&lt;br /&gt;
==JoinText(a, i, ''separator, finalSeparator, default, textForNull'')==&lt;br /&gt;
Returns the elements of array «a» joined together into a single text value over index «i». If elements of «a» are numeric, [[JoinText]]() first converts them to text using the number format settings for the variable whose definition contains this function call. For example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;I := ['A', 'B', 'C']&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(I, I) &amp;amp;rarr; 'ABC'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;A := Array(I, ['VW', 'Honda', 'BMW'])&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;B := Array(I, ['VW', Null, 'BMW'])&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(A, I) &amp;amp;rarr; 'VWHondaBMW'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the optional parameter «separator» is specified, it is inserted as a separator between successive elements, for example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(A, I, ', ') &amp;amp;rarr; 'VW, Honda, BMW'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The optional parameter «finalSeparator», if present, specifies a different separator between the second-to-last and last elements of «a».&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(A, I, '; ', '; and ') &amp;amp;rarr; 'VW; Honda; and BMW'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Null values in «a» are ignored unless the optional parameter «textForNull» is specified.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(B, I, ', ') &amp;amp;rarr; 'one, two'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(B, I, ', ', textForNull: '') &amp;amp;rarr; 'one, , two'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(B, I, ',  ' , textForNull: 'NULL') &amp;amp;rarr; 'one, NULL, two'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The optional «default» parameter is returned when all values are ignored, or «a» has a zero length.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText([Null, Null, Null], default: Null) &amp;amp;rarr; «null»&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==SplitText(text, separator, ''caseInsensitive, re'')==&lt;br /&gt;
Returns a list of text values formed by splitting the elements of text value text at each occurrence of separator «separator». For example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;SplitText('VW, Honda, BMW', ', ') &amp;amp;rarr; ['VW', 'Honda', 'BMW']&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[SplitText]]() is the inverse of [[JoinText]](), if you use the same separators. For example:&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;code&amp;gt;Var x := SplitText('Humpty Dumpty sat on a wall.', ' ') &amp;amp;rarr; ['Humpty', 'Dumpty', 'sat', 'on', 'a', 'wall.']&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(x,  , ' ') &amp;amp;rarr; 'Humpty Dumpty sat on a wall.'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When «separator» contains letters, setting «caseInsensitive» to &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; matches in a lower/uppercase-insensitive manner. When the «re» parameter is &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt;, separator is interpreted as a Perl-compatible [[regular expression]].&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;code&amp;gt;Variable s := 'Yes, Virginia. There is a Santa Claus!'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;SplitText(s, '[\s, \.!]+', re: 1) &amp;amp;rarr; ['Yes', 'Virginia', 'There', 'is', 'a', 'Santa', 'Claus', '']&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;SplitText(TextTrim(s, trimChars: ' , .!'), '[\s, \.!]+', re:1) &amp;amp;rarr; ['Yes', 'Virginia', 'There', 'is', 'a', 'Santa', 'Claus']&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tip title=&amp;quot;Tip&amp;gt; With [[SplitText]](), «text» must be a single text value, not an array. Otherwise, it might generate an array of arrays of different length. See [[Ensuring Array Abstraction|Functions expecting atomic parameters]] on what to do if you want apply it to an array.&lt;br /&gt;
&amp;lt;/Tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==TextLowerCase(t)==&lt;br /&gt;
[[TextLowerCase]]() returns the text «t» with all letters as lowercase. For example:&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;code&amp;gt;TextLowerCase('What does XML mean?') &amp;amp;rarr;  'what does xml mean?'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==TextUpperCase(t)==&lt;br /&gt;
[[TextUpperCase]]() returns the text «t» with all letters as uppercase. For example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;TextUpperCase('What does XML mean?') &amp;amp;rarr; 'WHAT DOES XML MEAN?'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==TextSentenceCase(Text, ''preserveUC'')==&lt;br /&gt;
[[TextSentenceCase]]() returns the text «t» with the first character (if a letter) as uppercase, and any other letters as lowercase. For example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;TextSentenceCase('mary ann FRED Maylene') &amp;amp;rarr;  'Mary ann fred maylene'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextSentenceCase(SplitText('mary ann FRED Maylene', ' ')) &amp;amp;rarr; ['Mary', 'Ann', 'Fred', 'Maylene']&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextSentenceCase('they are Fred and Maylene', true) &amp;amp;rarr; 'They are Fred and Maylene'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==NumberToText(x, format)==&lt;br /&gt;
&lt;br /&gt;
NumberToText() converts number «x» to text using the specified «format». It provides all the settings and options available in the [[Number formats]] dialog for displaying a number (including a date number). &lt;br /&gt;
&lt;br /&gt;
Possible values for «format» are: &amp;lt;code&amp;gt;'Suffix', 'Exponential', 'Fixed Point', 'Integer', 'Percent', 'Date', 'Boolean'&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;'Hexadecimal'&amp;lt;/code&amp;gt;. You can just use the first letter of a format to keep it brief:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(3.45M, ['S', 'E', 'F', 'I', 'H']) &amp;amp;rarr; ['3.45M', '3.45.e+006', '3450000', '3450000', '0x34a490']&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(0.0012, ['S', 'E', 'F', 'P']) &amp;amp;rarr; ['1.2m', '1.2e-003', '0', 0.12%']&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NumberToText() offers these optional parameters:&lt;br /&gt;
&lt;br /&gt;
*«digits» specifies the precision for Suffix and Exponential formats, and the digits to the right of the decimal for Fixed Point and Percent formats, for example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(Pi, 'Suffix', digits: 5) &amp;amp;rarr; '3.1416'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(Pi, 'Fixed Point', digits: 5) &amp;amp;rarr; '3.14159'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(Pi, 'Percent', digits: 5) &amp;amp;rarr; '314.15927%'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* «showZeros» forces the inclusion of trailing zeros:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(1/4, 'Percent', digits: 2, showZeros: True) &amp;amp;rarr; '25.00%'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set «thousandsSeparators» to &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; to separate digits into groups of three:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(7^12,'I',  thousandsSeparators: True) &amp;amp;rarr; '13,841, 287, 201'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* «currency» specifies a template with the currency symbol and its placement relative to the number and the minus sign.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(-372, 'F', currency: ['-£#', 'US$-#', '#£-', '($#)']) &amp;amp;rarr; ['-£372', 'US$-372', '372£-', '($372)']&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* «dateFormat» provides a date format template for converting [[date numbers]] to text:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(Today(), dateFormat: 'yyyy MMMM dd (wwww)') &amp;amp;rarr; '2013 July 01 (Monday)'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* «fullPrecision»: Set this to true, to include all digits to ensure that the full precision of the number.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(Pi, fullPrecision: True) &amp;amp;rarr; '3.141592653589793'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ParseNumber(text, ''badVal'') ==&lt;br /&gt;
&lt;br /&gt;
Parses a text value into a number. (For dates, use [[ParseDate]]()). The result is independent of the number format setting. Values that are already numeric are returned. If the number is unparseable, it returns &amp;lt;code&amp;gt;Null&amp;lt;/code&amp;gt;, unless you specify a different value to the optional parameter «badVal».&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;code&amp;gt;ParseNumber('12.43K') &amp;amp;rarr; 12.43K&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;ParseNumber('hello') &amp;amp;rarr; «null»&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;ParseNumber(14.3) &amp;amp;rarr; 14.3&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 If you use &amp;lt;code&amp;gt;ParseNumber(x, x)&amp;lt;/code&amp;gt; it will simply return any unparseable text values in «x» as the original text value:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;VAR x := ['3, 214', 14, 'foo'] DO ParseNumber(x, x) &amp;amp;rarr; [ 3214, 14, 'foo']&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==TextCharacterEncode(type,text)==&lt;br /&gt;
(''New to [[Analytica 5.0]]'' ) Transforms «text» into an alternative text encoding specified by «type». The text can be ''URL encoded'' for inclusion in a URL or ''URL decoded'', ''XML encoded'', put into one of the four normalized unicode forms, or converted to or from a UTF-8 encoding. See [[TextCharacterEncode]]. &lt;br /&gt;
:&amp;lt;code&amp;gt;TextCharacterEncode('UTF-8', 'γσh') &amp;amp;rarr; 'Î³Ïh'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextCharacterDecode('-UTF-8','Î³Ïh') &amp;amp;rarr; 'γσh'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextCharacterEncode('URL','3:4 = 3/4 &amp;amp; 1/2 = 0.5') &amp;amp;rarr; '3%3A4+%3D+3%2F4+%26+1%2F2+%3D+0.5'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TextDistance(t1,t2) ==&lt;br /&gt;
(''New to [[Analytica 5.0]]'' ) Returns a distance measure indicating how different two text values are. The result is the number of edit steps (substitutions, deletions, insertions, etc.) are required to transform «t1» into «t2». Many optional parameters can be used to specify which editing operations are allowed (see [[TextDistance]]()), allowing various standard distance measures including Levenshtein distance, Demerau-Levenshtein distance, Hamming distance, and Longest common subsequence among others.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;[[TextDistance]](&amp;quot;portland&amp;quot;, &amp;quot;orlando&amp;quot;) &amp;amp;rarr; 3&amp;lt;/code&amp;gt;&lt;br /&gt;
::Note: &amp;lt;code&amp;gt;&amp;quot;portland&amp;quot; &amp;amp;rarr; &amp;quot;ortland&amp;quot; &amp;amp;rarr; &amp;quot;orland&amp;quot; &amp;amp;rarr; &amp;quot;orlando&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Data file parsing and creation functions == &lt;br /&gt;
When you exchange data with other applications (which in generally requires the [[Analytica Enterprise]] edition or better), you may need to parse the data, or put your data into a given format. Commonly used formats include CSV (which stands for Comma Separated Values, but includes other separators such as tabs), XML and JSON. The following functions can be used to parse or create data in these formats:&lt;br /&gt;
* [[ParseCSV]] and [[MakeCSV]]&lt;br /&gt;
* [[ParseJSON]] and [[MakeJSON]]&lt;br /&gt;
* The Microsoft XML DOM parser. See [[Example_Models#Extracting_Data_from_an_XML_file|Parsing an XML file]]. This uses [[COM Integration]] and requires the [[Analytica Enterprise]] edition.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;[[ParseCSV]]( [[ReadTextFile]]( &amp;quot;MyData.csv&amp;quot; ) )&amp;lt;/code&amp;gt; &amp;amp;rarr; { 2-D array indexed by local indexes &amp;lt;code&amp;gt;.Column&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;.Row&amp;lt;/code&amp;gt;}&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2;-moz-column-count:2;-webkit-column-count:2&amp;quot;&amp;gt;&lt;br /&gt;
* [[Regular Expressions]]&lt;br /&gt;
* [[Asc]]()&lt;br /&gt;
* [[Chr]]()&lt;br /&gt;
* [[TextLength]]()&lt;br /&gt;
* [[SelectText]]()&lt;br /&gt;
* [[ FindInText]]()&lt;br /&gt;
* [[TextTrim]]()&lt;br /&gt;
* [[TextReplace]]()&lt;br /&gt;
* [[Text Concatenation Operator: &amp;amp;]]&lt;br /&gt;
* [[JoinText]]()&lt;br /&gt;
* [[SplitText]]()&lt;br /&gt;
* [[TextLowerCase]]()&lt;br /&gt;
* [[TextUpperCase]]()&lt;br /&gt;
* [[TextSentenceCase]]()&lt;br /&gt;
* [[NumberToText]]()&lt;br /&gt;
* [[TextDistance]]()&lt;br /&gt;
* [[TextCharacterEncode]]()&lt;br /&gt;
* [[Numbers and text]]&lt;br /&gt;
* [[Converting Numbers to Text]]&lt;br /&gt;
* [[ParseNumber]]()&lt;br /&gt;
* [[Model File Character Encoding]]&lt;br /&gt;
* [[Read and write text files]]&lt;br /&gt;
* [[Files and Editing]]&lt;br /&gt;
* [[Multiple formats in one table]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Text, Date, Math, and Financial Functions / {{PAGENAME}} / Date functions&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Fredbrunt</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Text_functions&amp;diff=62447</id>
		<title>Text functions</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Text_functions&amp;diff=62447"/>
		<updated>2025-04-03T05:02:18Z</updated>

		<summary type="html">&lt;p&gt;Fredbrunt: /* Re (Regular expression), Return, and Subpattern */ Fixed bad single quote character.  Replaced with proper single quote character that works in Analytica.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Analytica User Guide]]&lt;br /&gt;
[[Category: Text Functions]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt;Analytica User Guide &amp;gt; Text, Date, Math, and Financial Functions &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These functions work with [[text values]] (sometimes known as strings), available in the built-in Text library.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Asc(t)==&lt;br /&gt;
&lt;br /&gt;
Returns the numeric character code of the first character in text value «t». This is occasionally useful, for example to understand the alphabetic ordering of text values. Unicode characters may have values greater that 255.&lt;br /&gt;
&lt;br /&gt;
:Asc('d') &amp;amp;rarr; 100&lt;br /&gt;
:Asc('δ') &amp;amp;rarr; 948    { or, in hex, 0x3b4 }&lt;br /&gt;
&lt;br /&gt;
See also [[Asc]](t).&lt;br /&gt;
&lt;br /&gt;
==Chr(n)==&lt;br /&gt;
Returns the character corresponding to the numeric unicode code «n». [[Chr]]() and [[Asc]]() are inverses of each other, for example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Chr(65) &amp;amp;rarr; 'A', Asc(Chr(65)) &amp;amp;rarr; 65&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Asc('A') &amp;amp;rarr; 65, Chr(Asc('A')) &amp;amp;rarr; 'A'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Chr]]() is useful for creating characters that cannot easily be typed, such as ''Tab'', which is &amp;lt;code&amp;gt;Chr(9)&amp;lt;/code&amp;gt; and ''carriage return (CR)'', which is &amp;lt;code&amp;gt;Chr(13)&amp;lt;/code&amp;gt;. For example, if you read in a text file, &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, you can use&lt;br /&gt;
&amp;lt;code&amp;gt;[[SplitText]](x, Chr(13))&amp;lt;/code&amp;gt; to generate an array of lines from a multiline text file.&lt;br /&gt;
&lt;br /&gt;
==TextLength(t)==&lt;br /&gt;
Returns the number of characters in text «t».&lt;br /&gt;
&lt;br /&gt;
See also [[TextLength]]().&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;TextLength('supercalifragilisticexpialidocious') &amp;amp;rarr; 34&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==SelectText(t, m, n)==&lt;br /&gt;
Returns text containing the «m»'th through the «n»'th character of text «t» (where the first character is «m»=1). If you omit «n» it returns characters from the «m»'th through the end of «t».&lt;br /&gt;
&lt;br /&gt;
See also [[SelectText]]().&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;SelectText('One or two', 1, 3) &amp;amp;rarr; 'One'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;SelectText('One or two', 8) &amp;amp;rarr; 'two'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==FindInText(substr, text, ''start, caseInsensitive, re, return, subpattern, repeat, repeatSubpattern, repeatIndex'')==&lt;br /&gt;
Returns the position of the first occurrence of «substr» within «text», as the number of characters to the first character of text. If it can't find «substr» in text, it returns 0.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable People := 'Amy, Betty, Carla'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('Amy', People) &amp;amp;rarr; 1&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('Betty', People) &amp;amp;rarr; 6&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('Fred', People) &amp;amp;rarr; 0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Optional parameters ===&lt;br /&gt;
&lt;br /&gt;
==== CaseInsensitive ====&lt;br /&gt;
[[FindInText]]() is case-sensitive unless the optional parameter «caseInsensitive» is true:&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('amy', People) &amp;amp;rarr; 0&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('amy', People, caseInsensitive: true) &amp;amp;rarr; 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Start ====&lt;br /&gt;
The optional third parameter, «start», specifies the position to start searching at, for example, if you want to find a second occurrence of «substr» after you have found the first one.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('i','Supercalifragilisticexpialidocious') &amp;amp;rarr; 9&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('i','Supercalifragilisticexpialidocious', 10) &amp;amp;rarr; 14&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Repeat, RepeatIndex ====&lt;br /&gt;
Normally [[FindInText]]() returns information on the first match, but by using any of the three optional repeat parameters can be used to find all matches in text. When it finds multiple matches, the result is an array. If you specify&amp;lt;code&amp;gt;repeat: true&amp;lt;/code&amp;gt;, the resulthas a local index named &amp;lt;code&amp;gt;.Repeat&amp;lt;/code&amp;gt; with elements &amp;lt;code&amp;gt;1..n&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Alternatively, you can specify a preexisting index as «repeatIndex» parameter. If that index has ''n'' elements, it returns only the first ''n'' matches. &lt;br /&gt;
&lt;br /&gt;
This example parses XML text, returning an array of ages with a local index named «.Name», where the labels of the local index are the names of each person:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('&amp;lt;person.*?name = &amp;quot;(?&amp;lt;name&amp;gt;(.*?))&amp;quot;.*?&amp;gt;.*?' &amp;amp; '&amp;lt;age&amp;gt;(?&amp;lt;age&amp;gt;.*?)&amp;lt;/age&amp;gt;.*?' &amp;amp; '&amp;lt;/person&amp;gt;', xmlText, re: true, return: 'S', repeatSubpattern: 'name', subpattern: 'age')&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Re (Regular expression), Return, and Subpattern ====&lt;br /&gt;
&lt;br /&gt;
If you set optional parameter, «re», to &amp;lt;code&amp;gt;True,&amp;lt;/code&amp;gt;it interprets «substr» as a ''regular expression''. The regular expression language is widely used (not just in Analytica) to specify match criteria for text. It offers &amp;quot;wild cards&amp;quot; that match any letter, digit, or other character, identify separate words, and a lot more. See [[Regular expression]]s for details.&lt;br /&gt;
&lt;br /&gt;
Parentheses within a regular expression denote subpatterns, numbered in a depth first fashion. Subpatterns can also be named using the regular expression format “&amp;lt;code&amp;gt;(?&amp;lt;name&amp;gt;...)&amp;lt;/code&amp;gt;”. You can the match information for any subpattern by specifying the subpattern number or subpattern name in the optional «subpattern» parameter.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('d.*T', 'FindInText', re:1) &amp;amp;rarr; 4&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('d.*T', 'FindInText', re: 1, return:['L', 'S']) &amp;amp;rarr; [4, 'dInT']&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('(\d\d\d)-(\d\d\d\d)', '650-212-1212', re:1, return:'S',  subpattern:[0, 1, 2]) &amp;amp;rarr; ['212-1212', ’212’, ’1212’]&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FindInText('a*(?&amp;lt;bcd&amp;gt;b+(c+)(d*))','zyabdaabbcccfd', re:1, subpattern:['bcd', 0, 1, 2, 3]) &amp;amp;rarr; [8, 6, 8, 10, 13]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The «return» parameter alters what is returned, according to what letter you provide as the parameter:&lt;br /&gt;
&lt;br /&gt;
* ‘P’ (or ‘Position’): The position of the matching text or subpattern (default)&lt;br /&gt;
* ‘L’ (or ‘Length’): The length of the matching text or subpattern.&lt;br /&gt;
* 'S’ (or ‘Subpattern’): The text matched the regular expression or subpattern.&lt;br /&gt;
* ‘#’ (or ‘#Subpatterns’): The number of subpatterns in the regular expression.&lt;br /&gt;
&lt;br /&gt;
==TextTrim(t, ''leftOnly, rightOnly, trimChars'')==&lt;br /&gt;
Removes leading and trailing spaces from the text «t». &lt;br /&gt;
:&amp;lt;code&amp;gt;TextTrim(' Hello World ') &amp;amp;rarr; 'Hello World'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set optional parameter  «leftOnly» to True to remove only preceding spaces,  or set «rightOnly» to True to remove only followingspaces:&lt;br /&gt;
:&amp;lt;code&amp;gt;TextTrim(' Hello World ', leftOnly: True) &amp;amp;rarr; 'Hello World'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextTrim(' Hello World ', rightOnly: True) &amp;amp;rarr; ' Hello World'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To remove characters other than spaces, specify those characters in a text for  the optional «trimChars» parameter:&lt;br /&gt;
:&amp;lt;code&amp;gt;TextTrim(' [One, Two, Three] ', trimChars: ' []') &amp;amp;rarr; 'One, Two, Three'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==TextReplace(text, pattern, substr, ''all, caseInsensitive, re'')==&lt;br /&gt;
Returns text with the first occurrence of «pattern» replaced by «substr».&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;TextReplace('StringReplace, StringLength', 'String', 'Text') &amp;amp;rarr; 'TextReplace, StringLength'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If «all» is &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt;, it returns «text» with ''all'' occurrences of text «pattern» replaced by «subst».&lt;br /&gt;
:&amp;lt;code&amp;gt;TextReplace('StringReplace, StringLength', 'String', 'Text', All: True) &amp;amp;rarr; 'TextReplace, TextLength'&amp;lt;/code&amp;gt;&lt;br /&gt;
Matches are case-sensitive unless «caseInsensitive» is &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Re (Regular expression) ====&lt;br /&gt;
When the optional «re» parameter is &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt;, it treats «pattern» as a [[regular expression]]. In this mode, it replaces the character sequence &amp;lt;code&amp;gt;\0&amp;lt;/code&amp;gt; in «subst» by the matching text, and it replaces &amp;lt;code&amp;gt;\1, \2, ..., \9&amp;lt;/code&amp;gt;  by the subtext matched by the corresponding numbered subpattern in the regular expression. The character sequence &amp;lt;code&amp;gt;''&amp;lt;name&amp;gt;''&amp;lt;/code&amp;gt; in «subst» is replaced by the subtext matched to the indicated named subpattern.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;code&amp;gt;TextReplace('Hello world', '\w+', '«\0»', all:True, re: True) &amp;amp;rarr; '«Hello» «world»'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextReplace('Hello world', '(.{1, 7}).*', '\1…', re: True) &amp;amp;rarr; 'Hello w…'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextReplace(text: 'swap first and last', pattern: '(?&amp;lt;first&amp;gt;\w+)(?&amp;lt;mid&amp;gt;.*)(?&amp;lt;last&amp;gt;\b\w+)', subst:'&amp;lt;last&amp;gt;&amp;lt;mid&amp;gt;&amp;lt;first&amp;gt;', re: True) &amp;amp;rarr; 'last first and swap’&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextReplace('swap first and last', '(\w)(\w*)(\w)', '\3\2\1', re: 1, all: 1 ) &amp;amp;rarr; 'pwas tirsf dna tasl'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Joining Text: a &amp;amp; b==&lt;br /&gt;
The [[Text_Concatenation_Operator%3A_%26|&amp;amp;]] operator joins (concatenates) two text values to form a single text value, for example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;'What is the' &amp;amp; ' number' &amp;amp; '?' &amp;amp;rarr; 'What is the number?'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one or both operands are numbers, it converts them to text using the number format of the variable whose definition contains this function call (or the default suffix format if none is set), for example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;'The number is ' &amp;amp; 10^8 &amp;amp;rarr; 'The number is 100M'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is also useful for converting (or “coercing”) numbers to text. The [[NumberToText]] function is also useful for converting numbers to text when you want to specify the number format explicitly.&lt;br /&gt;
&lt;br /&gt;
The result of concatenation of text with the special value [[Null]] changed in the [[Analytica 5.0]] release:&lt;br /&gt;
:&amp;lt;code&amp;gt;'The value is ' &amp;amp; Null &amp;amp;rarr; 'The value is Null'&amp;lt;/code&amp;gt;  &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;''{in [[Analytica 5.0]] and later}''&lt;br /&gt;
:&amp;lt;code&amp;gt;'The value is ' &amp;amp; Null &amp;amp;rarr; «null»&amp;lt;/code&amp;gt; &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;''{in [[Analytica 4.6]] and earlier}''&lt;br /&gt;
&lt;br /&gt;
==JoinText(a, i, ''separator, finalSeparator, default, textForNull'')==&lt;br /&gt;
Returns the elements of array «a» joined together into a single text value over index «i». If elements of «a» are numeric, [[JoinText]]() first converts them to text using the number format settings for the variable whose definition contains this function call. For example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;I := ['A', 'B', 'C']&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(I, I) &amp;amp;rarr; 'ABC'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;A := Array(I, ['VW', 'Honda', 'BMW'])&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;B := Array(I, ['VW', Null, 'BMW'])&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(A, I) &amp;amp;rarr; 'VWHondaBMW'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the optional parameter «separator» is specified, it is inserted as a separator between successive elements, for example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(A, I, ', ') &amp;amp;rarr; 'VW, Honda, BMW'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The optional parameter «finalSeparator», if present, specifies a different separator between the second-to-last and last elements of «a».&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(A, I, '; ', '; and') &amp;amp;rarr; 'VW; Honda; and BMW'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Null values in «a» are ignored unless the optional parameter «textForNull» is specified.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(B, I, ', ') &amp;amp;rarr; 'one, two'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(B, I, ', ', textForNull: '') &amp;amp;rarr; 'one, , two'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(B, I, ',  ' , textForNull: 'NULL') &amp;amp;rarr; 'one, NULL, two'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The optional «default» parameter is returned when all values are ignored, or «a» has a zero length.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText([Null, Null, Null], default: Null) &amp;amp;rarr; «null»&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==SplitText(text, separator, ''caseInsensitive, re'')==&lt;br /&gt;
Returns a list of text values formed by splitting the elements of text value text at each occurrence of separator «separator». For example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;SplitText('VW, Honda, BMW', ', ') &amp;amp;rarr; ['VW', 'Honda', 'BMW']&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[SplitText]]() is the inverse of [[JoinText]](), if you use the same separators. For example:&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;code&amp;gt;Var x := SplitText('Humpty Dumpty sat on a wall.', ' ') &amp;amp;rarr; ['Humpty', 'Dumpty', 'sat', 'on', 'a', 'wall.']&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;JoinText(x,  , ' ') &amp;amp;rarr; 'Humpty Dumpty sat on a wall.'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When «separator» contains letters, setting «caseInsensitive» to &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; matches in a lower/uppercase-insensitive manner. When the «re» parameter is &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt;, separator is interpreted as a Perl-compatible [[regular expression]].&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;code&amp;gt;Variable s := 'Yes, Virginia. There is a Santa Claus!'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;SplitText(s, '[\s, \.!]+', re: 1) &amp;amp;rarr; ['Yes', 'Virginia', 'There', 'is', 'a', 'Santa', 'Claus', '']&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;SplitText(TextTrim(s, trimChars: ' , .!'), '[\s, \.!]+', re:1) &amp;amp;rarr; ['Yes', 'Virginia', 'There', 'is', 'a', 'Santa', 'Claus']&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tip title=&amp;quot;Tip&amp;gt; With [[SplitText]](), «text» must be a single text value, not an array. Otherwise, it might generate an array of arrays of different length. See [[Ensuring Array Abstraction|Functions expecting atomic parameters]] on what to do if you want apply it to an array.&lt;br /&gt;
&amp;lt;/Tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==TextLowerCase(t)==&lt;br /&gt;
[[TextLowerCase]]() returns the text «t» with all letters as lowercase. For example:&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;code&amp;gt;TextLowerCase('What does XML mean?') &amp;amp;rarr;  'what does xml mean?'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==TextUpperCase(t)==&lt;br /&gt;
[[TextUpperCase]]() returns the text «t» with all letters as uppercase. For example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;TextUpperCase('What does XML mean?') &amp;amp;rarr; 'WHAT DOES XML MEAN?'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==TextSentenceCase(Text, ''preserveUC'')==&lt;br /&gt;
[[TextSentenceCase]]() returns the text «t» with the first character (if a letter) as uppercase, and any other letters as lowercase. For example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;TextSentenceCase('mary ann FRED Maylene') &amp;amp;rarr;  'Mary ann fred maylene'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextSentenceCase(SplitText('mary ann FRED Maylene', ' ')) &amp;amp;rarr; ['Mary', 'Ann', 'Fred', 'Maylene']&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextSentenceCase('they are Fred and Maylene', true) &amp;amp;rarr; 'They are Fred and Maylene'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==NumberToText(x, format)==&lt;br /&gt;
&lt;br /&gt;
NumberToText() converts number «x» to text using the specified «format». It provides all the settings and options available in the [[Number formats]] dialog for displaying a number (including a date number). &lt;br /&gt;
&lt;br /&gt;
Possible values for «format» are: &amp;lt;code&amp;gt;'Suffix', 'Exponential', 'Fixed Point', 'Integer', 'Percent', 'Date', 'Boolean'&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;'Hexadecimal'&amp;lt;/code&amp;gt;. You can just use the first letter of a format to keep it brief:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(3.45M, ['S', 'E', 'F', 'I', 'H']) &amp;amp;rarr; ['3.45M', '3.45.e+006', '3450000', '3450000', '0x34a490']&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(0.0012, ['S', 'E', 'F', 'P']) &amp;amp;rarr; ['1.2m', '1.2e-003', '0', 0.12%']&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NumberToText() offers these optional parameters:&lt;br /&gt;
&lt;br /&gt;
*«digits» specifies the precision for Suffix and Exponential formats, and the digits to the right of the decimal for Fixed Point and Percent formats, for example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(Pi, 'Suffix', digits: 5) &amp;amp;rarr; '3.1416'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(Pi, 'Fixed Point', digits: 5) &amp;amp;rarr; '3.14159'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(Pi, 'Percent', digits: 5) &amp;amp;rarr; '314.15927%'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* «showZeros» forces the inclusion of trailing zeros:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(1/4, 'Percent', digits: 2, showZeros: True) &amp;amp;rarr; '25.00%'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set «thousandsSeparators» to &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; to separate digits into groups of three:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(7^12,'I',  thousandsSeparators: True) &amp;amp;rarr; '13,841, 287, 201'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* «currency» specifies a template with the currency symbol and its placement relative to the number and the minus sign.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(-372, 'F', currency: ['-£#', 'US$-#', '#£-', '($#)']) &amp;amp;rarr; ['-£372', 'US$-372', '372£-', '($372)']&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* «dateFormat» provides a date format template for converting [[date numbers]] to text:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(Today(), dateFormat: 'yyyy MMMM dd (wwww)') &amp;amp;rarr; '2013 July 01 (Monday)'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* «fullPrecision»: Set this to true, to include all digits to ensure that the full precision of the number.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;code&amp;gt;NumberToText(Pi, fullPrecision: True) &amp;amp;rarr; '3.141592653589793'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ParseNumber(text, ''badVal'') ==&lt;br /&gt;
&lt;br /&gt;
Parses a text value into a number. (For dates, use [[ParseDate]]()). The result is independent of the number format setting. Values that are already numeric are returned. If the number is unparseable, it returns &amp;lt;code&amp;gt;Null&amp;lt;/code&amp;gt;, unless you specify a different value to the optional parameter «badVal».&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;code&amp;gt;ParseNumber('12.43K') &amp;amp;rarr; 12.43K&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;ParseNumber('hello') &amp;amp;rarr; «null»&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;ParseNumber(14.3) &amp;amp;rarr; 14.3&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 If you use &amp;lt;code&amp;gt;ParseNumber(x, x)&amp;lt;/code&amp;gt; it will simply return any unparseable text values in «x» as the original text value:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;VAR x := ['3, 214', 14, 'foo'] DO ParseNumber(x, x) &amp;amp;rarr; [ 3214, 14, 'foo']&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==TextCharacterEncode(type,text)==&lt;br /&gt;
(''New to [[Analytica 5.0]]'' ) Transforms «text» into an alternative text encoding specified by «type». The text can be ''URL encoded'' for inclusion in a URL or ''URL decoded'', ''XML encoded'', put into one of the four normalized unicode forms, or converted to or from a UTF-8 encoding. See [[TextCharacterEncode]]. &lt;br /&gt;
:&amp;lt;code&amp;gt;TextCharacterEncode('UTF-8', 'γσh') &amp;amp;rarr; 'Î³Ïh'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextCharacterDecode('-UTF-8','Î³Ïh') &amp;amp;rarr; 'γσh'&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;TextCharacterEncode('URL','3:4 = 3/4 &amp;amp; 1/2 = 0.5') &amp;amp;rarr; '3%3A4+%3D+3%2F4+%26+1%2F2+%3D+0.5'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TextDistance(t1,t2) ==&lt;br /&gt;
(''New to [[Analytica 5.0]]'' ) Returns a distance measure indicating how different two text values are. The result is the number of edit steps (substitutions, deletions, insertions, etc.) are required to transform «t1» into «t2». Many optional parameters can be used to specify which editing operations are allowed (see [[TextDistance]]()), allowing various standard distance measures including Levenshtein distance, Demerau-Levenshtein distance, Hamming distance, and Longest common subsequence among others.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;[[TextDistance]](&amp;quot;portland&amp;quot;, &amp;quot;orlando&amp;quot;) &amp;amp;rarr; 3&amp;lt;/code&amp;gt;&lt;br /&gt;
::Note: &amp;lt;code&amp;gt;&amp;quot;portland&amp;quot; &amp;amp;rarr; &amp;quot;ortland&amp;quot; &amp;amp;rarr; &amp;quot;orland&amp;quot; &amp;amp;rarr; &amp;quot;orlando&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Data file parsing and creation functions == &lt;br /&gt;
When you exchange data with other applications (which in generally requires the [[Analytica Enterprise]] edition or better), you may need to parse the data, or put your data into a given format. Commonly used formats include CSV (which stands for Comma Separated Values, but includes other separators such as tabs), XML and JSON. The following functions can be used to parse or create data in these formats:&lt;br /&gt;
* [[ParseCSV]] and [[MakeCSV]]&lt;br /&gt;
* [[ParseJSON]] and [[MakeJSON]]&lt;br /&gt;
* The Microsoft XML DOM parser. See [[Example_Models#Extracting_Data_from_an_XML_file|Parsing an XML file]]. This uses [[COM Integration]] and requires the [[Analytica Enterprise]] edition.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;[[ParseCSV]]( [[ReadTextFile]]( &amp;quot;MyData.csv&amp;quot; ) )&amp;lt;/code&amp;gt; &amp;amp;rarr; { 2-D array indexed by local indexes &amp;lt;code&amp;gt;.Column&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;.Row&amp;lt;/code&amp;gt;}&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2;-moz-column-count:2;-webkit-column-count:2&amp;quot;&amp;gt;&lt;br /&gt;
* [[Regular Expressions]]&lt;br /&gt;
* [[Asc]]()&lt;br /&gt;
* [[Chr]]()&lt;br /&gt;
* [[TextLength]]()&lt;br /&gt;
* [[SelectText]]()&lt;br /&gt;
* [[ FindInText]]()&lt;br /&gt;
* [[TextTrim]]()&lt;br /&gt;
* [[TextReplace]]()&lt;br /&gt;
* [[Text Concatenation Operator: &amp;amp;]]&lt;br /&gt;
* [[JoinText]]()&lt;br /&gt;
* [[SplitText]]()&lt;br /&gt;
* [[TextLowerCase]]()&lt;br /&gt;
* [[TextUpperCase]]()&lt;br /&gt;
* [[TextSentenceCase]]()&lt;br /&gt;
* [[NumberToText]]()&lt;br /&gt;
* [[TextDistance]]()&lt;br /&gt;
* [[TextCharacterEncode]]()&lt;br /&gt;
* [[Numbers and text]]&lt;br /&gt;
* [[Converting Numbers to Text]]&lt;br /&gt;
* [[ParseNumber]]()&lt;br /&gt;
* [[Model File Character Encoding]]&lt;br /&gt;
* [[Read and write text files]]&lt;br /&gt;
* [[Files and Editing]]&lt;br /&gt;
* [[Multiple formats in one table]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Text, Date, Math, and Financial Functions / {{PAGENAME}} / Date functions&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Fredbrunt</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Error_Messages/20394&amp;diff=57195</id>
		<title>Error Messages/20394</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Error_Messages/20394&amp;diff=57195"/>
		<updated>2021-12-10T03:32:03Z</updated>

		<summary type="html">&lt;p&gt;Fredbrunt: /* Description */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Error messages]]&lt;br /&gt;
&lt;br /&gt;
== Error messages ==&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;''OLE Linking is not available in the Analytica Free 101 edition.''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt; ''If you would like to purchase Analytica Professional, which includes support for OLE linking, click the [http://www.lumina.com/shoppingcart/productorder/ Buy Analytica] link below.''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;''This file contains OLE links to external data.  OLE linking is not available in Analytica Free edition, so these links cannot be refreshed.  OLE linking is available in Analytica Professional and Analytica Enterprise.  Click on the [http://www.lumina.com/shoppingcart/productorder/ Buy Analytica] link below to upgrade.''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
[[OLE Linking| OLE linking]] allows you to create a live link between to or from data outside Analytica.  It is a lot like copy/pasting data, but in such a way that if the data changes, it is automatically refreshed.&lt;br /&gt;
&lt;br /&gt;
OLE linking is a feature that is available in all paid-for editions of Analytica (Analytica Professional, Enterprise and Optimizer).  It is not available in the Free edition.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [http://www.lumina.com/shoppingcart/productorder/ Buy Analytica]&lt;br /&gt;
* [[OLE linking]]&lt;br /&gt;
* [[Analytica User Guide]]&lt;/div&gt;</summary>
		<author><name>Fredbrunt</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Error_Messages/20394&amp;diff=57194</id>
		<title>Error Messages/20394</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Error_Messages/20394&amp;diff=57194"/>
		<updated>2021-12-10T03:31:30Z</updated>

		<summary type="html">&lt;p&gt;Fredbrunt: /* Error messages */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Error messages]]&lt;br /&gt;
&lt;br /&gt;
== Error messages ==&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;''OLE Linking is not available in the Analytica Free 101 edition.''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt; ''If you would like to purchase Analytica Professional, which includes support for OLE linking, click the [http://www.lumina.com/shoppingcart/productorder/ Buy Analytica] link below.''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;''This file contains OLE links to external data.  OLE linking is not available in Analytica Free edition, so these links cannot be refreshed.  OLE linking is available in Analytica Professional and Analytica Enterprise.  Click on the [http://www.lumina.com/shoppingcart/productorder/ Buy Analytica] link below to upgrade.''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
[[OLE Linking| OLE linking]] allows you to create a live link between to or from data outside Analytica.  It is a lot like copy/pasting data, but in such a way that if the data changes, it is automatically refreshed.&lt;br /&gt;
&lt;br /&gt;
OLE linking is a feature that is available in all paid-for editions of Analytica (Analytica Professional, Enterprise and Optimizer).  It is not available in the Free 101 edition.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [http://www.lumina.com/shoppingcart/productorder/ Buy Analytica]&lt;br /&gt;
* [[OLE linking]]&lt;br /&gt;
* [[Analytica User Guide]]&lt;/div&gt;</summary>
		<author><name>Fredbrunt</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=ACP_Style_Library&amp;diff=57111</id>
		<title>ACP Style Library</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=ACP_Style_Library&amp;diff=57111"/>
		<updated>2021-11-15T09:57:23Z</updated>

		<summary type="html">&lt;p&gt;Fredbrunt: /* How to install the ACP Style library */ minor tweak to link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica Cloud Player]]&lt;br /&gt;
{{ReleaseBar}}&lt;br /&gt;
&lt;br /&gt;
The [[Analytica Cloud Platform]] (ACP) offers a variety of user-interface styles and features useful for web applications, and not available in desktop Analytica. These include navigation styles with tabs across the top or down the left side, node styles, and Frame nodes to show tables and graphs embedded in a Diagram.  Using the '''ACP Style Library''' makes it much easier to select these styles than setting special flags and codes in the  [[AcpStyles]] attributes of the model.   You should first import this library into desktop Analytica.  {{Release||5.4| You can then select options in the library in desktop Analytica which shows previews of their effects in ACP.  &lt;br /&gt;
&lt;br /&gt;
You can see a video of the ACP Style library in use in the [https://youtu.be/OH3mYa_m0xE Analytica Cloud Player (ACP) Webinar]. }}  &lt;br /&gt;
&lt;br /&gt;
{{Release||6.0| After uploading the model into ACP, you can open the library and select styles. You will see their effects immediately in the ACP model. }}&lt;br /&gt;
&lt;br /&gt;
=== How to install the ACP Style library ===&lt;br /&gt;
&lt;br /&gt;
The ACP Style library is included as a standard Analytica library, but we recommend using '''the most recent ACP Style library version which you can download here: [[Media:ACP_style_library.ana|ACP style library.ana]],''' since there have been major enhancements recently.'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--The simplest way to add the ACP Style library is to load it from the standard Analytica libraries:&lt;br /&gt;
# Make sure you are in edit mode. &lt;br /&gt;
# Click [[File menu]] &amp;gt; '''Add Library...'''&lt;br /&gt;
# Select '''ACP Styles.ANA'''  and click '''Open''--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--Alternatively, you can download the latest version of the ACP style library from here: [[Media:ACP style library.ana]]. This version may include some more recent [[What's new in ACP?|enhancements to ACP]]. --&amp;gt;After downloading the library into a folder, you can read it into your model:&lt;br /&gt;
# Make sure you are in edit mode. &lt;br /&gt;
# Click [[File menu]] &amp;gt; '''Add Module...'''&lt;br /&gt;
# Select '''ACP Styles.ANA''' from the folder into which you saved the file and click '''Open''&lt;br /&gt;
The 'ACP Styles library' will appear in the diagram:&lt;br /&gt;
&lt;br /&gt;
{{Release||5.4|:[[File:Add styles library01.PNG]]}}&lt;br /&gt;
{{Release|6.0||:[[File:Reading ACP Style library into a model in desktop Analytica.png]]}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Release|6.0||&lt;br /&gt;
=== Upload your model into ACP ===&lt;br /&gt;
&lt;br /&gt;
Once you've imported the ACP Styles library into your model, you can use it to set ACP styles in desktop Analytica.&lt;br /&gt;
But, it's better to do in in ACP so you can immediately see the effects of each setting.&lt;br /&gt;
&lt;br /&gt;
If you have an ACP account, you can upload your model into ACP from inside Analytica on the desktop:&lt;br /&gt;
* From the '''File''' menu, select '''Publish to cloud..'''&lt;br /&gt;
&lt;br /&gt;
Otherwise, you can upload your model from inside ACP&amp;quot;&lt;br /&gt;
# Start up ACP from [https://acp.analytica.com/]&lt;br /&gt;
# Sign in (or sign up if you don't yet have an ACP account).&lt;br /&gt;
# When you see the '''Models''' tab, click the '''Upload''' button. &lt;br /&gt;
# Follow the file browser prompts to upload your model into ACP&lt;br /&gt;
# Click the name of your uploaded model to start it up in ACP.&lt;br /&gt;
&lt;br /&gt;
=== How to set ACP styles  ===&lt;br /&gt;
&lt;br /&gt;
The easiest way to see what each option does is just to select from the menu or (uncheck) the checkbox. ACP will immediately show the effect of the changed style. The Default styles for tables and graphs show in the &amp;quot;Preview result&amp;quot; just to the right. A few, like the &amp;quot;Fly-in&amp;quot; option for Index menus show the Pivot icon only when you move your cursor over the &amp;quot;Preview result&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:ACP Style library w Preview result styles.png|border]]&lt;br /&gt;
&lt;br /&gt;
You can also move your cursor over each control to see its description in a balloon, in the usual way.&lt;br /&gt;
&lt;br /&gt;
More details coming soon....&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Release||5.4| &lt;br /&gt;
&lt;br /&gt;
=== How to use the ACP Style library ===&lt;br /&gt;
&lt;br /&gt;
After installing the library into your model, double-click the '''ACP Style library''' node to view its main control panel:&lt;br /&gt;
&lt;br /&gt;
:[[File:Open Styles Library01.png]]&lt;br /&gt;
&lt;br /&gt;
Click one of these buttons to open a dialog to select those styles and options:&lt;br /&gt;
*  [[#Navigation styles]]: For tab styles, expandable module outline, window size, and other options to navigate the model in ACP.&lt;br /&gt;
* [[#Node styles]]:For styles to display nodes, balloon help.&lt;br /&gt;
* [[#Frame nodes]]: To select text nodes that display edit and result tables and graphs embedded in a user-interface diagram.&lt;br /&gt;
See below for details on each dialog.&lt;br /&gt;
&lt;br /&gt;
=== Set ACP styles in Analytica, and view them in ACP ===&lt;br /&gt;
You use the '''ACP Style library''' to set styles in Analytica on the desktop, but you can only see their effect in ACP. (The ACP Style library does show some examples of what the styles look like.)  After setting some ACP styles, you can see their full effect by uploading your model into ACP. You can do this quickly by selecting '''Publish to cloud...''' from the '''File''' menu. It lets you upload and run the model in your free individual ACP account, or in an [[ACP Group Accounts|ACP Group account]] if you have one.   &lt;br /&gt;
&lt;br /&gt;
The library is invisible in ACP. Once you have selected the ACP styles you want, you can delete the ACP Styles Library from your model. Your selections  model will remain. Tthe library file size is over 1 MB, so removing it from your model saves a little time when uploading and running the model in ACP.&lt;br /&gt;
&lt;br /&gt;
==Navigation styles==&lt;br /&gt;
&lt;br /&gt;
This dialog lets you configure the navigation style using the outline view, hierarchy header as in Analytica, or tabs across the top or down the left.  You can also control the display of some elements such as those in the banner shown above the diagram.  Click the '''Navigation styles''' button to get started.&lt;br /&gt;
&lt;br /&gt;
[[File:NavStyleButton01.png]]&lt;br /&gt;
&lt;br /&gt;
The Navigation styles dialogue window opens...&lt;br /&gt;
&lt;br /&gt;
:[[File:Navstyle pane01.png]]&lt;br /&gt;
&lt;br /&gt;
The '''Navigation style''' pulldown menu selects ways to navigate the model:  The '''Preview''' pane beneath the menus shows an example ACP interface with the options you have selected: &lt;br /&gt;
:[[File:Navstyle01.png]]&lt;br /&gt;
&lt;br /&gt;
The '''Navigation style''' options are:&lt;br /&gt;
&lt;br /&gt;
* '''Outline''': With an expandable module hierarchy (see example below) that lets you quickly find the module you want to see, similar to the [[Outline window]] in Analytica on the desktop.&lt;br /&gt;
:[[File:Outline01.png]]&lt;br /&gt;
&lt;br /&gt;
* '''Top diagram only''': Shows in ACP as a single diagram, with no Outline or hierarchy or tabs. This is useful when creating a simple Web application with a single UI, and no need for any navigation.  Prevents opening other diagrams with the [[AcpStyles#Top Diagram Only]]. flag You need to arrange, and size the diagram to display what you want users to see in ACP.&lt;br /&gt;
&lt;br /&gt;
'''Tabbed Navigation''' styles:  These show the main modules in your top model as tabs  (ordered left to right then top to bottom). It is most useful for creating a web application for  people  not familiar with Analytica. It works best when you create a few modules at the top level with user inputs and outputs, showing input tables and result tables and charts in [[#Frame nodes]]. The Navigation style menu offers these options:&lt;br /&gt;
&lt;br /&gt;
'''Single level tabs''':&lt;br /&gt;
&lt;br /&gt;
* '''Top tabs''': Display the tabs left to right across the top of the diagram. For example:&lt;br /&gt;
&lt;br /&gt;
:[[File:ACP Tabs across top01.png]]&lt;br /&gt;
&lt;br /&gt;
* Side tabs: Display the tabs in a column on the left of the diagram. For example:&lt;br /&gt;
&lt;br /&gt;
:[[File:ACP Tabs down left01.png]]&lt;br /&gt;
&lt;br /&gt;
'''Two-level hierarchical tabs''' : Modules in the main model appear as top tabs (left tabs). Modules in those top level modules appear as subtabs. When you select a top-level tab, it shows its submodules as subtabs.&lt;br /&gt;
&lt;br /&gt;
*Two top tabs&lt;br /&gt;
*Two side tabs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Other Navigation Options''' In the top pane of the Navigation style dialog: &lt;br /&gt;
&lt;br /&gt;
''These next two checkboxes are unusable - and so are hidden - when you have not selected a tabbed Navigation style.''&lt;br /&gt;
&lt;br /&gt;
*'''Include top level diagram as tab:''' Can be used only with 'Side tabs' or 'Top tabs'. You may check this checkbox to include the top model diagram as the leftmost tab for &amp;quot;Side tabs&amp;quot;, or top tab for &amp;quot;Top tabs&amp;quot;. If you uncheck this checkbox, the top diagram will not display in ACP, so you include the key user interface pages as modules in the main model. Currently for 2 level tabs it is required to exclude the top diagram from the tabs, so this checkbox is hidden.  [[AcpStyles#Exclude_the_top_level_diagram_from_tabs| More...]]&lt;br /&gt;
&lt;br /&gt;
:[[File:Show as tab01.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Show hierarchy''': Lists the titles of the top, ancestor, parent, and current modules to show where you are in a model (see example below). You can click any ancestor to move up the module hierarchy, similar to the [[Show module hierarchy]] in Analytica on the desktop. Note that, to save screen space, the hierarchy does not display when it would be redundant, showing the same information displayed on the top tabs or side tabs, i.e. in the top levels of the model. The Show Hierarchy style is controlled by a checkbox in the Edit menu's preferences dialog in Desktop Analytica. Both the Hierarchy and the outline tree will show if this preference is checked, but the Styles library will turn this preference off if you select '''Outline''' style, since it duplicates the information on the outline. For the '''Top diagram only''' style there is no need for the hierarchy.&lt;br /&gt;
:[[File:Show hierarchy01.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Minimum resolution''': The resolution  in pixels of the smallest screen that your end users may have.  ACP uses a fixed browser window size (canvas) for all Diagrams (tabs), unlike Analytica on the desktop that lets you have a different window size for each one.  It's important to select a size that works well for all users, even on laptops with smaller screens.  When you select a minimum resolution for the screen, it automatically resizes the main Diagram size in the desktop so that it will work well in ACP. The actual diagram size will be smaller than the screen resolution to allow for space for the web browser controls, menus, and tabs at the top, and window edges and scroll bars that  take a little space on the sides and bottom.  &lt;br /&gt;
&lt;br /&gt;
:[[ACP_Diagram_Sizes#Diagram_Size_in_the_ACP_Style_Library|More...]]&amp;lt;br/&amp;gt;&lt;br /&gt;
:[[File:Min res01.png]]&lt;br /&gt;
&lt;br /&gt;
===ACP Navigation options===&lt;br /&gt;
&lt;br /&gt;
In this bottom section of the ACP Navigation styles, you can control how the banner area above your diagram appears and whether or not to add scroll bars. To simplify the  process of setting the styles, these checkboxes are hidden if you have selected an incompatible Navigation style in the top pane.&lt;br /&gt;
&lt;br /&gt;
:[[File:Navigation checkboxes01.png]]&lt;br /&gt;
====Banner logo and tabs====&lt;br /&gt;
Unchecking the 'Banner logo and tabs' hides the banner space usually present at the top of ACP.  The banner typically contains the Lumina Logo, the '''Parent Diagram''' button, tabs, '''Close Model''' button, and '''Save''' button. &lt;br /&gt;
&lt;br /&gt;
:[[File:Styles library 16.png]]&lt;br /&gt;
&lt;br /&gt;
====Parent button====&lt;br /&gt;
Flag to control the display of the '''Go into Parent''' button. Currently the button is shown by default with Outline style. The checkbox is hidden in other styles. It is possible to display this button with top tabs, but not by using the styles library, since there are some model specific settings involved. [[AcpStyles#Go_into_Parent_Button Not compatible with Side tabs. | More...]]&lt;br /&gt;
&lt;br /&gt;
:[[File:Styles library 17.png]]&lt;br /&gt;
&lt;br /&gt;
====Toolbar tabs====&lt;br /&gt;
&lt;br /&gt;
By clearing this checkbox, you can remove the default ACP tabs that appear at the top of ACP.  These are the tabs with titles like &amp;quot;Diagram&amp;quot;, &amp;quot;Object&amp;quot;, &amp;quot;Edit Table&amp;quot;, &amp;quot;Table&amp;quot;, &amp;quot;Graph&amp;quot;...  Toolbar tabs are compatible only with 'Outline' style. They will not show if the model title is shown, since they would tend to overlap.&lt;br /&gt;
&lt;br /&gt;
:[[File:Styles library 18.png]]&lt;br /&gt;
&lt;br /&gt;
====Use Top diagram size for all windows====&lt;br /&gt;
Sets the size of all diagrams based on the size of the diagram window of the top level when the model was last viewed in Desktop Analytica (in non-maximized mode). This is mandatory in all but 'Outline' style.&lt;br /&gt;
&lt;br /&gt;
====Model title====&lt;br /&gt;
Shows the title of the model at the top to the right of the Lumina (or other) logo.  Note that if you check this the toolbar tabs will not show, because the tabs and title would overlap, &lt;br /&gt;
&lt;br /&gt;
:[[file:Styles library 19.png]]&lt;br /&gt;
&lt;br /&gt;
===Diagram title===&lt;br /&gt;
You can control whether or not to display the diagram's title at the top of the diagram. Only usable with 'Outline' style. (And the preference for showing the model hierarchy needs to be turned off as explained above, ).&lt;br /&gt;
&lt;br /&gt;
:[[file:styles library 20.png]]&lt;br /&gt;
&lt;br /&gt;
====Auto calc====&lt;br /&gt;
Checking this causes ACP to calculate any result (table or graph) as it displays a diagram window containing the result,  and to immediately recalculate any result when the user changes an input on that diagram that affects the result. (It combines Calculate on open and Auto recalc results.)  This behavior is unlike Analytica which does not usually calculate results until the user asks for them by clicking the Calc button.&lt;br /&gt;
&lt;br /&gt;
====Add Scroll bars====&lt;br /&gt;
When checked, ACP adds scroll bars if needed to be able to see the entire diagram. When unchecked, the diagram will be either the top diagram size if this flag is set, or the canvas size.&lt;br /&gt;
&lt;br /&gt;
'''Once you have the navigation styles set the way you want, click '''Close'''. This will close the Navigation panel and take you back to the Main ACP Style Library diagram. '''&lt;br /&gt;
&lt;br /&gt;
:[[File:CloseNavstyles01.png]]&lt;br /&gt;
&lt;br /&gt;
==Node styles==&lt;br /&gt;
&lt;br /&gt;
The Node styles dialog lets you configure how nodes are displayed including bevels and shadows. You can specify the style for highlighting when you move the mouse over a node, and whether to show [[Help balloons|balloon help]] with a description for each node.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:[[File:Nodestyledialog01.png]]&lt;br /&gt;
&lt;br /&gt;
===Node effect on mouse-over===&lt;br /&gt;
Select a highlighting effect for nodes when you move the cursor over the node. The default setting is 'Outline', with 'Glow' and 'None' as the other choices. As you select an effect from the pulldown menu a preview is shown.&lt;br /&gt;
&lt;br /&gt;
:[[File:ACP Effect on mouseover01.PNG]]&lt;br /&gt;
&lt;br /&gt;
===Node edge appearance===&lt;br /&gt;
In this pane, the 2 checkboxes set flags controlling the appearance of the edge of the nodes. Bevels adds a 3 d bevel to the node. Shadows adds a drop shadow effect. You can select either of these effects or both.&lt;br /&gt;
&lt;br /&gt;
:[[File:ACP Node edge appearance01.PNG]]&lt;br /&gt;
&lt;br /&gt;
===Balloon help=== &lt;br /&gt;
This pane has two checkboxes to set whether the identifier and/or the definition is also shown in the [[Help balloons|balloon]], and a pulldown menu which sets the delay before a balloon appears.&lt;br /&gt;
&lt;br /&gt;
By default, ACP displays the description - if any - the units, and the title of an object in a balloon as you place the mouse over it. If there is no description the balloon will not appear.&lt;br /&gt;
&lt;br /&gt;
:[[File:Default Balloon wiki071212.PNG]] &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Identifier in balloon.''' This can be useful when a node is titled 'Net present value' and has an identifier &amp;lt;code&amp;gt;Npv&amp;lt;/code&amp;gt; for example.&lt;br /&gt;
&lt;br /&gt;
:[[File:Id in balloon wiki071212.PNG]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Definition in balloon.'''  When checked, it shows the Definition of a variable in the balloon when you move the mouse cursor over its node.&lt;br /&gt;
&lt;br /&gt;
:[[File:Def in Balloon wiki071212.PNG]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Both Definition and Identifier boxes checked'''&lt;br /&gt;
&lt;br /&gt;
:[[File:Def id in balloon wiki071212.PNG]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Balloon delay''' When you mouse over a node, there's a short delay of about half a second before it displays the balloon (to prevent wild balloon appearance when you move the cursor rapidly over a diagram.) You can tweak this delay time measured in seconds.&lt;br /&gt;
&lt;br /&gt;
:[[File:Balloon delay wiki 071212.PNG]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Uncertainty icon in outputs===&lt;br /&gt;
Analytica normally shows, just to the right of an output node, a little icon indicating the uncertainty view last displayed e.g. [[mid]], [[mean]], [[ProbBands]], [[pdf]] ...&lt;br /&gt;
&lt;br /&gt;
You can suppress these icons.  This might be desirable, for instance, if your model is not probabilistic.&lt;br /&gt;
&lt;br /&gt;
:[[file:styles library 27.png]]&lt;br /&gt;
&lt;br /&gt;
===Flash buttons===&lt;br /&gt;
For button nodes, instead of drawing a button that looks like a button node in desktop Analytica, use a Flash button.  A Flash button component looks and feels a little bit more like a GUI button used in software applications.  &lt;br /&gt;
&lt;br /&gt;
If you are building a web application which uses '''Submit''' or other buttons, you might find it looks better using the Flash button component rather than a traditional Analytica button node.&lt;br /&gt;
&lt;br /&gt;
However, if you are using multi-line text or have images embedded in any of the button nodes, then you should not use Flash Buttons since they don't support these features.&lt;br /&gt;
&lt;br /&gt;
:[[File:Styles library 28.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''*Once you have the Node styles set remember to click 'done'. This will apply the node style attributes you have selected to the model and return you to the ACP Style Library diagram'''&lt;br /&gt;
&lt;br /&gt;
:[[File:Nodestyleclose01.png]]&lt;br /&gt;
&lt;br /&gt;
==Frame nodes==&lt;br /&gt;
&lt;br /&gt;
:[[File:Styles library 05.png]]&lt;br /&gt;
&lt;br /&gt;
:[[File:Styles library 08.png]]&lt;br /&gt;
&lt;br /&gt;
'''What is a frame node?'''&lt;br /&gt;
If you are creating a Web Application which does not use the toolbar tabs, then you probably will want to display tables and graphs on the influence diagram.  You can specify the location and size of the tables and graphs on the diagram using a Frame node.  A module frame node is just a text node in a module that one tells ACP to use as the location for displaying tables and graphs in that module.&lt;br /&gt;
&lt;br /&gt;
These are used with Web Application navigation styles where the toolbar tabs are not present.  If you are not using one of the Web Application navigation styles, then you can skip this step.&lt;br /&gt;
&lt;br /&gt;
'''How to make a text node be a frame node'''&lt;br /&gt;
&lt;br /&gt;
First, create a text node in the module you want to display tables and graphs. Here is a Model with a text node on the top diagram.&lt;br /&gt;
&lt;br /&gt;
:[[file:Styles library 30.png]]&lt;br /&gt;
&lt;br /&gt;
===Select frame===&lt;br /&gt;
&lt;br /&gt;
*In the Frame Nodes control panel, select the module where the text node is located from the 'Select module' pulldown menu. &lt;br /&gt;
&lt;br /&gt;
*Select the frame node's identifier from the 'Select frame node' pulldown menu. &lt;br /&gt;
''(If the text node is newly added to the model, it may not be listed if this variable has not been 'dirtied'. If it is not listed, you need to click the refresh button.)''&lt;br /&gt;
&lt;br /&gt;
:[[File:Styles library 29.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Once you have the correct node selected, then check &amp;quot;Use as a module frame node&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
:[[File:Use as frame node 071212.PNG]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once you check this checkbox the options in the field below will be displayed and enabled..&lt;br /&gt;
&lt;br /&gt;
:[[File:Set Frame node01 071212.PNG]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Select frame node styles===&lt;br /&gt;
&lt;br /&gt;
'''Index Menus''' Controls the display of the Index pulldown menus on the diagram. Unchecked by default, since this saves diagram space, and it is assumed that a modeller will usually choose how he wants people to view the orientation and dimensions of a table/graph in his model on the web. If you want people to be able to view and use these menus in ACP, check this box. &lt;br /&gt;
&lt;br /&gt;
:[[File:Index menu no 0071212.PNG]][[File:Index menu yes 0071212.PNG]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Title'''  This checkbox controls whether or not the title of the node is shown above the table or graph on the diagram.&lt;br /&gt;
&lt;br /&gt;
'''Description'''  This checkbox controls whether or not the description of the node is shown above the table or graph on the diagram.&lt;br /&gt;
&lt;br /&gt;
'''Description length''' Length of description of variable as a percent of Frame height. Not enabled if the 'description' check box is unchecked. If the Description is too long to fit the allotted space, it will be truncated and a scroll bar will be used to view the entire description. (This feature will only display correctly if you have made the frame node large enough to accommodate the scroll bar within the allotted space).&lt;br /&gt;
&lt;br /&gt;
:[[File:Descr 50 071212.PNG]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Table and or graph'''  When the results of a node are shown, you have the following options, to show just the graph, just the table, show both the table and the graph.  If you want the table or graph to be shown based on what was viewed last in Analytica, you can choose 'As saved in Analytica'.&lt;br /&gt;
&lt;br /&gt;
For edit tables, the table will always be displayed regardless of this setting.&lt;br /&gt;
&lt;br /&gt;
:[[File:Table over graph 071212.PNG]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once you have chosen the settings for your frame node, you can make another frame node, either in a different module or in the same module. If there is more than one Frame, each time you click on a node, it will show its table or graph in the Frame whose contents was displayed the longest ago. Thus, as you click on different nodes, it cycles through the Frames.  In this way, you can see and compare edit tables or results from multiple nodes -- all in the same diagram window.&lt;br /&gt;
&lt;br /&gt;
Click '''Done''' when your settings are complete.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
* [[Media:ACP style library.ana|ACP style library.ana]]&lt;br /&gt;
* [[AcpStyles]]&lt;br /&gt;
 {{Release||5.4| * [https://youtu.be/OH3mYa_m0xE Analytica Cloud Player (ACP) Webinar] }}&lt;br /&gt;
* [[Analytica Cloud Platform]]&lt;/div&gt;</summary>
		<author><name>Fredbrunt</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Formatted_Text_Literals&amp;diff=55765</id>
		<title>Formatted Text Literals</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Formatted_Text_Literals&amp;diff=55765"/>
		<updated>2021-04-03T07:51:22Z</updated>

		<summary type="html">&lt;p&gt;Fredbrunt: /* Width and Alignment */ fix typo in expression&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''New to [[Analytica 6.0]]''&lt;br /&gt;
&lt;br /&gt;
A [[Formatted Text Literals|formatted text literal]] (or F-string for short) is a double-quoted text literal that is prefixed with an F or f.  These can include replacement expressions that are delineated by curly braces, which get replaced by the result of evaluating the expressions.  &lt;br /&gt;
&lt;br /&gt;
The following is an example of an F-String that inserts the current values of x, y and x+y:&lt;br /&gt;
:&amp;lt;code&amp;gt;F&amp;quot;The value of x is {x}, y is {y} and their sum is {x+y}&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although you could accomplish the same result using [[Text_Concatenation_Operator%3A_%26|text-concatenation]] as&lt;br /&gt;
:&amp;lt;code&amp;gt;&amp;quot;The value of x is &amp;quot; &amp;amp; x &amp;amp; &amp;quot;, y is &amp;quot; &amp;amp; y &amp;amp; &amp;quot; and their sum is &amp;quot; &amp;amp; (x+y)&amp;lt;/code&amp;gt;&lt;br /&gt;
the version using F-strings is more concise and easier to read.&lt;br /&gt;
&lt;br /&gt;
[[Formatted Text Literals]] aren't really literals like normal single- or double-quoted text values are.  They are instead themselves expressions whose value is determined at evaluation time. Nevertheless, because they have the syntactic appearance of literals, the term is used. The names [[Formatted Text Literals]] and [[F-Strings]] are borrowed from [https://docs.python.org/3/reference/lexical_analysis.html?highlight=formatting#formatted-string-literals Python].&lt;br /&gt;
&lt;br /&gt;
== Syntax ==&lt;br /&gt;
&lt;br /&gt;
A [[Formatted Text Literals|formatted text literal]]  starts with either &amp;lt;code&amp;gt;F&amp;quot;&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;f&amp;quot;&amp;lt;/code&amp;gt;, and ends with &amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;. In other words, it is a double-quoted text value prefixed with an upper or lower case F.  There can be no space between the F and the opening quote.  Within the text, expressions are inserted using curly braces, &amp;lt;code&amp;gt;{expr}&amp;lt;/code&amp;gt;. When the F-String is evaluated, the expressions in curly braces are evaluated and their result is substituted for the curly braces and expression.&lt;br /&gt;
&lt;br /&gt;
There is currently no single-quoted version of F-strings in Analytica, so you cannot write &amp;lt;code&amp;gt;f'Something'&amp;lt;/code&amp;gt;.  It must use double quotes is in &amp;lt;code&amp;gt;f&amp;quot;Something&amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If you want to embed a double quote (&amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;), or curly brace (&amp;lt;code&amp;gt;{&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;}&amp;lt;/code&amp;gt;) in the text part of an F-string, you must double the character.  For example, &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 F&amp;quot;An F-string has the form F&amp;quot;&amp;quot;some text {{ an expression : format spec }} some more text&amp;quot;&amp;quot;.&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
which has the content: ''An F-string has the form F&amp;quot;some text { an expression : format spec } some more text&amp;quot;.''&lt;br /&gt;
&lt;br /&gt;
When the curly braces are not doubled, the content between them is parsed as an expression.  Optionally, the expression can be followed by a colon (&amp;lt;code&amp;gt;:&amp;lt;/code&amp;gt;) and a [[#Format Specifiers|format specifier]].  For example:&lt;br /&gt;
:&amp;lt;code&amp;gt;F&amp;quot;1/3 = {1/3 : %6}&amp;quot;&amp;lt;/code&amp;gt; &amp;amp;rarr; &amp;quot;1/3 = 33.333333%&amp;quot;&lt;br /&gt;
&lt;br /&gt;
When you omit a format specifier, the [[Number formats|number format]] for the current expression context is used, i.e., for the current variable or [[User-Defined Function]], which you set using the [[Number formats|number format dialog]].&lt;br /&gt;
&lt;br /&gt;
== Array abstraction ==&lt;br /&gt;
When your expression evaluates to an array, a separate text value is created for each cell. When you have more than one expression, the indexes of your final result will be the union of the indexes for all the expressions.  For example:&amp;lt;code&amp;gt;&lt;br /&gt;
:[[LocalIndex]] X := 1..9;&lt;br /&gt;
:[[LocalIndex]] Y := 1..9;&lt;br /&gt;
:F&amp;quot;{X} * {Y} = {X*Y}&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
returns a 2-D array having 81 cells:&lt;br /&gt;
&amp;lt;center&amp;gt;[[image:FstringExampleXxY.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A format specifier is static. It isn't computed and cannot vary along any index, so the same format specifier (if any) applies to every cell of the result.&lt;br /&gt;
&lt;br /&gt;
== Format Specifiers ==&lt;br /&gt;
Format specifiers are optional, but when you want to specify the format, follow your expression with a colon and then with the format specifiers.  F-String format specifiers are terse by design, so as to minimize the distraction from the content and keep your formatted text literal looking as much as possible like the final result.  But being terse, they are also cryptic.  Except for numeric parts, each element of the format is denoted by a single character.  Analytica's format specifiers have several similarities to Pythons, but are not exactly the same. &lt;br /&gt;
&lt;br /&gt;
You don't need a format specifier when you've set the [[Number formats|Number Format]] of your variable or [[UDF]] to be as you'd like.  Also, you have the option of using [[NumberToText]] for a more descriptive way to specify the format.&lt;br /&gt;
&lt;br /&gt;
A format specifier can specify the following information:&lt;br /&gt;
* The number format for numeric values&lt;br /&gt;
* Minimum width (in characters) and alignment within that space&lt;br /&gt;
* The date template for date-time values&lt;br /&gt;
All three are optional, or you may specify more than one.&lt;br /&gt;
&lt;br /&gt;
Parts that aren't explicitly specified are inherited from the current variable or [[UDF]]'s number format.&lt;br /&gt;
&lt;br /&gt;
=== Number formats ===&lt;br /&gt;
A number format type can be one of the following characters:&lt;br /&gt;
* &amp;lt;code&amp;gt;S&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;: Suffix&lt;br /&gt;
* &amp;lt;code&amp;gt;E&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt;: Exponential&lt;br /&gt;
* &amp;lt;code&amp;gt;G&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;g&amp;lt;/code&amp;gt;: General&lt;br /&gt;
* &amp;lt;code&amp;gt;F&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;f&amp;lt;/code&amp;gt;: Fixed point&lt;br /&gt;
* &amp;lt;code&amp;gt;I&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt;: Integer&lt;br /&gt;
* &amp;lt;code&amp;gt;P&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;%&amp;lt;/code&amp;gt;: Percent&lt;br /&gt;
* &amp;lt;code&amp;gt;B&amp;lt;/code&amp;gt;: Boolean (Prints as True or False)&lt;br /&gt;
* &amp;lt;code&amp;gt;H&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;h&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;X&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;: Hexadecimal&lt;br /&gt;
* &amp;lt;code&amp;gt;b&amp;lt;/code&amp;gt;: binary&lt;br /&gt;
&lt;br /&gt;
The type can be followed by the number of digits or decimals, such as &amp;lt;code&amp;gt;G12&amp;lt;/code&amp;gt; for General type with 12 digits.  For suffix, exponential, general, hex and binary types, the number is the number of digits total, for fixed point and percent types it is the number of decimal places.  See [[Number formats]].&lt;br /&gt;
&lt;br /&gt;
The following characters specify additional components of the number format:&lt;br /&gt;
* &amp;lt;code&amp;gt;'!'&amp;lt;/code&amp;gt;: Display full precision&lt;br /&gt;
* &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;z&amp;lt;/code&amp;gt;: Show trailing zeros. If you use 0, it needs be separated in some way from the number of digits, such as by a space of '.'.  E.g., F10 is Fixed point with 10 decimals, whereas F1.0 is fixed point with 1 decimal and trailing zeros.&lt;br /&gt;
* &amp;lt;code&amp;gt;,&amp;lt;/code&amp;gt;: Show thousands separators&lt;br /&gt;
* ''space'' or &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;: Ignored characters.&lt;br /&gt;
&lt;br /&gt;
A few options not available (if you need these, use [[NumberToText]]) are: Currency symbols, use of parentheses for negative numbers, control of the ordering of currency, sign and digits.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
:&amp;lt;code&amp;gt;F&amp;quot;π={Pi:!}&amp;quot;&amp;lt;/code&amp;gt; &amp;amp;rarr; &amp;quot;π=3.141592653589793&amp;quot;&lt;br /&gt;
:&amp;lt;code&amp;gt;F&amp;quot;The 25th power of 3 is {3^25:I,}&amp;quot;&amp;lt;/code&amp;gt; &amp;amp;rarr; &amp;quot;The 25th power of 3 is 847,288,609,443&amp;quot;&lt;br /&gt;
:&amp;lt;code&amp;gt;F&amp;quot;${profit:F2,0}&amp;quot;&amp;lt;/code&amp;gt; &amp;amp;rarr; &amp;quot;$17,343,300.00&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Width and Alignment ===&lt;br /&gt;
When you specify a (minimum) width and alignment, the expression uses at least that number of characters, using spaces to pad unused space.  The alignment character comes first, followed by the width, and both are required. The possible alignment characters are:&lt;br /&gt;
* &amp;lt;code&amp;gt;L&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;amp;lt;&amp;lt;/code&amp;gt;: Left align&lt;br /&gt;
* &amp;lt;code&amp;gt;R&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;amp;gt;&amp;lt;/code&amp;gt;: Right align&lt;br /&gt;
* &amp;lt;code&amp;gt;C&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt;: Center align&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
:&amp;lt;code&amp;gt;F&amp;quot;π≈{pi:R10G4} π/2≈{pi:L10G4} |π^2≈{pi:C10G4}|&amp;quot;&amp;lt;/code&amp;gt; &amp;amp;rarr; &amp;quot;π≈     3.142 π/2≈1.571      |π^2≈   9.87   |&amp;quot;&lt;br /&gt;
:&amp;lt;code&amp;gt;F&amp;quot;Cost=${Cost:I,R15}&amp;quot;&amp;lt;/code&amp;gt;&amp;amp;rarr;[[image:FStringCurrencyLeft.png]]&lt;br /&gt;
:&amp;lt;code&amp;gt;F&amp;quot;Cost={F&amp;quot;${Cost:I,}&amp;quot;:R15}&amp;quot;&amp;lt;/code&amp;gt; &amp;amp;rarr;[[image:FStringCurrencyWithNumber.png]]&lt;br /&gt;
&lt;br /&gt;
The last example shows how you can use a nested F-string to produce a fixed-width cost column while keeping the $ attached to the number.&lt;br /&gt;
&lt;br /&gt;
=== Date template ===&lt;br /&gt;
The date template is used to render date-time values. This can be specified along with a number format, so that when an expression returns an array of values with some dates and some numbers, the number format is used for numbers and the date format for dates.&lt;br /&gt;
&lt;br /&gt;
The date template is preceded by the letter &amp;lt;code&amp;gt;D&amp;lt;/code&amp;gt;, and then continues to the closing curly brace. The date format therefore must be last and come after any alignment and width or number format.  Any spaces that appear after the D and before curly brace become part of the final text.  The date template specified in an F-string cannot contain curly braces. Otherwise, it uses the same conventions as the date template in the number format dialog.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
* &amp;lt;code&amp;gt;F&amp;quot;The current time is {Today(true):Dhh:mm:ss tt}&amp;quot;&amp;lt;/code&amp;gt; &amp;amp;rarr; &amp;quot;The current time is 03:31:38 PM&amp;quot;&lt;br /&gt;
* &amp;lt;code&amp;gt;F&amp;quot;In the US it is {Today():DMM/dd/yyyy}, but in Europe it is {Today():Ddd/MM/yyyy}.&amp;quot;&amp;lt;/code&amp;gt; &amp;amp;rarr; &lt;br /&gt;
*:::&amp;quot;In the US it is 03/24/2021, but in Europe it is 24/03/2021.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Text_Concatenation_Operator%3A_%26|The text-concatenation operator, &amp;amp;]]&lt;br /&gt;
* [[NumberToText]]&lt;br /&gt;
* [[Number formats]]&lt;br /&gt;
* [[Text values]]&lt;br /&gt;
* [[JoinText]]&lt;/div&gt;</summary>
		<author><name>Fredbrunt</name></author>
	</entry>
</feed>