How to translate only the missing rows in CSV or Excel, with AI

How to translate only the missing rows in CSV or Excel, with AI

September 7, 2026

You are looking at a file where some of the work is already done. Four hundred rows have a German title. Three thousand six hundred do not. Somebody, at some point, translated the first batch, and then the catalogue grew.

The obvious tools all want the whole file. So the question is not how to translate it. The question is how to translate the part that is missing, and pay for that part only.

What a partly translated file actually looks like

Here is the shape of the problem, small enough to see at once.

A file where two of four rows already have a German title. Only the two empty cells are in scope, and the rest of the file comes back byte for byte.

Scale that to four thousand rows and the two outcomes stop being similar. Either you pay for 4,000 rows and review a diff covering all of them, or you pay for 3,600 and review 3,600. The second one also leaves the wording your colleague already checked exactly as she left it.

The five files this happens to

This is not an edge case. It is the normal state of any file that has been touched more than once.

Rows added since last time. The catalogue grew by 200 products. The other 3,800 are done and reviewed. This is the most common one by a wide margin, and it repeats every month.

A language added to a file that already has three. Your spreadsheet has French, German and Spanish columns. Italian was agreed last week and its column is empty, or not there at all. You want Italian written and the other three left alone.

A handover somebody else started. A freelancer got through the first third before the project stalled. You do not know exactly where they stopped, and you do not want to find out by paying for the overlap.

A file where a previous tool wrote the source into the target as a placeholder. This one catches everybody, because the file looks finished. In an XLIFF or a PO export, every entry has a target slot, and plenty of tools fill it with a copy of the source text so the structure is valid. Open it and every target is populated. Almost none of them are translated.

Rows that were deliberately left alone. Internal SKU descriptions, a legal paragraph your counsel signed off in one language only, three products being discontinued. These are not gaps. They are decisions, and a tool that helpfully fills them has damaged the file.

Those last two are the reason “translate the empty ones” is not a checkbox. What counts as missing is something only you know, so the mechanism has to take a sentence from you rather than a setting.

Why nothing else does this

Retranslating the whole file means paying twice for the part that was already finished. Translating only the gaps prices and reviews the missing rows alone.

A machine translator has no concept of scope. DeepL and Google Translate take text and give back text. There is no place to express “not this row”, because a row is not something they see. You can filter the file yourself before sending it and stitch the result back afterwards, which is a spreadsheet exercise you now own and have to repeat every month. Separately, and this is customer experience rather than any test we have run: teams have come to us because on their real content, with their real terminology, machine translation stopped clearing the bar they publish at.

A general assistant can hold the rule for a while. Paste 50 rows into ChatGPT or Claude with “only fill the empty German cells” and it will do it. The problem arrives at scale, and it arrives quietly: somewhere past the first few chunks a row that already had a translation gets a new one, and you find it during review, or you do not. There is a longer version of that comparison if you want it, but the short version is that a rule you have to trust cannot be checked, and one applied by code can be.

An agency will do exactly what you ask. The cost is not the per-word rate, it is the preparation: extracting the missing rows, explaining which columns to leave alone, waiting, then merging the result back into your own file. That work is not language work, and the hidden cost is that you repeat all of it on the next update.

The instruction becomes code, which is why it holds at row 18,000

This is the part worth understanding, because it explains why a scope rule behaves differently here.

Your sentence is not passed along as a hint to a translation model. AI Glot reads the structure of your file, then turns your instruction into a small program that runs over the file and produces the list of exactly which pieces of text are in scope. That list is then translated. The rule is evaluated once per record by code, so record 18,000 gets the same test as record 1. There is no drift, because there is nothing to drift.

That program runs under a set of checks before any credits move:

  • It may not change your file. The document is compared before and after the program runs, and any modification is rejected outright. Your upload is never touched, and every scope decision applies to the output file only.
  • It may not invent text. Every piece of text it selects has to exist in your file word for word. It cannot paraphrase a cell on the way past.
  • Every destination has to be a real writable slot, so a rule pointing at a column that does not exist fails at planning time rather than producing a strange file.
  • If your rule matches nothing at all, planning fails and tells you. That sounds unfriendly and is genuinely useful: it is how you learn, for free, that the file you thought was half done is finished.

“Still missing” means four different things

Here is the nuance that decides whether your sentence works. A gap is not the same object in every format, so the test your instruction has to describe changes with the file in front of you.

One plain sentence about what is missing, and the four different tests it becomes depending on the format of your file.

In a spreadsheet, a gap is an empty cell. Whether the file arrived as a CSV export or an Excel workbook, the test is the same: this row has an English title and nothing in the German column, so this row is in scope. Say “only the rows where the German column is still empty”.

In a bilingual file, a gap is a target that still equals its source. XLIFF and PO pair each entry with one translation slot, and that slot is usually pre-filled with a copy of the source. So emptiness is the wrong test, and the right one is a comparison: “only translate the units where the target still holds the same text as the source”. This single sentence is why a 228-unit WordPress export where 217 targets are still the original French is a normal job rather than an argument about whether the file is done.

In a key tree, a gap is a key that is not there. In JSON or YAML the German translation of a string either exists as a sibling key or it does not, and a missing key can be created as long as its parent object exists. An empty value counts too, so “only where the de key is missing or empty” covers both.

