Log in

All POD statements, as described in the ODT section, can also be used within an ODS template.

A statement applies to a part of the template. Within an ODT template, it is quite intuitive to deduce the part of the document you are currently "in". When you open a blank ODT file, you are "in" a paragraph. If you create a table and position the cursor in its first cell, you are "in" a cell, being itself in a row, being itself in a table. If you create a section, and you place the cursor in it, you are "in" a paragraph, being itself in a section.

In an ODS template, forget about paragraphs, titles or sections. When you create a blank ODS file, LibreOffice creates a empty sheet, implemented as a table. If you create multiple sheets, it is like if you were in an ODT document exclusively made of tables.

Generating multiple sheets

One sheet = one table. Consequently, positioning, in the first cell of a sheet, a statement of the form:

do table for someData()

creates an ODS result made of as many sheets as elements returned by function someData().

Consider the following example. Parts of it are written in french. If you don't master it, don't panic. This is a unique opportunity for you to learn this fantastic language while learning Appy. And this is free! (unless I change my mind).

This ODS template comes from an app allowing to register children to activities. Activities take place at some periods (ie, summer week 1, summer week 2, ...). The objective is to produce one sheet per period, containing all children registered at this period.

The first (merged) cell of this sheet contains a comment misused to encode a POD statement. This is a multi-statement:

  • the for part will create as many sheets as there are datasets as returned¬†by expression helpers.ChildrenWalker(objects).get();
  • the with part will define variable tableName, accessible in the context of the every sheet (=every table from the POD point of view).

The second row hardcodes column headers.

The third row will be repeated for every child found in the current period-related dataset, thanks to the "do row" statement, which is, again a multi-statement:

  • the for part allows to create one copy of the row for every child;
  • a silly developer has injected some parents within lists of children, so the if sub-statement ignores any child not being a real child;
  • the ending with statement unwraps the child's parent as variable parent, easier to use in subsequent POD expressions.

Every cell in the third row is a POD expression conforming to the convention explained in the previous page. For example, the expression being truncated in cell E3 is

It computes the child's age at the start of the period.

The 4th row is only shown if no child is registered (yet) to this period (check the corresponding if statement).

I let you imagine the ODS result, because, for privacy reasons, I can't dump a real example and will not take the time to invent silly names. But here is a part of the names of the sheets that were generated in the ODS result. "√Čt√©" means "summer" in french, congrats for having learned your first word. The number into parentheses is the number of children registered at every period.

You may say: how the hell did you set these nice names to the generated sheets? In the ODS template, a single sheet, named with hard-coded string "Children" was there (but not shown on the screenshot).

The most attentive of you have understand that this magick was done by defining variable tableName in the main POD statement. Indeed, this is a POD convention: defining a variable named tableName will be used to name the enclosing table. You can also use this convention in ODT templates. In ODT, however, table names are not so important: they appear at some places in the UI, it's true, but this is ignored by most users. In ODS files, it is more important: a table represents a sheet; its name direclty appears in the range of sheets.

When using variable tableName, please respect the typing conventions imposed by LibreOffice: