Body property

EmailReportButton.Body — Text

Special value available in formulas:

Item

EmailReportButton

The button this property is part of, enabling multiple checked items in the app designer to share the same formula and be updated all at once.

Consider the fields Field1 and Field2, which should only be considered to be valid if their values are greater than 4. Without using the Item value, the Valid property of Field1 would need to use the formula Field1 > 4Field1 > 4 and the Valid property of Field2 would need to use the formula Field2 > 4Field2 > 4.

Using Item, both formulas can read Item > 4Item > 4. This is useful if you have many fields and you want to be able to update their formulas all at once. To do so, click their check boxes in Calcapp Creator and make sure that a checked field is selected. Then, when you update a formula for one checked field, you update all the other checked fields too, which is a great timesaver.

Use Item in exactly the same way you'd use the regular name. Button1.VisibleButton1,Visible and Item.VisibleItem,Visible are equivalent, for instance.

The body of the sent email.

If this property is not set, a default body is used. If the format of the email report button calls for a file to be attached (containing, say, a PDF document), the default body includes instructions in English on how to open the attached file. By setting a body explicitly through this property, you can fully determine the email body yourself.

If the format of the button is set to text, field values are included directly in the email body and are not part of an attached file. In this case, the body as set through this property appears just before the text that appears before field values in the email body. If the format is set to text, the default body is empty.

Building the body of an email with formulas

You can make values entered in your app part of the email body using formulas. If you set the body using the inspector in Calcapp Creator, enclose formulas inside of {{ and }} markers.

Consider this body:

To whom it may concern,

The weight is {{Weight}} lbs.

The value above produces something like the following:

To whom it may concern,

The weight is 23.30 lbs.

Inside {{ and }}, you can use any formulas you like.

Behind the scenes, Calcapp converts an inspector value with formulas to a single traditional formula. You can view this formula, or edit it directly, by selecting the Body property from the drop-down menu next to the formula bar.

The rest of the examples on this page use traditional formulas, where text strings and other values are joined together using & and line breaks are produced using NEWLINE. To enter them in the inspector, be sure to enclose them within {{ and }} markers. Alternatively, enter them in the formula bar.

Creating a list of field values

Calcapp can be instructed to incorporate fields and their values in your email body, without your having to write any formulas. Simply set the format to text and decide which fields to include — which can be done using the IncludedFields property — and Calcapp will produce a table of fields and their values, right in your email body.

What if you, for reasons of maximum flexibility, want to produce this list using a formula? If your screen contains 100 fields, referencing them one by one in a formula is not appealing:

"Weight: " & Weight.FormattedValue & NEWLINE() & "Length: " & Length.FormattedValue & NEWLINE() & ..."Weight: " & Weight,FormattedValue & NEWLINE() & "Length: " & Length,FormattedValue & NEWLINE() & ...

Luckily, Calcapp supports a compact way of referencing many fields at once. Field1:Field5Field1:Field5 creates an array bookended by Field1 and Field5, with all the fields that appear between them sandwiched between them (like Field2, Field3 and Field4).

For the purposes of the examples below, let's assume that Field1:Field5Field1:Field5 is equivalent to { Field1, Field2, Field3, Field4, Field5 }{ Field1; Field2; Field3; Field4; Field5 } and that their values are 1, 2, 3, 4 and 5, in that order.

A formula associated with Body must return a text string, whereas Field1:Field5Field1:Field5 is an array of fields. To convert their values to a single text string, TEXTJOIN may be used:

TEXTJOIN(", ", FALSE, Field1:Field5)TEXTJOIN(", "; FALSE; Field1:Field5)

This results in the values of all fields being joined together in a single text string, separated by commas: 1, 2, 3, 4, 5.

What if every value should appear on its own line? Simply replace the first parameter with NEWLINE, causing all values to be separated by line breaks:

TEXTJOIN(NEWLINE(), FALSE, Field1:Field5)TEXTJOIN(NEWLINE(); FALSE; Field1:Field5)

This is the text produced by the formula:

1
2
3
4
5