In a single-language file, there is nothing inside the file to compare against, and this is the honest limit. An Android strings.xml, an iOS .strings, a Java .properties, a .NET RESX and an SRT subtitle file all hold exactly one value per key. There is no source column sitting next to it. So “already translated” cannot be tested mechanically, because the file does not record it. What does work is anything the file actually shows: an empty value, or a marker you left yourself such as a TODO prefix. If your only signal is that a value “looks like English”, no rule can express that reliably, and you are better off splitting the file before you upload it.

Where the scope sentence goes, and where it silently does nothing

Get this wrong and you pay to translate the whole file. There are two places to write an instruction and they are not interchangeable.

The plan instruction decides which text is translated. The batch instructions decide how each string is written. Scope in the wrong one does nothing at all.

The plan instruction is the one you type before you see a plan. It is read against the shape of your file, and it is what the plan is built from. Scope lives here.

The batch instructions are carried into the translation and applied as each individual string is written. At that moment the only thing in view is one string, so a rule can only describe something visible inside that string: keep a placeholder as it is, leave an in-content URL alone, never translate a product name, use informal register.

Now the failure. Put “only translate the empty cells” in the batch instructions and nothing happens, and nothing warns you. There are no cells at that point. There is one string, already selected, already being translated, because the scope decision was taken earlier by an instruction that never mentioned scope. The file comes back fully translated and the invoice reflects it.

Written in the batch instructions Why it does nothing Where it belongs
“Only translate the empty cells.” No cells are in view, one string is. The plan instruction
“Skip the first column.” A column is file structure. The plan instruction
“Only the rows added since March.” Same. The plan instruction
“Leave the SKU column alone.” Same. Describe the content instead: “leave alphanumeric product codes untranslated”. Either, reworded

The simplest way to remember it: the plan decides what gets translated, the batch instructions decide how it reads.

Writing the sentence

Plain English, one or two lines, naming the source and the target explicitly. These all work as written:

Only the rows where the German column is still empty. Source is English.
Only translate the units where the target is identical to the source,
it is a placeholder. Leave every unit that already differs.
Fill the empty Italian column from the English one. Do not touch the
French, German or Spanish columns.
Translate the description and the SEO title into Dutch where the Dutch
version is missing. Leave the handle and the SKU alone.
Instructions for this batchOptional
On top of your glossaryApply
You describe the job in plain English. AI Glot turns it into a plan you can read and correct before anything runs.

Two habits that pay for themselves. Name the source language rather than letting it be inferred, because inference is least reliable exactly where it costs most: short strings, and files that already contain some translated values, which is every file in this article. And name the columns or keys you want left alone, even when your scope rule already excludes them. It costs a clause and it removes a whole category of misunderstanding.

If the same terms have to come out the same way they did in the last batch, put them in a workspace glossary once. The rows you are filling now will then match the rows somebody filled in March, which is the other half of finishing a partly translated file properly.

Confirm the scope before you pay for it

You never have to trust that the sentence landed, because you read the plan first.

The plan comes back with measured counts, the real number of items and words found in your file, not an estimate from its size. It offers three ways to check it: a preview of what your file will look like afterwards, a table of the exact pieces of text that will be sent, and a plain-language summary of what was understood. The item table is where a wrong scope becomes obvious, because a row you expected to be excluded is either in that list or it is not.

If it is wrong, say so in a sentence and it plans again. Creating the batch and planning are free, and repeatable as many times as you like. Approval is the only step that spends credits, and the number you approve is the measured word count of what is in scope. So the expensive mistake in this whole article, paying to retranslate work that was already done, is one you can only make by approving a plan that says so.

That order matters more than it sounds. A tool where scope is a guess has to be trusted. A tool where scope is a plan you read is one where being wrong costs nothing.

Two more things worth knowing

You can ask for only the touched records back. If what you actually need is a small file to hand to a reviewer rather than the whole catalogue, say so and the output keeps only the records that received a translation. This works for CSV, Excel, JSON, YAML, PO, XLIFF, SRT and ZIP archives of those. It is deliberately refused for app resource files, because an app looks up every key it expects to find and a partial strings.xml is a crash rather than a smaller file.

A rule that has to count across the whole file will not work. For a large file, the program that selects your scope runs over consecutive windows of rows rather than seeing everything at once. Rules based on position work, because it can do the arithmetic: every second row, the first 500 rows. A rule that needs a running total, like “the first 200 rows that are still empty”, does not, because no single pass knows how many earlier windows already matched. Ask for all the empty rows, or for a fixed row range, and both are fine.

The honest scope of all this

Use it for the part that is genuinely repetitive: the 200 rows that appeared this month, the fourth language somebody agreed to last week, the two thousand units a previous tool left holding their own source text. That work is miserable by hand, and it is the same work every month.

Then spend review time on the output, not on filtering the file. Plenty of teams run this as a first pass and have a reviewer go through it, which is a good use of an expert and a poor use of an afternoon spent making a copy of a spreadsheet with some rows deleted.

If you have not run one of these end to end yet, start with the whole flow rather than with the scope: there is a walkthrough for translating a CSV file and one for translating an Excel workbook, and the scope sentence above drops into either of them unchanged.

For your homepage, hire a translator. For the 3,600 rows that are still empty, do not pay for the 400 that are not.

10,000 words free when you sign up

Ready to translate your large files?