myContactCenterManual

Formulas

The formula language of the wallboards — values, operators, list queries, conditions, row reference and time zones — and what the error messages mean.

Every value on a wallboard comes from a formula. A formula is a single expression over the live data of the contact center, for example

Conversations.Count(State = "Waiting")

— the number of waiting conversations. Which data exists is described in Data for formulas; ready-made formulas are listed under Examples. The performance indicators use the same language, with slightly different data, see below.

What a formula must return

Where Result
Label, digital display, table column any value
Gauge, state indicator a number
Row formula of a table or chart yes/no
Series of a chart a number or time span

Basic rules

  • A formula is one expression — without statements, variables or comments.
  • Upper and lower case do not matter for names: conversations.count() is the same as Conversations.Count(). When comparing texts, however, case does matter: SkillName = "support" does not find the skill “Support”.
  • You can use any number of spaces and line breaks between the parts.
  • You append fields and methods with a period: Conversations.First().Agent.Name, Name.StartsWith("A").
  • List queries need parentheses, even without content: Agents.Count().
  • Quotation marks are the straight " — typographic ones such as “ ” cause a syntax error.

Values

Notation Meaning Example
whole number number 42
number with a decimal point decimal number 2.5
text in double quotation marks; a " in the text is doubled text "Support"
true, false yes, no IsLogin = true
null empty Agent = null
Now the current server time, in UTC Now - StartTime
TimeSpan(hours, minutes, seconds), TimeSpan.FromMinutes(5), TimeSpan.Zero time span QueuedTimeSpan > TimeSpan(0,2,0)
DateTime(year, month, day), DateTime.MinValue point in time ChangeTime = DateTime.MinValue
the internal name of a state or type in quotation marks state, type State = "Waiting"

You compare states and types using their internal names, see States and types; here, upper and lower case do not matter, and an unknown name is an error.

You convert with the .NET type names, for example Int32(x) or Double(Agents.Count()), and with Convert.ToInt32(…) or Convert.ToString(…); the language does not know short names such as int or double. For calculations, all functions of Math are available — Math.Round(x), Math.Round(x, 1), Math.Max(a, b), Math.Abs(x) — plus the methods of the values themselves: Name.ToUpper(), Subject.Length, QueuedTimeSpan.TotalSeconds, StartTime.ToLocalTime().

Operators

Ordered by precedence, the strongest first:

Operators Meaning
. [ ] field, method, index
-x, not x or !x sign; negation of yes/no
*, /, % or mod multiplication and division. Whole numbers are divided as integers: 7 / 2 results in 3, 7 / 2.0 results in 3.5.
+, -, & addition and subtraction, also with time spans and points in time: Now - StartTime results in a time span. & concatenates texts.
= or ==, <> or !=, <, >, <=, >= comparison
and or && and
or or || or
condition ? value1 : value2 condition, see below

Parentheses ( ) change the order.

If & concatenates a state, a time span or a point in time with text, the value appears untranslated: states with their internal names, time spans with fractions of a second, points in time in UTC. So format it yourself, for example "Longest wait: " & Conversations.Max(QueuedTimeSpan).ToString("mm\:ss").

List queries

Every list — conversations, agents, skills … — supports these queries:

Query Returns For an empty list Example
Count() the number 0 Agents.Count()
Count(condition) the number of entries for which the condition holds 0 Conversations.Count(State = "Waiting")
Where(condition) the entries for which the condition holds empty InboundCalls.Where(SkillName = "Support").Count()
First(), First(condition) the first (matching) entry empty Agents.First(IsLogin).Name
Min(field), Max(field) the smallest or largest value 0 or 00:00:00 Conversations.Max(QueuedTimeSpan)
Sum(field) the sum 0 or 00:00:00 ACDs.Sum(WaitingCalls)
Average(field) the average 0 or 00:00:00 Conversations.Average(QueuedTimeSpan)
  • Inside the parentheses, the fields of the individual entry apply: in Agents.Count(IsLogin), IsLogin is the field of each agent. You refer to the entry itself as it.
  • Queries can be chained: Conversations.Where(ConversationType = "InboundCall").Max(QueuedTimeSpan).
  • If the condition cannot be evaluated for an entry — for example Skill.Name for a conversation without a skill — the entry counts as not matching.
  • You check whether there is at least one entry with Conversations.Count(State = "Waiting") > 0.

Conditions

iif(condition, value1, value2) and condition ? value1 : value2 return value1 if the condition holds, otherwise value2. Both values must be of the same type:

iif(Wrapup, WrapupTimeSpan, TimeSpan.Zero)
Agents.Count(IsLogin) = 0 ? "nobody" : "staffed"

Row and it

In table columns, row formulas and chart series, the current row is available as Row. You can also name its fields without Row: in an agent table, Name and Row.Name are the same.

Within a list query, it denotes the entry of the list; the row remains accessible via Row. In a skill table, each row thus counts its own waiting conversations:

Conversations.Count(Skill.Id = Row.Id and State = "Waiting")

If a field of the row has the same name as a list — agents, for example, have the fields Skills and Languages — the name alone refers to the list. You reach the field with Row.Skills or, in a query, with it.Skills.

Time and time zones

  • Now and all points in time that the server supplies — StartTime, LoginTime, RaiseTime — are in UTC.
  • Time spans such as Now - StartTime or QueuedTimeSpan do not depend on this.
  • A label whose formula returns a point in time shows it in the local time of the computer. In tables and in texts you build yourself, you convert: StartTime.ToLocalTime(), Now.ToLocalTime().ToString("HH:mm").

Error messages

The designer checks every formula as you type; if it contains errors, the field changes color and the message appears below it, often with the position “(at index n)”. The most common ones:

Message Cause
Unknown identifier '…' The name is misspelled, or the list does not exist.
No property or field '…' exists in type '…' The field does not exist for this entry, see Data for formulas.
Operator '…' incompatible with operand types '…' and '…' The values do not go together, for example a number and a time span.
Expression of type '…' expected The result has the wrong type — a gauge does not get a number, a row formula does not get yes/no.
Ambiguous invocation of method '…' in type '…' The arguments match several versions of a function.
Syntax error for example a single | or typographic quotation marks
Unterminated string literal A " is missing.
Character literal must contain exactly one character A text is in single instead of double quotation marks.
Expression expected The formula is empty, or something is missing after an operator.

On the wallboard, a label with an erroneous formula shows the formula itself.

If an error only occurs during calculation — for example First().Name on an empty list — the element shows an empty value: 0, empty text, 00:00:00 or “No”.

Differences from performance indicators

Wallboard Performance indicator
Calculated in the Wallboard program, every second on the server
Filters the filters of the display element none
Agents all configured agents that match the filter — Agents.Count(IsLogin) counts the logged-in ones only the logged-in agents
ACDs with metrics such as Open and WaitingCalls only the settings of the distribution rules
Alarms the active alarms empty
Configuration, TimeStamps, ConversationStates, ConversationTypes, Bins available not available

    ↑ ↓ select · Enter open · Esc close