Small BusinessIndependent InvestorTrade BusinessAccountingFinanceLegalMarketingOperationsSalesReal EstateTemplatesPricingDocs
Get started

Step Guide: Dataset

Data & Files

Store, look up, and update your own data across workflow runs

Overview

A dataset is your own table of data that lives in Formt, so a workflow can remember things between runs instead of starting fresh each time. Use one to build up a list your workflows read and write over time (contacts, orders, a price book), to look up reference data mid-run, or to keep the same record from being processed twice. The Dataset step is how a workflow reads and writes those rows.

Find Row by Key

Look a single row up by the dataset's unique key. Returns the row's columns, plus a found flag so a miss is something you can branch on rather than a failure.

  • A form comes in: look the matching contact up by email and branch on whether you already know them
  • Look a price up by product code before building a quote
  • Check whether you have already stored a record, so you can skip repeats

In "Match Key", give a value for each of the dataset's unique-key columns (a fixed value, or one from an earlier step). The row with that key is returned. "Columns to Return" picks which columns come back, each a field you can reference downstream (for example {{find.email}}), alongside found; leave it empty to return the whole row. When no row has that key, found is false and the run carries on, so pair it with a Condition step to take a different path. The dataset needs a unique key for this action; without one, use Find Rows.

Tips
  • Branch on found before using the returned columns; they are empty when nothing matched
  • Find Row by Key then Add or Update Row is the classic keep-a-record-current pattern, split across a read and a write
  • Set the dataset's unique key to the column that identifies a row, like an email or an order number

Find Rows

Return every row that matches a condition, as a list you can loop over. Optionally cap how many come back and sort them.

  • Pull every open order for a customer and process each one in a loop
  • Get all the contacts in a region to email
  • List the rows added today and summarise them

Build a "Match Condition" from the dataset's columns; every matching row is returned. Leave the condition empty to return all rows. "Columns to Return" chooses what each row includes (all columns by default), "Max Rows" caps how many come back, and "Sort By" orders them. A single run returns at most 5,000 rows.

Tips
  • The result is a list, so connect the output to a For Each step to act on each row
  • Range filters like greater than, less than, before and after only appear for a column marked "Indexed" in the dataset, which also keeps those reads fast as it grows
  • Leave the condition empty to read the whole dataset

Add or Update Row

Add a row to a dataset. If the dataset has a unique key and a matching row already exists, you choose what happens: skip, update, or fail.

  • Log every run into a dataset as an audit trail
  • Keep a contacts list current: add new people, refresh the ones you already have
  • Collect results across a loop into one place you can read back later

Under "Columns to Set", fill in a value for each column you want to write (a fixed value, or one pulled from an earlier step). Columns you do not set here stay unchanged when a row is updated, and are empty when a new row is added. When the dataset has a unique key, the value you give in "Match Key" is what picks the row to add or update. If a row with that key already exists, the setting labelled "When the row already exists" decides what happens: "Skip" keeps the existing row untouched, "Update" refreshes it with the columns you supplied, and "Fail" stops the step. A dataset with no unique key simply adds a new row every time. The output tells you which happened: inserted, updated, or skipped.

Tips
  • Set "When the row already exists" to "Skip" when you just want to avoid duplicates, and "Update" when you want to keep the row current
  • Give the dataset a unique key (like email) if you want de-duplication; without one, it adds a new row every time
  • This is safe to run inside a loop over many items: same-key rows will not double up

Update Rows

Set one or more columns on every row that matches a condition. Reports how many rows changed.

  • Mark every order older than 30 days as archived
  • Set a status on all the contacts you just emailed
  • Clear a flag across a batch of rows once they have been handled

Build a "Match Condition" to choose which rows to change, then under "Columns to Set" select the columns to update and their new values. Every matching row gets those columns updated; the columns you do not list are left as they were, and no new rows are added. Its unique-key columns cannot be changed here: this sets the same value on every matching row, which would give them all an identical key, and no two rows can share a key. To change one row's key, use Add or Update Row, which works a single row at a time. The output reports how many rows were updated. Turn on "Require review" for the step and the run pauses first, showing how many rows it will change so you can approve before it runs.

Tips
  • Narrow the condition carefully: this changes every matching row, and an empty condition matches every row, not none
  • Range filters like greater than, less than, before and after only appear for a column marked "Indexed" in the dataset
  • Turn on "Require review" for this step to pause and approve how many rows it will change before it runs
  • To change the identity of a row (its key), use Add or Update Row instead

Delete Rows

Delete every row that matches a condition. Reports how many rows were removed.

  • Remove a contact from a list when they unsubscribe
  • Purge records older than a cut-off date
  • Clear out a batch of working rows once a workflow has finished with them

Build a "Match Condition" from the dataset's columns, the same way as Find Rows; every matching row is removed and the output reports how many. To delete one specific row, match on its unique key, which identifies a single row. Turn on "Require review" for the step and the run pauses first, showing how many rows it will delete so you can approve before it runs.

Tips
  • Match on the unique key to delete a single known row
  • An empty condition matches every row, not none, so it clears the whole dataset
  • Range filters like greater than, less than, before and after only appear for a column marked "Indexed" in the dataset
  • Turn on "Require review" for this step to pause and approve how many rows it will delete before it runs

Frequently Asked Questions

When should I use Find Row by Key versus Find Rows?
Use Find Row by Key when you know the value that identifies one row (an email, an order number) and want just that row back as fields. Use Find Rows when you have a filter that can match many rows and want them as a list to loop over. Find Row by Key needs the dataset to have a unique key; Find Rows works on any dataset.
What happens when Find Row by Key matches nothing?
It returns found: false with empty columns. That is a normal outcome, not an error, so the run continues. Put a Condition step after it to branch on the found field.
What is a unique key and why does it matter?
A unique key is the column, or set of columns, that identifies a row (an email, an order number, a product code). It is what lets Find Row by Key fetch one row directly, and what lets Add or Update Row spot a row you already have and either skip or update it instead of adding a duplicate. A dataset with no unique key adds a new row every time and cannot be looked up by key.
Do Update Rows and Delete Rows act on every matching row?
Yes. Both act on every row the condition matches. Turn on "Require review" for the step and the run pauses first, showing how many rows it will change or remove so you can approve a concrete number before it runs. To act on a single row, match on its unique key.
When a matching row is updated, does it overwrite the whole row?
No. It changes only the columns you fill in and leaves the rest of the row as it was. To keep the record current, supply just the columns that changed.