Osprey Academy - Customer Support & Training

Using Osprey

Learn how to use Osprey to manage your day-to-day operations and processes


Formula Functions Reference

Who is this guide for?

Case Management Supervisors and System Supervisors

This guide will assist you with using each of the functions available when writing a formula in Osprey

Our guide Add and Use Formulae > explains how to create a formula and add it to a custom data page or standard document. This guide explains what each function does, with an example of the result, so you can build your own formulae. You don’t need any previous experience of formulae.

Only Supervisor level users are able to create formulae.

Click the Supervisor menu followed by Case management setup and Formulae. Click New to start a new formula, or right-click an existing formula and select Edit.

Formulae screen with the New button highlighted

In the Formula section, choose a Function Categories option (DateTime, Logical, Math or Text) to list its functions. Double-click a function, operator or field to add it to the Formula Editor, or type the formula directly. Click Validate to check the formula before you save it.

Formula editor with Function Categories, Functions, Formula Editor and Validate highlighted

The hint shown next to each function in the list is not always accurate. Where the hint and this guide differ, follow this guide.

How a Formula Works

A formula is a set of instructions that Osprey follows to produce a value, such as a name, a date or an amount. You only need a few building blocks:

Building blockWhat it meansExample
A functionAn instruction, such as Upper (make it capitals) or Left (take letters from the start).Upper
BracketsHold whatever the function works on.Upper('smith') gives SMITH
CommasSeparate the pieces of information inside the brackets. The order matters.Left('Smith', 1) gives S
Single quotesAnything inside single quotes is used exactly as you type it, including spaces.'Dear '
&Joins pieces together.'Dear ' & 'Mr Smith' gives Dear Mr Smith
A fieldA value from the client or matter. Fields appear in curly brackets.{!LINKNAME.SURNAME_1}
True / FalseSome functions answer a yes/no question. Osprey shows the answer as True or False.Begins('BRA0001', 'BRA') gives True

Putting these together, 'Dear ' & {!LINKNAME.TITLE_1} & ' ' & {!LINKNAME.SURNAME_1} takes the text Dear, adds the client’s title, a space and their surname. For a client called Mr John Smith, it gives Dear Mr Smith.

When Osprey counts the letters in a piece of text, the first letter is position 0, the second is position 1, and so on. In HR2 9ED, the H is position 0 and the 9 is position 4. This matters for the Mid and Find functions.

  • Use single quotes, not double quotes. You can’t include an apostrophe inside quoted text.
  • Capital letters don’t matter in function names: Upper and UPPER both work.
  • Capital letters do matter when comparing text: Osprey treats 'yes' and 'Yes' as different.
  • If a formula can’t work something out (for example, it asks for more letters than a field holds), the result is left blank rather than showing an error.

Text Functions

These work with words, names, addresses and references.

