# Update many records at once

Select rows in the Data grid, choose a bulk action, and every change is applied one record at a time by the service that owns that record — the same code path an edit on the record's own screen would take. That is why some rows in a selection succeed and others are refused, and why the refusals are worth reading rather than retrying.

- **Status:** Available
- **Audience:** both
- **In the app:** #/data
- **Last verified:** 2026-09-10
- **Canonical:** https://connectbyjbrh.com/docs/how-to/bulk-update-records/

## The grid is a view, not a table

Data is an Excel-like grid over thirteen sheets: companies, people, leads, prospects, follow-ups, deals, conversations, calls, cases, onboarding, knowledge, files and memory. It looks like a spreadsheet and behaves like one, but nothing writes directly to a row. Each edit is handed to the service that owns the record, so a stage rule, a compliance check or a permission applies exactly as it would elsewhere.

This is the difference that matters when a bulk action half-works. A spreadsheet would have written all of it or none of it. The grid applies each record through its own rules, so a batch of forty can land thirty-six changes and refuse four, each for its own reason.

## Making the selection you actually meant

1. Open Data and pick the sheet. Filter and group before you select anything.
   - Result: Filtering is done in the database rather than over a fetched page, so the count you see is the real count and not the first few hundred rows.
2. Sort by the column you are about to change, then select the contiguous block.
   - Result: Sorting first turns 'the ones with no owner' into a visible run, which is far easier to check than a scattered multi-select.
3. Save the filter as a view before acting.
   - Result: A saved view is how you find the same set again afterwards to confirm the change, and how a colleague reproduces what you did.
4. Apply the bulk action and read the result summary rather than closing it.
   - Result: The summary is where refusals appear. Each names the record and the rule that stopped it.

> **Careful** Selection follows the filter, not the screen. If you filter, select everything, then change the filter, you have not deselected anything — check the count on the action before confirming it.

## What gets refused, and why that is correct

| Refusal | Cause | What to do |
|---|---|---|
| Stage move refused | The pipeline's stage rules do not allow that transition | Move through the intermediate stage, or change the rule |
| Recipient suppressed | An unsubscribe, complaint or do-not-contact entry | Leave it. A suppression cleared in bulk is the one that causes a complaint |
| Edit refused on a derived column | The value is computed from other records, not stored | Change the source record instead |
| Permission denied | The action is outside what your membership may do | An administrator applies it, and the audit records who |
| Row not visible | The record belongs to another workspace, or carries no workspace stamp | Not recoverable from the grid; see the troubleshooting page for invisible rows |

None of these are grid faults. Each is the owning service saying no in the one place it always says no, which is what keeps the grid from becoming a back door around the rules the rest of the product enforces.

## Confirming the change landed

1. Reopen the saved view.
   - Result: If the filter was on the field you changed, the rows should now have left the view. Rows still present are the refusals.
2. Open the Decision Log and filter to the period of the edit.
   - Result: Bulk changes are recorded per record, with who made them, so the trail answers 'who changed these forty' months later.
3. Export the view to CSV if somebody outside Connect needs the evidence.
   - Result: The export neutralises formula-leading characters, so a cell beginning with an equals sign arrives as text rather than as something a spreadsheet will execute.

> **Note** Import is the mirror image of this and has the same property: rows are created through the owning service, so an import can partly succeed. Read the dropped-rows report rather than assuming a silent success.

## Questions

### Can I undo a bulk change?

Not as one action. Each change was applied individually, so reversing it means selecting the same set and applying the opposite change — which is why saving the view before you act is worth the extra few seconds.

### Why did the grid let me type a value it then rejected?

The cell accepts input; the service validates it. Keeping validation in the service rather than duplicating it in the grid is deliberate — two copies of a rule drift, and the copy in the interface is always the one that gets stale.

### Does a bulk edit trigger the engine?

Changing a field the engine reads changes what it does next. Thread priority is the clearest case: it is read when work is picked, so correcting priority in bulk changes behaviour rather than just re-sorting a list.

## Related

- [The Data grid](https://connectbyjbrh.com/docs/files-data/data-grid/)
- [Bulk selection and actions](https://connectbyjbrh.com/docs/files-data/bulk-actions/)
- [Saved views](https://connectbyjbrh.com/docs/files-data/saved-views/)
- [Import contacts](https://connectbyjbrh.com/docs/how-to/import-contacts/)
- [Export your data](https://connectbyjbrh.com/docs/how-to/export-your-data/)
- [The grid would not save an edit](https://connectbyjbrh.com/docs/troubleshooting/grid-edit-refused/)

## What this page is based on

- Connect source pack: overview (docs-source/sources/GENERAL.md §9 — files and the Data grid)
- Connect source pack: channels (docs-source/sources/CHANNELS.md §5 — query cost and paging)
- Connect capability registry (docs-source/facts.py — data_workspace)
