Results, export and sharing

Why does the Total row of my saved search CSV export fail to parse as a number?

Updated
saved-searchcsvexportsummarytotal-rowparsingsilent-failure

Why does the Total row in my saved search CSV export not parse as a number?

The Total row formats that column differently from the rows above it, adding a thousands separator and a trailing .0, which forces CSV quoting. A parser gets integers for the body and a string for the total, so a cast returns NaN or a value silently truncated at the separator, on the total row only, with no warning.

Because NetSuite formats the Total row differently from the rows above it. The body of the column exports as plain integers, and the total of that same column arrives with a thousands separator and a trailing .0, which forces the field to be quoted. Your parser reads a run of numbers and then a string.

Minimal reproduction

Build a summary saved search, group it, give one column a numeric summary, and export it with Export - CSV. Here is the tail of such a file. The values below are invented round numbers for illustration; the formatting around them is verbatim from the export tested.

Bill,900,2100
Check,400,800
Invoice,1500,12000
Total,4000,"120,000.0"

Read down the third column. Every group row is a bare integer. The total is "120,000.0": quoted, comma-separated, with a decimal part that the body values do not have.

Now read across the last row instead. The second column's total in that same row gets none of that treatment. It is a bare integer, in the same row, in the same file, written by the same export. That is what rules out a locale or number-format setting as the explanation: a setting would have applied to both columns.

What it does to a consumer

A parser reading the numeric column receives integers for every group row and then a string for the total row. From there it depends on how forgiving your language is, and every outcome is bad:

  • A strict cast raises, or yields NaN, on the last row only.
  • A permissive parse stops at the first separator and returns the leading digits as the value. In the illustrative line above that is 120 instead of 120,000.
  • A spreadsheet import shows the total left-aligned as text while the column above it is right-aligned, which is the only visible tell and only if someone is looking.

Nothing warns, in the file or in the UI. The rows that break are exactly the rows a report consumer trusts most, because a total is what gets quoted upstream.

The trailing .0 is worth noticing separately. The column being summarised was integer-valued throughout, so the total carries a decimal place that has no source in the data. Number formatting in saved searches has form here: Formula(Numeric) does not round either.

The fix

Strip formatting before casting, rather than trusting the column type:

def as_number(cell):
    return float(cell.replace(",", "").strip('"'))

Or drop the exported total row on import and re-total the column yourself. That is the better option when the file feeds anything downstream, because it also removes the row from any sum() you run over the column and gives you a total whose provenance you control.

Either way, do not write code that treats the last row of a NetSuite summary export as structurally identical to the rows above it. It is not.

How to tell if you are affected

Open the CSV in a text editor rather than a spreadsheet, and look at the last line. If any field on it is quoted while the same column above is not, that column will not parse cleanly. The quote marks are the signal, and they are invisible in Excel, which is why this survives review.

The other check is on the receiving side. If a report has ever shown a total that is a thousandth of what it should be, or a total cell that is empty while the detail rows are populated, this is a candidate cause.

Scope: one sandbox account on NetSuite 2026.1, Administrator role, two exports taken through the Export - CSV button on the results page, one detail export and one summary export. The Total row only exists in the summary export, so that is where this was observed. The detail export contains no total row and nothing in it was misformatted. Whether the same reformatting applies to Currency or Percent columns, or to totals in the PDF and Excel exports, was not tested.

How this was established

1 probe run against one NetSuite 2026.1 sandbox account on the Administrator role, through the saved search UI and the SuiteScript search engine. Where this page draws a boundary around a finding, that boundary is the edge of what was actually run.

Related

  • Why does my saved search CSV export have two columns with the same header?

    NetSuite writes the column label straight into the CSV header with no disambiguating suffix, so selecting the same field twice gives you the same header twice. The fix is custom column labels: they are honoured exactly as typed, in both detail and summary exports.

  • Why does my saved search only show 500 rows in the browser?

    The results page renders a fixed 500-row window and never says so. The size URL parameter is ignored, there is no truncation warning and no pagination control, and the correct Total sits at the bottom of a page showing a fraction of it. The CSV export from the same page is complete and matched that Total exactly.

  • Why does my Formula (Numeric) column return 39 decimal places?

    Because Formula (Numeric) does not round at all. It hands back the raw Oracle NUMBER, which is what reaches your CSV export or SuiteScript variable, so 1/3 comes back with 39 decimal places. Formula (Currency) is not the fix: it rounded to 3 dp on some values and 2 on another. Use ROUND(x,2) in the expression.

From the blog