# Standard spreadsheet services

This chapter covers the spreadsheet objects available in the standard spreadsheet module. All functions and objects are part of the `afnix-sps` module and bounded in the `afnix:sps` nameset.

## Folio object

The `Folio` object is the primary object used for storing data. Although, a folio is a collection of sheets, it the primary object that should be created when manipulating such collection.

## Creating a folio

The `Folio` object is built without argument. In this case, the folio is empty. A predicate is available for testing the `Folio` object.

const sps (afnix:sps:Folio) afnix:sps:folio-p sps # true

The constructor can operate also by name or by input stream. With a string, a new folio those name is the argument is created. By stream, a new folio is created and loaded with the input stream data. Eventually, the folio name can be set with the `set-name` command and retrieved with the `get-name` command.

const sps (afnix:sps:Folio) sps:set-name "planets"

## Sheet object

The `Sheet` object is the primary object used to store data in a folio. Since a `Folio` object is a collection of sheets, a sheet can be manipulated either by getting getting it from the folio or by creating it independently and adding it into the folio.

## Creating a sheet

An empty sheet can be created simply with or without name. Without argument, an unnamed sheet is created. Similar to the `Folio` class, the sheet name can be passed at construction or set with the `set-name` method. As usual a predicate is provided.

const sht (afnix:sps:Sheet) afnix:sps:sheet-p sht # true

When the sheet is created, it can be added to the folio spreadsheet with the `add` method.

const sht (afnix:sps:Sheet "data") sps:add sht

## Adding data to the sheet

The process of adding data to a sheet is a straightforward operation with the `add-data` method or the `add` method. With the `add-data` method, data are added as literals. With the `add` method, data are added with the help of a record object.

sht:add-data "Mercury" 4840 "1407:36" sht:add-data "Venus" 12400 "5819:51" sht:add-data "Earth" 12756 "23:56" sht:add-data "Mars" 6800 "24:37" sht:add-data "Jupiter" 142800 "9:50" sht:add-data "Saturn" 120800 "10:14" sht:add-data "Uranus" 47600 "10:49" sht:add-data "Neptune" 44600 "15:40" sht:add-data "Pluto" 5850 "153:17" sht:add-data "Sedna" 1800 "960:00"

Data can be imported in a sheet by importation with an input stream. During the importation, the serialized data are decoded and placed sequentially in the stream.

## Sheet sorting

A sheet can be sorted with the `sort` method. The `sort` method uses the first integer argument as the column number. The second optional argument is a boolean argument that selects the sorting method which can be ascending (by default) or descending if the flag is false.

sht:sort 0 sht:sort 1 false

## Record object

The `Record` object is an alternative to the sheet data filling. With the help of the `add` method, a record can be added to a sheet.

## Creating a record

A record is a named object that acts as a vector of cells. The record name can be set either by construction or with the `set-name` method. As usual a predicate is provided.

const rcd (afnix:sps:Record) afnix:sps:record-p # true

## Filling a record

A record can be filled either with literal data or `Cell` objects. In the first case, the cell is automatically created for each literal added to the record. The `add` method add a cell or literal to the record.

const rcd (Record) rcd:add "Mercury" 4840 "1407:36"

For data extraction, the `length` method returns the record length. Data can be extracted by index with either the `get` or `map` method. The `get` method returns the record cell while the `map` method returns the cell literal.

## Object search

The search methodology is divided either by sheet or cells. In a folio, the search is done in terms of sheets while the construction of a cross-reference table is required for searching cells.

## Searching in a folio

The `Folio` object provides the primary mean to search for sheet. The `find` and `lookup` methods return a sheet by tag. The first sheet that matches the tag is returned by these methods. The `find` method returns nil if the sheet cannot be found while the `lookup` method throws an exception.

# get a sheet by tag const sheet (folio:lookup "the tag")

If there are several sheets that matched the tag, the `filter` method is more appropriate. The `filter` method returns a new folio that contains the sheet that matches the requested tag.

# get a sub-folio by tag const sf (folio:filter "the tag")

## Searching for a cell

The `Folio` object also provides the method for building a cross-reference table. The cross-reference table is represented by the `Xref` object. By default, a complete `Xref` object table is built with the `getxref` folio method. Such method, scan all cells in the folio and add them in the cross-reference table if the cell has a name.

# get a default xref table const xref (folio:getxref)

The cross-reference table can also be built by searching for sheet tags. With a string argument, the `getxref` search for all sheets that matches the tag and then build a cross-reference table. This method is equivalent to the operation of building a new folio by tag with the `filter` method and then building the cross-reference table.

# get a xref table by tag const xref (folio:getxref "the tag") # another method const sf (folio:filter "the tag") const xref (sf:getxref)

A cross-reference table can also be built by cell index and/or record index. With a cell index, the cross-reference table is built by indexing the sheet column. With both the cell and record indexes, the cross-reference table is built by indexing all cells at the coordinate for all sheets.

# get a xref table by cell index const xref (folio:getxref 0) # get a xref table by cell and record index const xref (folio:getxref 0 1)