# Standard Spreadsheet Module

The Standard Spreadsheet module is an original implementation that provides the necessary objects for designing a spreadsheet. A spreasheet acts a great interface which structure data in the form of record and sheets. Once structured, these data can be indexed, manipulated and exported into various formats.

## Spreadsheet concepts

The sole purpose of using a spreadsheet is to collect various data and store them in such a way that they can be accessed later. Unlike standard spreadsheet system, the standard spreadsheet module does not place restrictions on the data organization.

The spreadsheet module stores data in a hierarchical fashion. The basic data element is called a cell. A set of cells is a record. A set of records is a sheet. A set of sheets and records is a folio.

### Cell and data

A cell is a data container. There is only one data element per cell. Eventually a name can be associated with a cell. The cell data can be any kind of literals. Such literals are integer, real, boolean, character or strings.

### Record

A record is a vector of cells. A record can be created by adding cell or simply by adding data. If the record has a predefined size, the cell or data can be set by indexing.

### Sheet

A sheet is a vector of records. A sheet can be created by adding record. Similarly, if the sheet has a predefined size, record cell or data can be added by indexing. A sheet can also be seen as a 2 dimensional array of cells. For the purpose of managing extra information, the sheet carry also several extra records, namely, the marker record, the header record and footer record as well as the tag vector and the signature.

### Folio

A folio is a set of sheets and/or records. A folio of sheets permits to structure data in the form of tables. Since cell, record and table can have a name, it is possible to create link between various elements, thus creating a collection of structured data.

## Storage model

There are several ways to integrate data. In the simplest form, data are integrated in a record list. A complex model can be built with a sheet. More complex models can also be designed by using a folio.

### Single record model

With a single record model, the data are accumulated in a single array. This kind of data storing is particularly adapted for single list recording. As a single record, the basic search and sorting algorithm can be applied. For instance, a list name can be stored as a single record. With this view, there is no difference between a list, a vector and a record. The record can also be named.

### Record importation

Data are imported into the record, either by construction, list or stream. Since the record object is a serializeable object, the importation process is also performed automatically in the collection. The base record importation class implements a simple importation model based on blank separated literals. Complex importation models can be devised by derivation. A special case with a cons cell is also supported where the car is the cell name and the cadr is the cell object.

# an example of file importation 1 "a string" 'a' 'b' ("cell name" 2) 123

The previous example shows the file structure that can be used to import cell data. The fist line defines a record with 3 cells. The second line defines also a record with 3 cells. The second cell is a named cell.

### Record exportation

A record is an object that can be serialized. It can therefore be exported easily. However, in the serialized form, the record is in a binary form. It is also possible to walk through the record and exports, for each cell its literal form.

## Folio indexation

There are various ways to access a folio by reference. Since a folio can contain several sheets, it seems natural to access them by tag. The other method is to index the cells in a cross-reference album in order to access rapidly.

### Sheet access model

The sheet access model uses a tag to access one or several sheets in a folio. A tag is a string attached to a sheet. It is possible in a folio to have several sheet with the same tag. It is also possible to attach several tags to a sheet. When a folio is searched by tag, the first sheet that matches the tag is said to be the valid one. If all sheets that match the requested tag are needed, it is possible to create a derived folio with all sheets that match the requested tag.

### Cell access model

The cell access model operates with a cross-reference table built with an index. An index is a multiple entry record that stores the cell location. A cell coordinate comprises the cell index in the record, the record index in the sheet and the sheet index in the folio. If an index contains multiple entries, this indicates that several cells are indexed. A cell cross-reference table is a collection of index. Generally the index name is the cell name. When the cross-reference table is built, all cell of interests are scanned and if a cell name exists, the cell is indexed in the cross-reference table. If there are several cells with the same name, the index length associated with the name is the number of cells with that name.

### Search and access

The methodology for searching is to decide whether a sheet or a cell should be accessible. If a sheet access is desired, the search by tag method is the preferred way. This method assumes that the requested sheet is structured in a particular way, known to the user. If a cell access seems more appropriate, a cross-reference table should be built first, and the search done from it. In the case of search by tag, the method is dynamic and operates well when sheets are added in a folio. When a cross-reference table is used, proper care should be taken to rebuild the cross-reference table when some sheets are added unless the user knows that there is no need for it.

## 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)