Including the field label

Just having a list of values isn't very descriptive, though. To include the field label in the body, use the Label property of fields:

TEXTJOIN(NEWLINE(), FALSE, (Field1:Field5).Label & ": " & Field1:Field5)TEXTJOIN(NEWLINE(); FALSE; (Field1:Field5),Label & ": " & Field1:Field5)

Here's the end result (assuming that the label of every field is identical to its name):

Field1: 1
Field2: 2
Field3: 3
Field4: 4
Field5: 5

Omitting blank values and hidden fields

Calcapp's native support for including field values in the email body supports omitting blank values and hidden fields. If the field values are produced through a Body formula, we can achieve the same effect using the FILTER function.

This formula returns the array { 20, 30 }{ 20; 30 }, because only 2 and 3 are greater than 1:

FILTER({ 10, 20, 30 }, { 1, 2, 3 } > 1)FILTER({ 10; 20; 30 }; { 1; 2; 3 } > 1)

The second parameter to FILTER is a logical array with the same number of elements as the first array, where TRUE elements indicate that the corresponding element in the first array should be included in the returned array from FILTER, and FALSE elements indicate that they should not be.

Applying this logic to fields, the following formula returns an array containing only fields whose values are not blank, using the ISDEFINED function:

FILTER(Field1:Field5, ISDEFINED(Field1:Field5))FILTER(Field1:Field5; ISDEFINED(Field1:Field5))

If the Field1:Field5Field1:Field5 range includes elements that are not fields (like a button appearing directly after Field1), those elements will generally be included. In order to only include fields with non-blank values, the Value property can be specified explicitly:

FILTER(Field1:Field5, ISDEFINED((Field1:Field5).Value))FILTER(Field1:Field5; ISDEFINED((Field1:Field5),Value))

This formula only includes visible fields:

FILTER(Field1:Field5, (Field1:Field5).Visible)FILTER(Field1:Field5; (Field1:Field5),Visible)

To transform these fields and their values to a text string suitable for use with the Body property, we should add the MAP function to our arsenal, which is the topic of the next section.

Transforming field arrays to email bodies with MAP

MAP takes an array as its first parameter and a formula fragment that transforms every array element as its second parameter. Ultimately, MAP returns an array of all the transformed array elements, in the original order. This MAP formula transforms the array { 1, 2, 3 }{ 1; 2; 3 } into the array { 10, 20, 30 }{ 10; 20; 30 } by multiplying every element with 10:

MAP({ 1, 2, 3 }, Element * 10)MAP({ 1; 2; 3 }; Element * 10)

The reason we need MAP is because otherwise we need to repeat the FILTER invocation every time we reference the field array. With MAP, we can do it just once, and then transform the value using a formula fragment.

The FILTER formula must be given as the first parameter to MAP, to enable the field values to be included in an email body. This formula only includes values of visible fields:

TEXTJOIN(NEWLINE(), FALSE, MAP(FILTER(Field1:Field5, (Field1:Field5).Visible), Element.Label & ": " & Element))TEXTJOIN(NEWLINE(); FALSE; MAP(FILTER(Field1:Field5; (Field1:Field5),Visible); Element,Label & ": " & Element))

Here's an equivalent formula which does not use MAP:

TEXTJOIN(NEWLINE(), FALSE, FILTER(Field1:Field5, (Field1:Field5).Visible).Label & ": " & FILTER(Field1:Field5, (Field1:Field5).Visible))TEXTJOIN(NEWLINE(); FALSE; FILTER(Field1:Field5; (Field1:Field5),Visible),Label & ": " & FILTER(Field1:Field5; (Field1:Field5),Visible))

Finally, here's an equivalent formula that uses LET to cut down on formula repetition instead of MAP:

LET(Fields := Field1:Field5, TEXTJOIN(NEWLINE(), FALSE, FILTER(Fields, Fields.Visible).Label & ": " & FILTER(Fields, Fields.Visible)))LET(Fields := Field1:Field5; TEXTJOIN(NEWLINE(); FALSE; FILTER(Fields; Fields,Visible),Label & ": " & FILTER(Fields; Fields,Visible)))

