# Tables and Table Formulas

> Build tables in a WPF TextControl with the ribbon or TableCollection: add rows, open Table Properties, calculate cells with formulas, A1 and R1C1 references.

- **Product:** TX Text Control .NET for WPF
- **Section:** Documentation
- **Kind:** Topic
- **Path:** TX Text Control .NET for WPF > Document Editor > Tables and Table Formulas
- **8043 words**
- **Web URL:** https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/tables/
- **LLMs URL:** https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/tables/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/tables/llms-full.txt

---

In a WPF word processor built with TX Text Control, a table is inserted from the **Insert** tab and changed on the **Table Layout** tab, and its cells can add up, average or compare other cells with formulas that follow the syntax of spreadsheet applications. The same tables are open to your code through `TextControl.Tables`: it inserts and fills them, acts on the table the user is working in and switches on the calculation of formulas.

The examples are event handlers in *MainWindow.xaml.cs* of a window with a `TextControl` named `textControl1`, as in [Create Your First WPF Application](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/getting-started/document-editor/first-application/llms-full.txt). Connect them to buttons or menu items of your window; replace `SampleApp` with the namespace of your project. Tables in documents processed without a user interface are the subject of [Tables and Calculations](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-processing/tables/llms-full.txt) in Document Processing.

### How Tables Are Organized

[TextControl.Tables](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/tables-property/llms-full.txt) returns the [TableCollection](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/tablecollection/llms-full.txt) of the main text, while headers, footers and text frames have their own. The table classes are those of the `TXTextControl` namespace, the same as in the Windows Forms product: a [Table](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/table/llms-full.txt) has [Rows](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/table/rows-property/llms-full.txt), [Columns](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/table/columns-property/llms-full.txt) and [Cells](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/table/cells-property/llms-full.txt), numbered from 1, and a [TableCellFormat](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/tablecellformat/llms-full.txt) holds the borders, colors and number format of a cell, a row or a column.

![Class diagram of the table classes: TextControl, WPF.TextControl and ServerTextControl lead to TableCollection, Table, the row, column and cell collections, TableCell, TableRow, TableColumn and TableCellFormat, with the version each member was introduced in.](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-wpf/tables-class-diagram.5760f9e2.webp)

Your code finds a table in one of two ways:

- **By its ID.** A table your code adds gets an ID from 10 to 32767 (`short.MaxValue`), and [TableBaseCollection.GetItem](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/tablebasecollection/getitem-method/llms-full.txt) with that ID returns it. Tables inserted or pasted by users have no ID.
- **By the input position.** [TableCollection.GetItem](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/tablecollection/getitem-method/llms-full.txt) without a parameter returns the table that contains the input position, or `null`.

Widths, heights and border widths of tables are measured in twips, 1/1440 inch, not in the device-independent units of WPF.

### Work With Tables in the Ribbon

On the **Insert** tab, **Table** in the **Tables** group inserts a table at the input position: users drag over a grid to choose its size, or click **Insert Table...** to type the number of rows and columns.

Two tabs change the table that contains the input position:

