Nonprofit Cloud · migration from spreadsheets
Moving donations from spreadsheets into Nonprofit Cloud?
It is finished when three totals match your own book.
A migration from spreadsheets into Nonprofit Cloud is finished when three totals in Salesforce match three figures in your own workbook to the penny: money received, money still expected and money promised. Until then, nobody should trust a dashboard built on it. This is the order of work and the traps, from building fundraising for a UK charity whose income lived in colour coded spreadsheets.
Reviewed 1 November 2026.
The finish line
When is a spreadsheet migration to Nonprofit Cloud finished?
When the paid payments add up to what your workbook says was received, the commitments add up to what it says was promised, and the unpaid payments add up to what is still expected. Agree those three cells with your finance lead before any data moves, then refuse to show a dashboard until all three match.
Salesforce renamed Nonprofit Cloud to Agentforce Nonprofit on 2 December 2025; the objects are the same. Its own migration guide, version 2 of 1 June 2026, is written for charities leaving the Nonprofit Success Pack. Two of its rules apply to spreadsheets just as well: keep a full copy of the source exactly as extracted, and give every loaded record a field holding its legacy identifier. For a spreadsheet, that identifier is the sheet and the row.
The data model
What does one spreadsheet row become in Nonprofit Cloud?
Rarely one record. A grant or pledge row becomes a funder account, an application, a Gift Commitment for the promise, a split across programmes and a Gift Transaction for each payment. Money received becomes a paid transaction, and the rest of this year and later years become unpaid ones, so expected income is visible too.
Individual donors become Person Accounts: the migration guide names them as the way Nonprofit Cloud represents people. An unrestricted income stream with no application behind it, such as fares or room hire, becomes a commitment with no opportunity at all.
| The funder or donor in the name column | Account |
| The bid or application, with its stage | Opportunity |
| The amount awarded or pledged | Gift Commitment |
| The programme or project area | Gift Default Designation |
| Money already received | Gift Transaction, Paid |
| The rest of this year, and later years | Gift Transaction, Unpaid |
Before the load
Six things to fix in the workbook first.
Each of these was in the charity’s own spreadsheets, and none of them raised an error.
- 01
Read the colours before anything is exported
In the charity’s workbook the status of an application was the fill colour of a cell. A CSV export drops fills without a word. Worse, the same blue meant a contract on one sheet and a draft on another, so each sheet needs its own colour table, read from the file, not from memory.
- 02
Test the reader before you trust the data
The first extract shifted values into the wrong columns: an empty cell was skipped, and the next value landed in its place, so funder names turned into small numbers. Nothing failed. Open the raw cells of one row and compare them with the screen before reading thousands of rows.
- 03
Convert what Excel hides
Dates arrive as serial numbers such as 46113, counted from 30 December 1899. A confidence of 0.75 becomes 7500% in a percent field unless it is multiplied first. Amounts typed as prose, two years in one cell or a slash for a decimal point, need a person, not a formula.
- 04
Distrust column headings
On the older sheet a column titled Programme held the initials of the staff member responsible. Loaded as written, every gift would have reported under a programme that does not exist. It maps to the record owner instead.
- 05
Choose one source for every number
The same application sat on three sheets with three different amounts, and the oldest sheet called it agreed when the two newer ones said it was still waiting. Decide which sheet is the truth for each figure, in writing, and load the rest as history or not at all.
- 06
Give every record the address it came from
Each loaded record carries an External ID naming the sheet and row it came from, so a second run updates instead of duplicating. The catch: rows move when the workbook is edited. Before reloading from a new version, remove the previous load in reverse order, or the keys point at the wrong rows.
The load
How do you load the history without emailing a single donor?
Bring every historical payment in already marked as thanked, switch off the alert addresses while test data sits in the org, and count the emails the org logged after every pass. On the charity’s build that count stayed at zero through every load, because it was checked each time rather than assumed.
- 01
Load in six passes, parents first
Funders, then applications, then commitments, then the programme split, then schedules, then payments. Each pass is an upsert by External ID. Salesforce’s Data Loader matches a parent by its External ID in the same file, so a payment can name its commitment without anyone looking up a record Id.
- 02
Mark old payments as already thanked
Every historical paid payment arrives with its acknowledgement status set to Sent and a stewardship date. Without those two columns the thank you automation treats a donation from last spring as new and writes to the donor on the day of the load.
- 03
Check the automation that only runs on create
The flow that splits each payment across programmes was set to run when a payment is created. When the link to the commitment arrived in a later pass, it never ran, and historical income showed under no programme with no error anywhere. Its entry condition now also fires when that link changes.
- 04
Rehearse with a rollback
A trial loads two complete chains, checks them and rolls everything back. The first trial caught an alert that crashed when its address field was blank, because a flow reads a blank as null and null is not an empty text. Fixed before a single real record was written.
- 05
Start small and read the cost
The Data Loader Guide sets the import batch at no more than 200 records through the SOAP API and 10,000 through the Bulk API. Flows run inside each batch, so begin with 50 rows, read the limits used, then raise it.
The proof
Five checks before anyone sees a dashboard.
The first three come straight from your workbook. Run this in the Developer Console query editor, with your own legacy identifier field, and compare the paid and unpaid lines with the sheet.
- 01
Money received
The sum of paid payments equals the workbook’s own funds realised figure. This is the one a treasurer will check first, and on the charity’s build it matched to the penny.
- 02
Money promised
The sum of every commitment equals the workbook’s totals cell. If it is out, look first at the rows where a cell held two years of money as prose: that is where a promise goes missing.
- 03
Money still expected
Unpaid payments add up to what the sheet still expects this year and later. Where a funder paid more than the year expected, no unpaid remainder should exist at all.
- 04
Nothing left unlinked
No payment without a commitment and a donor, no commitment without a donor, and every payment split across programmes. The query for the last one is in the article on payments with no programme split.
- 05
No email went anywhere
Count the emails the org logged after each pass, and look at the flow error messages too: a failed flow writes to the administrator even when every alert address is blank.
My first trial reported every check green while a paid payment was missing. The checks counted what must not happen, such as emails, and never counted what must exist. Now the first check counts the records each pass should have created, and a missing payment fails it. The rest of the build is in the charity case study.
Asked often enough to answer here
Questions
- Q
Can we import the spreadsheets ourselves with the Data Import Wizard?
For a plain list of people, often yes. Salesforce’s Data Loader Guide, last updated 28 August 2026, recommends the wizard below 50,000 records on the objects it supports. Money is the harder part, because one row becomes several linked records loaded in order, which is what an upsert by External ID in Data Loader is built for.
- Q
Do we have to move every year of history?
No. Move the money you report on, thank for or still expect, and keep the rest as an archive. On the charity’s build the oldest pipeline sheet contradicted the newer ones, so it stayed a read only record instead of a source of amounts.
- Q
Why does the donor summary panel say No Data after the load?
Because Nonprofit Cloud fills donor gift summaries with Data Processing Engine, not as payments are saved. Trailhead says to activate the template definitions without modifying them and to schedule a flow that recalculates them. Until that runs, the panel stays empty however correct the payments are.
A simple import from your spreadsheets is part of Fundraising essentials: €4,550 for 70 hours on the ten licences Salesforce donates. The full money history, reconciled to the penny as described here, is part of Fundraising complete, €8,450 for 130 hours.
Serhii Skrypnyk · Senior Salesforce Administrator · 7 Salesforce certifications · on the platform since 2018. Reviewed 1 November 2026.
Read next
The question that usually comes after this one.
- 01
NPSP vs Nonprofit Cloud: Must You Move?
Salesforce still supports NPSP, and its own guide treats the move to Nonprofit Cloud as a reimplementation in a new org. When staying is fine and when moving pays.
- 02
Nonprofit Cloud Gift Commitment Schedules
How a Gift Commitment, its schedule and its Gift Transactions produce expected payments in Nonprofit Cloud, and what a UK charity build had to add.
- 03
Case: Community charity, United Kingdom
Three colour coded spreadsheets became one fundraising system, with every payment split across programmes and committee scoring inside Salesforce.