FunctionWhat it doesExampleNotes
Len(text)Counts the characters in the text.Len('John Smith') gives 10Spaces count as characters. A blank field gives 0, so this is a handy way to check whether a field has been filled in.
Left(text, number)Takes letters from the start of the text.Left('HR2 9ED', 3) gives HR2If you ask for more letters than the text has, the result is blank.
Right(text, number)Takes letters from the end of the text.Right('HR2 9ED', 3) gives 9EDIf you ask for more letters than the text has, the formula won’t validate.
Mid(text, start, number)Takes letters from the middle of the text.Mid('HR2 9ED', 4, 3) gives 9EDInside the brackets: the text, the position to start at, and how many letters to take. Positions start at 0, so the 9 is position 4. All three are needed.
Find(text, look for, start)Finds where something first appears in the text and gives its position.Find('John Smith', ' ') gives 4Put the text to search first, then what you’re looking for (the hint in the list shows these the other way round). Positions start at 0. If it isn’t found, the result is -1. Capital letters must match. Start is optional.
Begins(text, check)Checks whether the text starts with something.Begins('BRA0001', 'BRA') gives TrueHandy for checking a reference. Capital letters must match.
Ends(text, check)Checks whether the text ends with something.Ends('jane@firm.co.uk', '.co.uk') gives TrueCapital letters must match.
Contains(text, check)Checks whether something appears anywhere in the text.Contains('Purchase of 344 Broad St.', 'Purchase') gives TrueCapital letters must match. To ignore them, make the text lower case first: Contains(Lower(text), 'purchase').
Substitute(text, old, new)Replaces every occurrence of one piece of text with another.Substitute('Flat 1, 2 High St', ',', '') gives Flat 1 2 High StEvery match is replaced. Capital letters must match. Use '' (two single quotes) as the new text to remove something.
Text(value)Turns a number or date into text.Text(Date(2026, 10, 16)) gives 16/10/2026You can’t choose a format: Osprey accepts a format such as 'dd MMMM yyyy' but ignores it. A date field also shows its time (for example 13/12/2024 00:00:00), so use DateOnly for date fields.
Trim(text)Removes spaces from the start and end of the text.Trim(' John Smith ') gives John SmithSpaces in the middle are kept. Useful for tidying details that were typed with extra spaces.
TrimStart(text) / TrimEnd(text)Removes spaces from the start only, or the end only.TrimEnd('Smith ') gives SmithUse Trim unless you need to keep spaces on one side.
PadLeft(text, length) / PadRight(text, length)Adds spaces before or after the text until it reaches the length you choose.PadLeft('42', 6) gives ‘ 42’Pads with spaces only. If the text is already longer, it’s left as it is.
Lower(text) / Upper(text)Changes the text to lower case or capitals.Upper('hr2 9ed') gives HR2 9EDThere’s no function to capitalise just the first letter of a name. See the Examples section for a way to do this.
Hyperlink(web address, link text, target)Creates a clickable link.Hyperlink('https://example.com', 'Example')Target is optional. The result is a link, so it’s best used on its own rather than joined to other text.
Image(web address, description, height, width)Displays a picture from a web address.Image('https://…/logo.png', 'Logo')Height and width are optional.

Logical Functions

These let a formula make a decision, such as showing different wording depending on a field.

FunctionWhat it doesExampleNotes
If(question, if yes, if no)Asks a question and gives one result if the answer is yes and another if it’s no.If(1500 > 1000, 'Over limit', 'Within limit') gives Over limitAll three parts are needed. You can put one If inside another to check more than one thing.
Case(value, match 1, result 1, …, otherwise)Compares a value with a list of options and gives the matching result.Case('P', 'P', 'Purchase', 'S', 'Sale', 'Other') gives PurchaseTidier than several If functions inside each other. The final “otherwise” result is required.
question AND questionYes only if both questions are yes.If('Yes' = 'Yes' AND 1500 > 1000, 'Chase client', 'No action') gives Chase clientWrite AND between the two questions.
question OR questionYes if either question is yes.If('Sale' = 'Purchase' OR 'Sale' = 'Sale', 'Property matter', 'Other') gives Property matterWrite OR between the two questions.
NOT(question)Turns yes into no, and no into yes.If(NOT(Contains('Purchase of 344 Broad St.', 'Sale')), 'Not a sale', 'Sale') gives Not a saleFor a simple comparison, <> (is not equal to) is often easier to read.

Questions use these symbols:

SymbolMeansExample
=is equal to{!X} = 'Yes'
<>is not equal to{!X} <> 'Yes'
> / <is more than / is less than1500 > 1000
>= / <=is at least / is at most1500 >= 1500

Math Functions

These work with amounts and other numbers. You can also use + (add), - (subtract), * (multiply), / (divide) and ^ (to the power of), with brackets to control the order. For example, 1500 * 0.2 gives 300.

