Skip to content

No account required

Start a project

Find the stock that is not moving.

Stock aged by when it genuinely last sold, the cash locked inside what will not move, and the products that ran out while that cash was unavailable.

No account needed to start. You only pay when you like what you see.

  • .xlsx. Excel workbook. Every sheet read, including the ones that are notes rather than data.
  • .xls. Excel 97–2003. Read the same as a modern workbook.
  • .xlsm. Excel, macro-enabled. Values and formulas are read. Macros are never executed.
  • .ods. OpenDocument spreadsheet. LibreOffice and OpenOffice workbooks, read like Excel.
  • .numbers. Apple Numbers. Tables are pulled out of the Numbers package sheet by sheet.
  • .csv. CSV. Delimiter, quoting and encoding detected rather than assumed.
  • .tsv. Tab-separated. Read as delimited text.
  • .pdf. PDF. Checked for a text layer first. A PDF written by software keeps its table structure; a scan is read as an image and told apart from the first kind.
  • .docx. Word document. Tables are lifted out of the document; the prose around them is kept as context.
  • .pptx. PowerPoint deck. Tables and the data behind native charts are read slide by slide.
  • .rtf. Rich text. Tables extracted, formatting discarded.
  • .json. JSON. Nested objects are flattened into tables, keeping the path as the column name.
  • .ndjson. Newline-delimited JSON. Streamed a record at a time, so an export of any size is fine.
  • .xml. XML. Repeated elements become rows; attributes become columns.
  • .parquet. Parquet. Read columnwise, with the file's own types kept.
  • .sqlite. SQLite database. Every table read, with the foreign keys used to work out how they relate.
  • .db. SQLite database. Read as SQLite when the file is one, and reported plainly when it is not.
  • .png. PNG image. Screenshots of a dashboard or a table are read, and every figure is checked against the totals in the same image.
  • .jpg. JPEG photo. A photograph of a printed report or a handwritten sheet is read into a table.
  • .jpeg. JPEG photo. The same as .jpg.
  • .heic. iPhone photo. Accepted as it comes off the phone. Safari usually hands it over as a JPEG.
  • .webp. WebP image. Read like any other screenshot.
  • .tiff. TIFF scan. Multi-page scans are read page by page.
  • .txt. Plain text. Read as notes, or as data when the contents turn out to be a table.
  • .md. Markdown. Markdown tables become tables; the rest becomes context for the analysis.
  • .zip. Zip archive. Unpacked, and each file inside is treated as though you had uploaded it yourself.

What comes back

order_lines.csv
86,412 rowsChecked

Your best-selling product loses $2.15 a unit, and it paid for the stock you cannot sell.

The linen shirt is the top seller by volume and reports a 59% gross margin. After discounts, marketplace and payment fees, free shipping and a 26% return rate, it contributes −$2.15 per unit ordered — $8,988 over the year. Meanwhile $128,000 of stock, 31% of the total value, has not sold in nine months, and eight of the products that do sell were out of stock for 4.7% of the year.

$412,000Stock value+11.2%
31.0%Not sold in 9 months+4.3pp
214SKUs below zero
Open the full sample project

Where the linen shirt's margin goes

A 59% gross margin ends at −$8,988

  1. 01The best seller contributes −$2.15 per unit ordered.
  2. 02$128,000 of stock has not sold in nine months, and half of it was bought to hit a discount.
  3. 03Eight products that do sell were unavailable for 4.7% of the year.

01

It ages stock on sales, not on the stock sheet

Stock files carry a `last_sold` column that is almost always stale, and always stale in the flattering direction. Ageing is rebuilt from the order lines: in the worked example the sheet's own column disagrees for 312 SKUs and would have classified $47,000 of dead stock as active.

02

It reconstructs the stockouts

A stockout leaves no rows. Nothing is recorded on the days you had nothing to sell. Zero-stock windows are found in the movement history and valued at the SKU's own rate of sale either side, then re-run at a deliberately conservative rate so you can see the range rather than one confident number.

03

It traces dead stock back to the decision

Knowing which stock is dead is a stocktake. Knowing why is analysis: half the dead value in the example arrived on four purchase orders where the quantity was set by a supplier's minimum rather than by demand. One of them was 480 units of a product that has sold 96 in fourteen months.

It expects a mess.

Most files that arrive here have several tables on one sheet, a title block above the data, totals stranded in the middle of it, and dates in more than one format. That is the normal case, not the awkward one.

  • Stock aged by its real last sale
  • Dead stock ranked by the cash clearing it releases
  • Stockouts, with an estimate and its range
  • ABC classification, and where the attention is going instead
  • Cleaned .xlsx and methodology
sales_export_FINAL_v3(2).xlsx
A messy sales export, and the repairs Data Analysis App applies to it.
OrderDateCustomerAmt
1024107/02/26John Smith$84.00
102422 July 2026SARAH LOPEZ$41.00
102422 July 2026SARAH LOPEZ$41.00
1024345840s. lopez41
Not suppliedNot suppliedSUBTOTAL$166.00
102442026-07-03Amara Osei$127.50
  • Date format
  • Duplicate row
  • Serial date · text number
  • Total inside the data
A stock movement ledger, shelf cards and purchase orders tracing excess inventory to supplier minimums.

Questions it works through

  • How much cash is sitting in stock that will not sell?
  • Which of my best products ran out, and for how long?
  • What did I buy because of a supplier minimum rather than demand?
  • What do I have to discount, and by how much, to clear it in 60 days?

Questions people ask

Do I need a proper inventory system export?

No. A stock file with quantities and costs, plus sales history, is enough to age stock and rank it. Movement history makes stockouts measurable and purchase orders make the cause traceable — each extra file adds a section rather than being a prerequisite.

How does it know something was out of stock?

From the movement history, not from the absence of sales — those look identical and mean different things. Zero-stock windows shorter than two days are ignored as stock-count lag. With no movement history it reports what it cannot measure instead of inferring it.

Is the lost-sales figure real money?

It is an estimate of something that did not happen, and it is labelled that way everywhere it appears. It overstates in one direction — customers who bought another size are counted as lost — and understates in the other, since customers who left for good are not counted at all. Both are stated, and a conservative version is shown beside it.

What about seasonal stock?

A SKU that sold in the same month last year is excluded from the dead set rather than condemned for a quiet summer. That exclusion is listed, with the SKUs it applied to, so you can disagree with it.

Upload stock and sales

No account needed to start. You only pay when you like what you see.