Build a good table
/extract never stores a template: it reads the table you select, each time. How you lay the table out decides what Moby matches, what it fills and what it leaves alone. This page gives the reading rules, the habits that make a run reliable and the mistakes seen most often.
How /extract reads a table
| Element | Rule |
|---|---|
| Header rows | The first rows of the selection, top to bottom: category (matching only), column titles, optional description row. The data starts right under the last one |
| Description row | A row directly under the titles with hints ("in euros", "DD/MM/YYYY", "bottom right of the invoice") becomes part of the meaning of each column. A row of numbers or dates is data, never a description |
| Filled column | A matching key: Moby uses its values to find the document of each row. It is never written, even when partly blank |
| Empty column with a title | Filled from the document, one value per cell |
| Formula column | Skipped entirely |
| Column with no title and no data | Dropped |
| Merged label above columns | One document-type block (Invoice, Delivery note, Bank statement). A block holding only filled columns is the ledger block: an empty column inside it stays a key and is never filled |
| Same document type in two blocks | Read as one group when both blocks carry the same label. Two different labels for one document type mean two groups and two extractions |
| Mode | Keys and columns to fill: matching. No filled column: extraction, one new row per document. No column left to fill: Moby only matches and writes the Document column |
The rules
For every table
| # | Rule | Avoid | Do |
|---|---|---|---|
| R1 | One value, not a presence | "Is there an invoice in this document?" | "Invoice number" |
| R2 | A clear title, and a description under it only when the title alone is unclear | "Amount" alone: excl. VAT, incl. VAT or VAT? | "Amount incl. VAT", or "Amount" with the description "incl. VAT, in euros, bottom right of the document" |
| R3 | One reading per title | "Reference": invoice, order or customer? | "Order number, format PO-XXXX, top right" |
| R4 | The workflow extracts, it does not compute | Asking for the sum of the lines | Extract the values, then =SUM() in Excel. The agent can compute |
| R5 | Paste only the useful rows and columns | The whole general ledger or trial balance | The rows and columns the check needs |
| R6 | One document per PDF | A PDF bundling several documents, or one document spread over several files | /split a bundle first, /merge the pieces first |
For a matching table
| # | Rule | Why |
|---|---|---|
| K1 | Every key gets an empty twin in the document block | Matching uses the filled keys and never writes them. You can only compare the ledger and the document when the document's value is extracted next to the key: "Amount" filled on the ledger side, "Amount (invoice)" empty on the invoice side |
| K2 | One labelled block per document type | Without a label, the columns of a second document type are read as if they came from the first |
| K3 | Never split one document type under two labels | Two groups mean every document is read twice |
| K4 | Keys that identify: a reference first, then a distinctive amount, then the counterparty and a date | Moby tries identifiers first, then a distinctive amount, then the entity and its context |
For an extraction table
| # | Rule | Why |
|---|---|---|
| E1 | Select every header row and keep the rows under the header free | Moby writes one row per document there without inserting rows. Only cells inside the selection are protected, so a description row left out of the selection is overwritten |
Common mistakes
| What you see | Why | Fix |
|---|---|---|
| One new row per document instead of your rows being filled | The table has no filled column, so Moby reads it as an extraction | Paste the rows to test with their ledger columns (reference, amount, date) |
| Rows under the header are overwritten | Extraction writes from the first row under the header, without inserting | Select the description row too, and clear or move what sits under the header |
| Nothing is filled, only the Document column | No empty column with a title | Add the columns to fill, empty, in the document block |
| The value Moby found is not on the sheet, so no check is possible | A key has no empty twin | Add an empty "Amount (invoice)" column in the document block |
| A column you wanted filled stays empty | It sits under the ledger label, or it has no title, or it holds formulas | Move it into a document block, give it a title, move the formula elsewhere |
| A column you wanted filled is treated as a key | It was already full | Clear it, or add a new empty column |
| The wrong amount or date comes back | The title can be read several ways | A precise title, or a description row |
| Values of a second document type look wrong | Several document types share one block, or one type sits under two labels | One merged label per document type, the same label for the same type |
| The run is refused | More than 30 columns or 400 rows | Split the table or the run |
| Columns or rows are ignored | The selection stops before the edge of the table | Select the whole table |
Two layouts that work
Titles only, for extraction. Select the header rows.
| A | B | C | D | |
|---|---|---|---|---|
| 1 | Invoice no. | Invoice date | Supplier | Amount incl. VAT |
| 2 | empty: one row per document from here |
A ledger block and a document block, for matching. Select the whole table.
| A | B | C | D | E | F | G | H | |
|---|---|---|---|---|---|---|---|---|
| 1 | Accounting (merged A1:D1) | Invoice (merged E1:H1) | ||||||
| 2 | Entry ref | Entry date | Customer | Amount excl. VAT | Invoice date | Customer | Amount excl. VAT | Invoice no. |
| 3 | on the invoice, DD/MM/YYYY | name printed on the invoice | excl. VAT, number only | top right | ||||
| 4 | 5351200093 | 02/12/2025 | Spécialités Pharma | 46,348 |
Columns A to D are filled: the keys. Columns E to H are empty: filled from the invoice. F and G are the twins of C and D, and H adds the identifier.
With several document types, add one block per type: for a bank reconciliation, the account columns as keys, then a block for the reconciliation statement, one for the bank statement and one for the bank confirmation. The tie-out checks are formulas, not extracted values.
Shortcuts
| You want | Do this |
|---|---|
| A sheet already built for an audit test | /workpaper, tab Moby: ready-made sheets by cycle. See Workpaper library |
| A second opinion on your table before a run | Ask the agent: "check my table before extracting". It reports what the run should do and proposes edits; it changes the sheet only when you say which ones |
| To practise on sample documents | Your first dive |