FunctionWhat it doesExampleNotes
Round(number, decimal places)Rounds a number to the number of decimal places you choose.Round(1234.5678, 2) gives 1234.57When a number is exactly halfway, Osprey rounds to the nearest even number: Round(2.5, 0) gives 2, but Round(3.5, 0) gives 4. Both parts are needed.
Ceiling(number)Rounds up to the next whole number.Ceiling(2.1) gives 3Useful for rounding up part hours or part units.
Floor(number)Rounds down to the whole number below.Floor(2.9) gives 2Drops anything after the decimal point.
Max(number, number) / Min(number, number)Gives the larger or the smaller of two numbers.Max(1500, 2000) gives 2000Works with exactly two numbers. To compare three, put one inside the other: Max(a, Max(b, c)).
Abs(number)Removes a minus sign.Abs(1200 - 1500) gives 300Useful when you want the size of a difference, whichever way round it is.
Sign(number)Shows whether a number is positive (1), negative (-1) or zero (0).Sign(1200 - 1500) gives -1Useful for checking whether a balance is in credit or overdrawn.
Pow(number, power)Multiplies a number by itself the number of times you choose.Pow(2, 3) gives 82^3 does the same.
Sqrt(number)Gives the square root.Sqrt(16) gives 4Rarely needed in case management.
Exp, Log(number, base), Log10, Sin, Cos, Tan, Asin, Acos, AtanScientific functions.Log(8, 2) gives 3Rarely needed in case management. Log needs both the number and the base.

Date and Time Functions

These work with dates, such as completion dates, limitation dates and review dates.

FunctionWhat it doesExampleNotes
Date(year, month, day)Creates a date.Date(2026, 10, 16) gives 16/10/2026Put the year first, then the month, then the day.
Today() / Now()Today’s date, or today’s date and the current time.Today() gives today’s dateNothing goes in the brackets. Custom data pages show the date only.
DateTime(year, month, day, hour, minute, second)Creates a date with a time.DateTime(2026, 10, 16, 14, 30, 0)Custom data pages show the date only.
DateOnly(date)Removes the time from a date.DateOnly({!RC_DATES.I_COMPLTIONDATE}) gives 13/12/2024Use this whenever you join a date field to other text. Otherwise the time (00:00:00) appears after the date.
Day(date) / Month(date) / Year(date)Gives the day, month or year of a date as a number.Year(Date(2026, 10, 16)) gives 2026Combine with Date to build a related date, for example the first of January in the same year: Date(Year({!date}), 1, 1).
DayOfWeek(date)Gives the name of the day.DayOfWeek(Date(2026, 12, 25)) gives FridayThe list also shows a version with a format option (DayOfWeekFormat). In testing, it always gave the full day name, whatever the format.
IsWeekendDay(date)Checks whether a date is a Saturday or Sunday.IsWeekendDay(Date(2026, 10, 17)) gives TrueUseful for flagging deadlines that fall at a weekend. It doesn’t know about bank holidays: 25 December 2026 (a Friday) gives False.
DateAddDays(date, days)Adds days to a date.DateAddDays(Date(2026, 10, 16), 14) gives 30/10/2026Use a minus number to go back: DateAddDays(Date(2026, 10, 16), -7) gives 09/10/2026.
DateAddMonths(date, months)Adds months to a date.DateAddMonths(Date(2026, 10, 16), 3) gives 16/01/2027If the day doesn’t exist in the new month, the last day of the month is used: 31 January plus one month gives 28/02/2026.
DateAddYears(date, years)Adds years to a date.DateAddYears(Date(2026, 10, 16), 6) gives 16/10/2032Useful for retention or review dates. 29 February moves to 28 February in a non-leap year.
DateAddHours / DateAddMinutes / DateAddSeconds(date, number)Adds hours, minutes or seconds.DateAddHours(DateTime(2026, 10, 16, 23, 0, 0), 2) gives 17/10/2026Custom data pages show the date only, so the time won’t be visible.
IsLeapYear(year)Checks whether a year is a leap year.IsLeapYear(2028) gives TrueNeeds a year, not a full date. For a date field use IsLeapYear(Year({!date})).
DaysInMonth(year, month)Gives the number of days in a month.DaysInMonth(2026, 2) gives 28Useful for apportioning a monthly amount by days.
DateDiff(first date, second date, unit)Works out the time between two dates.DateDiff(Date(2026, 10, 1), Date(2026, 10, 16), 'day') gives 15The unit must be one of those in the table below. The answer is always a positive number, whichever date comes first.
EmptyDate()Meant to give a blank date.—In testing, any formula using EmptyDate failed to validate. To check whether a date field is blank, use If(Text({!date}) = '', 'No date', 'Has date').