Examples

"Dear " & Name & "," & NEWLINE() & NEWLINE() & "The
weight is " & FORMATNUMBER(Weight) & " lbs."
"Dear " & Name & "," & NEWLINE() & NEWLINE() & "The
weight is " & FORMATNUMBER(Weight) & " lbs."

Sets the body of an email sent through an email report button to Dear, , followed by the value of the Name field, followed by two line breaks, the text The weight is, a formatted version of the value of the Weight field and finally the text lbs..

TEXTJOIN(NEWLINE(), FALSE, (Field1:Field100).Label & ": " & Field1:Field100)TEXTJOIN(NEWLINE(); FALSE; (Field1:Field100),Label & ": " & Field1:Field100)

Sets the body of an email sent through an email report button to the values of the fields Field1, Field100 and all fields that appear between them. Every field value appears on its own line and is preceded by the label of the corresponding field.

The label of a field is accessed using the Label property. & joins text strings together. TEXTJOIN takes the array of text strings and turns it into a single text string, where each array element is separated by a line break (courtesy of the NEWLINE function).

TEXTJOIN(NEWLINE(), FALSE, MAP(Field1:Field100, "Value " & Index & ": " & Element))TEXTJOIN(NEWLINE(); FALSE; MAP(Field1:Field100; "Value " & Index & ": " & Element))

Sets the body of an email sent through an email report button to the values of the fields Field1, Field100 and all fields that appear between them. Every field value appears on its own line and is preceded by a text string identifying the position of the array element (first, second, etc).

MAP is used to convert the fields of the Field1:Field100Field1:Field100 range into text strings of the form "Value 1: [value of Field1]", "Value 2: [value of Field2]", etc. MAP makes the position of the array element available as Index. & joins text strings together. TEXTJOIN takes the array of text strings transformed by MAP and turns it into a single text string, where each array element is separated by a line break (courtesy of the NEWLINE function).

TEXTJOIN(NEWLINE(), FALSE, MAP(FILTER(Field1:Field100, ISDEFINED((Field1:Field100).Value)), Element.Label & ": " & Element))TEXTJOIN(NEWLINE(); FALSE; MAP(FILTER(Field1:Field100; ISDEFINED((Field1:Field100),Value)); Element,Label & ": " & Element))

Sets the body of an email sent through an email report button to the values of the fields Field1, Field100 and all fields that appear between them. Fields without a defined value are omitted. Every field value appears on its own line and is preceded by the label of the corresponding field.

The FILTER function, in conjunction with the ISDEFINED function, ensures that only fields with defined (non-blank) values are included.

MAP is used to convert the fields of the Field1:Field100Field1:Field100 range into text strings of the form "[label of Field1]: [value of Field1]", "[label of Field2]: [value of Field2]", etc. The label of a field is available through the Label property. & joins text strings together. TEXTJOIN takes the array of text strings transformed by MAP and turns it into a single text string, where each array element is separated by a line break (courtesy of the NEWLINE function).

TEXTJOIN(NEWLINE(), FALSE, MAP(FILTER(Field1:Field100, (Field1:Field100).Visible), Element.Label & ": " & Element))TEXTJOIN(NEWLINE(); FALSE; MAP(FILTER(Field1:Field100; (Field1:Field100),Visible); Element,Label & ": " & Element))

Sets the body of an email sent through an email report button to the values of the fields Field1, Field100 and all fields that appear between them. Invisible fields are omitted. Every field value appears on its own line and is preceded by the label of the corresponding field.

The FILTER function, in conjunction with the Visible property, ensures that only visible fields are included.

MAP is used to convert the fields of the Field1:Field100Field1:Field100 range into text strings of the form "[label of Field1]: [value of Field1]", "[label of Field2]: [value of Field2]", etc. The label of a field is available through the Label property. & joins text strings together. TEXTJOIN takes the array of text strings transformed by MAP and turns it into a single text string, where each array element is separated by a line break (courtesy of the NEWLINE function).