We have supported formula functions like SUM and PRODUCT for a long time now. What they have in common is that you supply multiple parameters and get a single result back.
These formula functions are used frequently by Calcapp authors, but provide
little value beyond adding or multiplying numbers together using +
and *
.
The formulas SUM(Field1, 4)
and Field1 + 4
do the exact same thing, which is
also true for the formulas PRODUCT(4, 8, 16)
and 4 * 8 * 16
.
Functions like SUM and PRODUCT are about to become significantly more useful, though, with the introduction of ranges. If you have more than a passing familiarity with spreadsheets like Microsoft Excel, you have definitely encountered ranges (whether or not you know them by that name).
In Excel, if cells A1 through A5 contain values you want to add together, you
can easily do so using the formula =SUM(A1:A5)
. By contrast, Calcapp has
historically forced you to enumerate all the values you wanted to add together,
by writing something like SUM(A1, A2, A3, A4, A5)
or A1 + A2 + A3 + A4 + A5
.
(Calcapp doesn’t require you to write =
before formulas.) Compared to using
ranges, that’s a lot more work.
The good news is that our upcoming release will support ranges. If you have five
number fields named A1
, A2
, A3
, A4
and A5
(appearing one after
another), adding their values together will be as easy as using the formula
SUM(A1:A5)
.
Calcapp authors don’t typically name their fields as though they were cells in a
spreadsheet grid. Rather, fields are automatically named using their labels as a
guide, so if you use the label “Maximum weight” for a field, the field is
assigned the name MaximumWeight
automatically. (To break the association
between the label and the name, simply type a new name manually in the name
field, to the left of the formula bar.) As such, ranges in Calcapp formulas will
typically look more like SUM(MaximumWeight:IndividualWeight)
than
SUM(A1:A5)
.
The formula SUM(MaximumWeight:IndividualWeight)
will add all values together
that belong to not only the fields MaximumWeight
and IndividualWeight
, but
all fields that appear between them in the app designer.
Under the hood
In a spreadsheet, the cell reference A1
refers to the cell in the first column
and the first row of the spreadsheet grid and A2
refers to the cell in the
first column and the second row. The range A1:A2
refers to both of these
cells.
Spreadsheets also support something called arrays, which are similar to ranges
in that they hold multiple values. An array constant in a spreadsheet is
written between curly brackets, like { 2, 4 }
, which is a value holding the
values 2 and 4. (As we have discussed earlier in this space,
we are adding support for arrays to Calcapp.)
Ranges and arrays are subtly different in spreadsheets. In Calcapp, there is no
spreadsheet grid, so a range and an array are one and the same. If Field1
,
Field2
and Field3
appear one after the other in the app designer, the
formulas SUM(Field1:Field3)
and SUM({ Field1, Field2, Field3 })
not only
return the same result, they look roughly identical to Calcapp. As such, a range
is simply a more concise way of writing an array.
An example
What if you have five fields (A1
through A5
, appearing one after the other)
and you want to add their values together, but only those that are greater than
two? This has been possible with Calcapp ever since our first release, but you
had to use a long and cumbersome formula:
IF(A1 > 2, A1) + IF(A2 > 2, A2) + IF(A3 > 2, A3) + IF(A4 > 2, A4) + IF(A5 > 2,
A5)
(This formula would become even more unwieldy if you had, say, 100 fields instead of five.)
Spreadsheets make this considerably easier. The standard way to solve this is through the SUMIF formula function:
SUMIF(A1:A5, ">2")
Calcapp currently supports neither arrays nor ranges, explaining why we haven’t been able to support the SUMIF function earlier. This issue will be rectified by our next release, which will add support for not only SUMIF, but also SUMIFS, COUNTIF, COUNTIFS, AVERAGEIF, AVERAGEIFS, MINIFS and MAXIFS.
As teased earlier, Calcapp will not only support the formula
SUMIF(A1:A5, ">2")
(where the ">2"
condition — determining which values
are considered – is expressed as a text string), but also an alternate form
which can be written like so:
SUMIF(A1:A5, Item > 2)
The second parameter is technically known as a lambda (or an anonymous
function), which returns a logical value (TRUE or FALSE), determining whether a
value should be considered. To help this lambda make this decision, the value
under consideration is available as Item
. (The name can be changed, but that’s
a topic for another blog post.)
Lambdas enable you to use complicated logic to determine whether a value should be considered:
SUMIF(A1:A5, (Item > 2) && (Item < 10) && ISODD(Item)
The example above only considers values which are greater than two, are less than ten and are odd. (In other words, only 3, 5, 7 and 9 are considered.)
Modern Excel and dynamic arrays
One of the most exciting changes to come to Microsoft Excel are dynamic arrays, along with a number of new formula functions. Dynamic arrays make it much simpler to perform actions like filtering an array (returning a copy of said array only containing elements satisfying a certain condition with the FILTER function) and removing duplicates from an array (with the UNIQUE function).
We’re happy to announce that we will have full coverage of Microsoft’s new dynamic array functions when our next release becomes available.
Let’s return to the SUMIF(A1:A5, ">2")
example above. If you think about it,
there are two things going on here. First, the array consisting of the A1:A5
values is filtered to only contain values that are greater than two. Second,
these values are added together and returned.
Filtering the array can be accomplished using the new FILTER function, and summing them can be done using the SUM function. Here’s what that looks like:
SUM(FILTER(A1:A5, A1:A5>2))
FILTER is asked to filter the A1:A5
range, passed as the first parameter. The
second parameter is also an array, with the same size as the first parameter.
However, it is a logical array, consisting of TRUE and FALSE values. A1:A5>2
returns an array consisting of TRUE values where the value is greater than two,
and FALSE values elsewhere. That means that { 1, 2, 3, 4 }>2
returns { FALSE,
FALSE, TRUE, TRUE }
, because only 3 and 4 are greater than two.
SUM(FILTER(A1:A5, A1:A5>2))
may look more cumbersome than SUMIF(A1:A5, ">2")
— and it is — but it provides far more flexibility. Which you wind up using
depends on your needs and on your preferences.
When will this become available?
We’re in the last stages of our big formula revamp (which is the first step of our next-generation Calcapp 4 project). We hope that our next release, containing these features, will see the light of day in March.