The unit for DateDiff goes in single quotes and must be written exactly as below (capital letters don’t matter). Other spellings, such as 'days' or 'week', won’t validate.

UnitWhat it countsExample
'day'Whole days. Part days are ignored.1 October to 16 October gives 15
'hour'Hours, including part hours.10:00 to 11:30 gives 1.5
'min'Minutes.10:00 to 11:30 gives 90
'sec'Seconds.10:00:00 to 10:00:45 gives 45
'month'How many times the month changes, not complete months.31 January to 1 February gives 1
'year'How many times the year changes, not complete years.31 December 2025 to 1 January 2026 gives 1

Because ‘month’ and ‘year’ count changes rather than complete months or years, don’t use them to work out someone’s age or how long a matter has been open. Use ‘day’ instead.

Fields and Blank Values

  • If a number field used in a calculation is blank, the whole result is blank. To treat a blank as 0, use If({!FW_APPORT.FW_SC_AMNT} = '', 0, {!FW_APPORT.FW_SC_AMNT}) + 1.
  • To check whether any field has been filled in, use If(Len({!field}) = 0, 'Not entered yet', 'Entered').
  • On a custom data page, number results are shown to 2 decimal places, so 1500 * 0.2 shows as 300.00. When a number is joined to text, use Round to control the decimal places: '£' & Round(1234.5678, 2) gives £1234.57. Thousands separators aren’t added.
  • A result made up only of digits can sometimes be shown as a number and lose its leading 0. In testing, 07700900123 showed as 7700900123.00. Adding text in front avoids this: 'Tel: ' & Substitute('07700 900123', ' ', '') gives Tel: 07700900123.

Examples

To do thisUse
Start a letter'Dear ' & {!LINKNAME.TITLE_1} & ' ' & {!LINKNAME.SURNAME_1}
Capitalise the first letter of a nameUpper(Left({!LINKNAME.FORENAME_1}, 1)) & Lower(Mid({!LINKNAME.FORENAME_1}, 1, Len({!LINKNAME.FORENAME_1}) - 1))
Show the completion date in a sentence'Completion is due on ' & DateOnly({!RC_DATES.I_COMPLTIONDATE})
Count the days since the matter was openedDateDiff({!MATTER.DATE_OPENED}, Today(), 'day')
Build a file reference{!MATTER.FEE_EARNER_ID} & '/' & {!MATTER.CLIENT_NO} & '/' & {!MATTER.MATTER_NO}
Take the first part of a postcodeLeft({!CLIENT.POSTCODE}, Find({!CLIENT.POSTCODE}, ' '))
Flag a deadline that falls at a weekendIf(IsWeekendDay(DateAddDays(Today(), 14)), 'Weekend - check deadline', 'Weekday')

If You Have Used Excel Before

Many functions share a name with Excel functions but behave differently. The main differences are:

  • Mid and Find count positions from 0, not 1. Find has the text to search first, and gives -1 rather than an error when nothing is found.
  • AND and OR go between the questions, not as AND(a, b).
  • Text comparisons are case-sensitive.
  • If and Case need every part, including the “if no” and “otherwise” results.
  • Round rounds exact halves to the nearest even number.
  • Max and Min take exactly two numbers. Ceiling and Floor take one. Log needs a base.
  • Left gives a blank, and Right fails, if you ask for more letters than the text has.
  • A blank number field makes the result blank rather than being treated as 0.
  • Text ignores any format you give it.
  • DateDiff has no "d"/"m"/"y" units, and its month and year results count changes rather than complete periods.


In this article Related Guides