| Tab | Class | Groups |
|---|---|---|
| **Table Layout** | [RibbonTableLayoutTab](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/ribbontablelayouttab/llms-full.txt) | **Table** (**Select**, **View Gridlines**, **Properties**), **Rows & Columns** (**Delete**, **Insert Above**, **Insert Below**, **Insert Left**, **Insert Right**), **Merge** (**Merge Cells**, **Split Cells**, **Split Table**), **Frames & Background**, **Alignment** and **Properties**, with the table's ID and descriptive text |
| **Formulas** | [RibbonFormulaTab](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/ribbonformulatab/llms-full.txt) | **Formulas**, **Number Format** and **Formula Settings**, described [below](#calculate-with-formulas) |

A WPF ribbon tab works with the editor once the `TextControl` names it: [RibbonTableLayoutTab](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/ribbontablelayouttab-property/llms-full.txt) and [RibbonFormulaTab](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/ribbonformulatab-property/llms-full.txt) of the `TextControl` hold the `x:Name` of the tabs. The tutorial [Create a WPF Ribbon Application](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/getting-started/document-editor/ribbon/#add-a-table-tools-tab) adds both as a contextual **Table Tools** group, which the WPF version of TX Text Control Words shows while the input position is in a table:

![The ribbon of TX Text Control Words for WPF with the contextual group Table Tools and its tabs Table Layout and Formulas next to the Form Fields tab.](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-wpf/table-tools-tab-group.22db06a3.webp)

**Properties** on the **Table Layout** tab opens the **Table Properties** dialog box with the tabs **Frame and Color**, **Size and Formatting** and **Formulas**. [Connecting Ribbon Tabs in XAML](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/ribbon-ui/ribbon-xaml/llms-full.txt) explains the connections by name, and **View Gridlines** is [TableCollection.GridLines](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/tablecollection/gridlines-property/llms-full.txt) in code: lines that mark the cells on screen and aren't printed.

### Insert a Table From Code

The following handler inserts the line item table of an order, with a heading row that is repeated on every page:

```csharp
using System.Windows;
using TXTextControl;

namespace SampleApp;

public partial class MainWindow : Window
{
    private void InsertTable_Click(object sender, RoutedEventArgs e)
    {
        // No table can be added at the input position, or the text there is protected
        if (!textControl1.Tables.CanAdd || !textControl1.CanEdit)
        {
            return;
        }

        // A heading row and three item rows in three columns, with the ID 10
        textControl1.Tables.Add(4, 3, 10);
        Table table = textControl1.Tables.GetItem(10);

        string[] headings = { "Description", "Quantity", "Price" };

        for (int column = 1; column <= headings.Length; column++)
        {
            table.Cells.GetItem(1, column).Text = headings[column - 1];
        }

        // Repeat the first row at the top of each page
        table.Rows.GetItem(1).IsHeader = true;

        // The first column is 3 inches wide, in twips
        table.Columns.GetItem(1).Width = 3 * 1440;

        table.DescriptiveText = "Line items of the order";

        // Give the keyboard focus back to the editor
        textControl1.Focus();
    }
}
```

The code works as follows:

- [TableCollection.CanAdd](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/tablecollection/canadd-property/llms-full.txt) tells whether a table can be inserted at the input position. It doesn't check protected text fields and document sections; [CanEdit](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/canedit-property/llms-full.txt) does.
- [TableCollection.Add](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/tablecollection/add-method/llms-full.txt) inserts a table with the given rows, columns and ID. Called without parameters, it opens the **Insert Table** dialog box.
- [TableCellCollection.GetItem](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/tablecellcollection/getitem-method/llms-full.txt) returns a cell by row and column, and [TableCell.Text](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/tablecell/text-property/llms-full.txt) sets its text.
- [TableRow.IsHeader](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/tablerow/isheader-property/llms-full.txt) repeats the row at the top of every page the table extends over.
- [TableColumn.Width](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/tablecolumn/width-property/llms-full.txt) sets the width of a column, and [Table.DescriptiveText](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/table/descriptivetext-property/llms-full.txt) the alternative text that screen readers and tagged PDF files use; see [Accessibility and UI Automation](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/integration/accessibility/llms-full.txt).
- A click on a WPF button takes the keyboard focus. `textControl1.Focus()` returns it to the editor, so the user can type into the new table right away.

[Tables and Calculations](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-processing/tables/llms-full.txt) sets borders, colors and text distances through `TableCellFormat`.

### Work With the Table at the Input Position

Buttons of your own for table commands should be enabled only while the input position is in a table. The `TextControl` raises [InputPositionChanged](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/inputpositionchanged-event/llms-full.txt) whenever the input position moves. Declare the buttons and the event in *MainWindow.xaml*, where the prefix `WPF` stands for the namespace `TXTextControl.WPF`:

```xml
<DockPanel>
    <StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
        <Button x:Name="addRowButton" Content="Add Row" Click="AddRow_Click" />
        <Button x:Name="tablePropertiesButton" Content="Table Properties" Click="TableProperties_Click" />
    </StackPanel>
    <WPF:TextControl x:Name="textControl1"
                    InputPositionChanged="TextControl1_InputPositionChanged" />
</DockPanel>
```

The handlers in *MainWindow.xaml.cs* enable the buttons, add a row below the current row and open the **Table Properties** dialog box:

```csharp
using System;
using System.Windows;
using TXTextControl;

namespace SampleApp;

public partial class MainWindow : Window
{
    private void TextControl1_InputPositionChanged(object sender, EventArgs e)
    {
        // Enable the table commands only while the input position is in a table
        bool inTable = textControl1.Tables.GetItem() != null;
        addRowButton.IsEnabled = inTable;
        tablePropertiesButton.IsEnabled = inTable;
    }

    private void AddRow_Click(object sender, RoutedEventArgs e)
    {
        Table table = textControl1.Tables.GetItem();

        if (table != null && table.Rows.CanAdd)
        {
            // One row after the row with the input position
            table.Rows.Add(TableAddPosition.After, 1);
        }
    }

    private void TableProperties_Click(object sender, RoutedEventArgs e)
    {
        if (textControl1.Tables.GetItem() != null)
        {
            textControl1.TableFormatDialog();
        }
    }
}
```

The code works as follows:

- `InputPositionChanged` passes a plain `EventArgs`, not a `RoutedEventArgs`. The handler checks with `Tables.GetItem()` whether there is a table at the input position.
- [TableRowCollection.Add](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/tablerowcollection/add-method/llms-full.txt) adds rows before or after the row with the input position, with `Before` or `After` from [TableAddPosition](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/tableaddposition/enumeration/llms-full.txt), when [CanAdd](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/tablerowcollection/canadd-property/llms-full.txt) is `true`. `Columns` has the same methods for columns.
- [TableFormatDialog](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/tableformatdialog-method/llms-full.txt) opens the **Table Properties** dialog box for the table at the input position. An overload takes the zero-based tab: 0 for frames and colors, 1 for size and alignment, 2 for formulas and number formats.

To merge cells, select them with [Table.Select](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/table/select-method/llms-full.txt), which takes a first and a last row and column, and call [MergeCells](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/table/mergecells-method/llms-full.txt) when [CanMergeCells](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/table/canmergecells-property/llms-full.txt) is `true`. [SplitCells](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/table/splitcells-method/llms-full.txt) splits merged cells, and [Split](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/table/split-method/llms-full.txt) divides the table in two. [CanTableFormat](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/cantableformat-property/llms-full.txt) tells whether the selected text can get table formatting, which depends on the permissions and the edit mode of the document.

[TableCreated](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/tablecreated-event/llms-full.txt) occurs when a table without an ID is pasted or loaded; [Events](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/events/llms-full.txt) lists the other table events.

### Calculate With Formulas

A table cell can hold a formula that calculates its text from other cells of the same table. When an input cell changes, the formula cell is updated; references to other tables aren't possible.

On the **Formulas** tab, users place the input position in a cell, choose a function from **Functions**, add it to the **Formula** box and complete the range, such as `SUM(B1:B4)`, then confirm with the check mark. **Select Cell References** picks the range with the mouse. **Number Format** sets how the result is displayed and whether the cell text is a number, and **Formula Settings** switches the calculation on or off, selects the A1 or R1C1 reference style and shows the references of a formula.

The following handlers fill the prices of the table from the first example, add a total row and apply a formula typed into a text box of your own:

```csharp
using System.Windows;
using TXTextControl;

namespace SampleApp;

public partial class MainWindow : Window
{
    private void AddTotal_Click(object sender, RoutedEventArgs e)
    {
        // Address cells with a column letter and a row number, such as C2
        textControl1.FormulaReferenceStyle = FormulaReferenceStyle.A1;
        textControl1.IsFormulaCalculationEnabled = true;

        Table table = textControl1.Tables.GetItem(10);

        if (table == null)
        {
            return;
        }

        // Numbers with two decimal places
        TableCellFormat amountFormat = new TableCellFormat()
        {
            TextType = TextType.Number,
            NumberFormat = "#,##0.00"
        };

        string[] prices = { "199.99", "99.98", "49.50" };

        for (int row = 2; row <= 4; row++)
        {
            TableCell price = table.Cells.GetItem(row, 3);
            price.CellFormat = amountFormat;
            price.Text = prices[row - 2];
        }

        // A row for the total below the last row
        table.Rows.GetItem(4).Select();
        table.Rows.Add(TableAddPosition.After, 1);

        table.Cells.GetItem(5, 1).Text = "Total";

        TableCell total = table.Cells.GetItem(5, 3);
        total.CellFormat = amountFormat;
        total.Formula = "SUM(C2:C4)";

        // Show cell references in the ruler bar while a formula cell is edited
        rulerBar1.FormulaMode = RulerBarFormulaMode.Auto;
    }

    private void ApplyFormula(string formula)
    {
        TableCell cell = textControl1.Tables.GetItem()?.Cells.GetItem();

        if (cell == null)
        {
            return;
        }

        try
        {
            cell.Formula = formula;
        }
        catch (FormulaException exc)
        {
            MessageBox.Show($"The formula is invalid at character {exc.CharacterIndex}.",
                "Formula Error", MessageBoxButton.OK, MessageBoxImage.Error);
        }
    }
}
```

The code works as follows:

- [FormulaReferenceStyle](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/formulareferencestyle-property/llms-full.txt) sets how formulas address cells: `A1` with a column letter and a row number, `R1C1` with row and column numbers.
- [IsFormulaCalculationEnabled](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/isformulacalculationenabled-property/llms-full.txt) turns on the automatic calculation.
- [TableCellFormat.TextType](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/tablecellformat/texttype-property/llms-full.txt) `Number` makes the cell text a number that formulas calculate with. In that text and in the format string, the period is always the decimal separator and the comma the thousands separator. [NumberFormat](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/tablecellformat/numberformat-property/llms-full.txt) `#,##0.00` displays it with two decimal places.
- [TableCell.Formula](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/tablecell/formula-property/llms-full.txt) sets the formula. A syntax error throws a [FormulaException](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/formulaexception/llms-full.txt) with the one-based [CharacterIndex](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/formulaexception/characterindex-property/llms-full.txt) of the first invalid character; an invalid number format throws a [NumberFormatException](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/numberformatexception/llms-full.txt).
- [RulerBar.FormulaMode](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/rulerbar/formulamode-property/llms-full.txt) shows cell references in the horizontal `RulerBar` named `rulerBar1`: `Auto` in cells with a formula, `Always` in every cell, `Fixed` relative to the cell where the mode was switched on, and `None`, the default, never.

The total cell shows 349.47 and follows every change of a price. The displayed number uses the separators of the system language, as described in [Number Formats](#number-formats). The *Spreadsheet* sample in [Document Editor Examples](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/examples/document-editor/llms-full.txt) adds a formula bar to a WPF window this way.

#### Formula Syntax

Formulas follow the syntax of SpreadsheetML (Office Open XML, ISO/IEC 29500-1, section 18.17.2), which Microsoft Excel and other spreadsheet applications use too. A formula is built from four kinds of elements: constants, cell references and functions stand for values, and operators combine them. In the formula `PI()*R[-2]C[-1]^2`, the cell two rows up and one column to the left is raised to the power of 2 and multiplied by π:

![The formula PI()*R[-2]C[-1]^2 with its parts numbered: 1 the constant 2, 2 the operators ^ and *, 3 the function PI(), 4 the cell reference R[-2]C[-1].](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-wpf/formula-elements.b830642d.webp)

#### Constants

A constant is a value written into the formula: a number, a logical value, a string, an error value or an array.

| Constant | Written as | Formula | Result |
|---|---|---|---|
| Integer | `4` | `9+7` | 16 |
| Decimal number, with a period | `3.937` | `4*5.5` | 22 |
| Engineering notation | `5e4` | `4*3e5` | 1200000 |
| Negative number, with a leading minus | `-7.6` | `-9+7` | -2 |
| Logical | `TRUE`, `FALSE` | `15>7=TRUE` | TRUE |
| String, in double quotes | `"text"` | `"TX"&"Text"&"Control"` | TXTextControl |
| Error | `#N/A` | `NA()` returns the same value | \#N/A |
| Array, in braces | `{1,2,3;4,5}` | `SUM(10,{1,2,3;4,5})` | 25 |

In an array constant, commas separate the values of a row and semicolons separate the rows: `{1;2;3}` is a column of three values, and `SUM({1;2;3})` returns 6. An array holds numbers, logical values and strings. Strings can be compared as well: `"Two"="One"` returns FALSE, and `"FALSE"="FALSE"` returns TRUE.

#### Operators

Arithmetic operators return a number, comparison operators return `TRUE` or `FALSE`, and the text operator joins strings:

| Operator | Meaning | Formula | Result |
|---|---|---|---|
| `+` | Addition | `8+6` | 14 |
| `-` | Subtraction | `14-6` | 8 |
| `*` | Multiplication | `4*3` | 12 |
| `/` | Division | `17/2` | 8.5 |
| `%` | Percent, after a number | `290%` | 2.9 |
| `^` | Exponentiation | `3^2` | 9 |
| `=` | Equal to | `2=2` | TRUE |
| `>` | Greater than | `4>6` | FALSE |
| `<` | Less than | `4<6` | TRUE |
| `>=` | Greater than or equal to | `6>=4` | TRUE |
| `<=` | Less than or equal to | `26<=4` | FALSE |
| `<>` | Not equal to | `2<>2` | FALSE |
| `&` | Joins two strings | `"TX"&"Spell"` | TXSpell |

#### Functions

A function starts with its uppercase name, followed by its arguments in parentheses, separated by commas. The parentheses are required even without an argument, as in `PI()`. An argument is a number, a logical value, a string or an array, written as a constant, given as a cell reference or range, or returned by another function. The result of a function is a number, a logical value, a string or an array.

![The function POWER(1.234,5.1) with its function name, its two arguments and the parenthesis area labeled.](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-wpf/formula-function-parts.6541df41.webp)

| Formula | Result |
|---|---|
| `ABS(-7.765)` | 7.765 |
| `PI()` | 3.141592654 |
| `POWER(3,2.5)` | 15.5884573 |
| `SUM(1,2,3)` | 6 |
| `SUM({1;2;3})` | 6 |
| `SUM(A1:A3)` | 6, when cells A1, A2 and A3 hold 1, 2 and 3 |

The functions come from the mathematical and trigonometric, statistical, logical, lookup and reference and information functions of SpreadsheetML. [Formula Functions](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/formula-functions/llms-full.txt) lists all 85 with their arguments, defaults and limits, such as `COUNT`, which doesn't count dates. [TableCollection.SupportedFormulaFunctions](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/tablecollection/supportedformulafunctions-property/llms-full.txt) returns their names at runtime, for example to fill a drop-down list.

#### Cell References

`FormulaReferenceStyle` decides whether a formula addresses other cells of its table in A1 or in R1C1 style.

**A1 style.** A column letter and a row number address a cell. The columns are named A to Z, then AA to AZ, BA to BZ and so on, so `B3` is the cell in the second column of the third row. A plain A1 reference is relative to the formula cell, the same as a relative R1C1 reference. A `$` before the column, the row or both makes that part absolute, independent of where the formula is: `$B$3`, `$B3` or `B$3`.

**R1C1 style.** `R` with a row number and `C` with a column number address a cell. In square brackets, the numbers are relative: the number of rows and columns from the formula cell, negative up and to the left, `[0]` in the same row or column. Without brackets, as in `R5C4`, they are absolute. For a formula in row 4 and column 3, the relative references point at these cells:

![A table of five rows and four columns, labeled R1 to R5 and C1 to C4, with a formula with a cell reference in the cell at R4 and C3 and numbers in the other cells.](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-wpf/formula-r1c1-table.44608763.webp)

| Relative reference | Refers to |
|---|---|
| `R[-3]C[-1]` | Row 1, column 2 (R1C2) |
| `R[1]C[-2]` | Row 5, column 1 (R5C1) |
| `R[0]C[1]` | Row 4, column 4 (R4C4) |
| `R[-2]C[1]` | Row 2, column 4 (R2C4) |

Text Control recommends relative references, because absolute ones return wrong or invalid values once the table is edited or its cells are pasted as a new table.

A range consists of the upper left and the lower right cell, separated by a colon. For a formula in row 3, column 3, the four ranges below cover the numbered areas:

![A table of five rows and five columns with four marked areas: 1 SUM(R[-1]C[-2]:R[0]C[-1]), 2 SUM(R[-2]C[0]:R[-1]C[0]), 3 SUM(R[-2]C[2]:R[1]C[2]) and 4 SUM(R[2]C[-1]:R[2]C[1]).](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-wpf/formula-cell-ranges.38fceb7e.webp)

`LEFT`, `ABOVE`, `RIGHT` and `BELOW` refer to all cells in one direction from the formula cell, as in `SUM(ABOVE)`:

![A table with a formula cell SUM(...) in row 3, column 3 and the four areas that LEFT, ABOVE, RIGHT and BELOW refer to, numbered 1 to 4.](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-wpf/formula-left-above-right.dc8142f4.webp)

### Number Formats

A number format decides how the number of a cell is displayed, whether a user typed it, your code set it or a formula calculated it. It applies when `TextType` is `Number`. Without a format, `NumberFormat` is an empty string: a whole number is shown without decimal places, and a decimal number with all of its decimal places.

A format is made of the placeholders `#` and `0`, the separators `.` and `,`, the percent sign `%` and other characters or text. The rules:

| Rule | Number format | Value | Displayed |
|---|---|---|---|
| `#` shows only the digits the number has | `#` | 1234 | 1234 |
| `0` fills a position with a zero | `000` | 7 | 007 |
| Without a period, the number is rounded to an integer | `#` | 17.548 | 18 |
| The placeholders after the period are the maximum number of decimal places | `#.##` | 12.6 | 12.6 |
| `0` after the period always shows the decimal place | `#.00` | 5 | 5.00 |
|  | `#.00` | 0.543 | 0.54 |
| A comma followed by placeholders inserts a thousands separator | `,###.##` | 9876543210.1234 | 9,876,543,210.12 |
|  | `#,##0.00` | 4471000 | 4,471,000.00 |
| A comma without a placeholder after it divides by 1,000, once per comma | `#,,` | 12200000 | 12 |
|  | `#.0,,` | 12200000 | 12.2 |
| `%` with a placeholder multiplies by 100 | `#%` | 0.52 | 52% |
|  | `0.##%` | 0.00321 | 0.32% |
| `%` can stand before the placeholders | `%#` | 0.52 | %52 |

The period and the comma of a format string mean the decimal and the thousands separator in every language. The displayed number uses the separators of the system language: on a German system, the decimal separator is shown as a comma and the thousands separator as a period.

These characters can be written into a format as they are: `$`, `-`, `+`, `/`, `(`, `)`, `:`, `!`, `^`, `&`, `'`, `~`, `{`, `}`, `<`, `>`, `=` and the space. Any other single character, such as a currency symbol, a letter or a digit that isn't a placeholder, needs a backslash before it. Words go in double quotes:

| Number format | Value | Displayed |
|---|---|---|
| `#$` | 500 | 500$ |
| `+.##` | 12.345 | +12.35 |
| `~#.0` | 7.654 | ~7.7 |
| `{-#}` | 67 | {-67} |
| `\1/#` | 4 | 1/4 |
| `#.00\€` | 12.99 | 12.99€ |
| `\"#\"` | 42 | "42" |
| `#:\X` | 18 | 18:X |
| `# "Units"` | 76 | 76 Units |

[TableCollection.SupportedNumberFormats](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/tablecollection/supportednumberformats-property/llms-full.txt) lists common formats, the list of the **Number Format** box. The blog article [Formatting Numbers in Table Cells](https://www.textcontrol.com/blog/2022/06/21/formatting-numbers-in-table-cells/) shows more of them.

### Remove a Table

[TableBaseCollection.Remove](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/tablebasecollection/remove-method/llms-full.txt) removes a table by its ID, and [TableCollection.Remove](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/tablecollection/remove-method/llms-full.txt) without a parameter the table at the input position. Users choose **Delete Cells**, **Delete Columns**, **Delete Rows** or **Delete Table** from **Delete** on the **Table Layout** tab.

### Next Steps

- [Text and Paragraph Formatting](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/formatting/llms-full.txt): format the text in table cells.
- [Merge Blocks](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/mail-merge/blocks/llms-full.txt): repeat a table row for each record of your data.
- [Sections and Page Layout](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/sections/llms-full.txt): put a wide table on a landscape page.
- [Tables and Calculations](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-processing/tables/llms-full.txt): tables in code without a user interface.

---

## Nearby

- **Previous:** [Bullets and Numbered Lists](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/lists/llms-full.txt)
- **Next:** [Images](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/images/llms-full.txt)
