Codice fiscale in Excel
Aggiornato il 30 luglio 2026 · 9 minuti di lettura
Verificare un elenco di codici fiscali in Excel si fa con una formula sola; calcolarli da zero richiede invece una decina di colonne di appoggio. Sotto trovi entrambe le cose, la tabella completa dei valori del carattere di controllo e l’elenco delle parti che in Excel non conviene affrontare.
Verificare un elenco di codici fiscali
È il caso d’uso più frequente: una colonna di codici arrivata da un gestionale o da un modulo, e la domanda “quali sono sbagliati?”. Con il codice in A2, questa formula risponde in una cella sola, senza colonne di appoggio.
=LET(
cf; UPPER(TRIM(A2));
k; SEQUENCE(15);
ch; MID(cf;k;1);
p; IFERROR(FIND(ch;"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");0);
ps; IF(p=0;1;p);
pari; IF(ps<=10; ps-1; ps-11);
dispari; VALUE(MID("0100050709131517192102041820110306081214161022252423"; pari*2+1; 2));
atteso; MID("ABCDEFGHIJKLMNOPQRSTUVWXYZ"; MOD(SUM(IF(ISODD(k); dispari; pari));26)+1; 1);
IF(LEN(cf)<>16; "lunghezza " & LEN(cf) & " invece di 16";
IF(MIN(p)=0; "contiene un carattere non ammesso";
IF(EXACT(MID(cf;16;1); atteso); "valido";
"controllo errato: atteso " & atteso)))
)Restituisce valido oppure il motivo preciso dello scarto. Trascinala verso il basso e hai la colonna degli errori.
| A2 | Risultato |
|---|---|
| MRTMTT25D09F205Z | valido |
| MLLSNT82P65Z404U | valido |
| RSSMRA85M01H5LMT | valido |
| RSSMRA85M01H501Z | controllo errato: atteso Q |
| RSSMRA85M01H501 | lunghezza 15 invece di 16 |
Tre dettagli che vale la pena di notare. UPPER e TRIM assorbono le minuscole e gli spazi a inizio e fine cella, che in un’esportazione ci sono quasi sempre; uno spazio in mezzo al codice, invece, resta e fa scattare l’errore di lunghezza. EXACT confronta rispettando le maiuscole, a differenza dell’operatore =, che in Excel non le distingue. E la terza riga della tabella mostra che un codice omocodico passa senza problemi: la formula non pretende cifre nelle posizioni numeriche.
Quello che questa formula non fa è controllare la forma, cioè che ogni posizione contenga il tipo di carattere previsto. In pratica pesa poco: il carattere di controllo coincide per caso in un caso su ventisei, quindi respinge da solo circa il 96% di qualunque stringa sbagliata.
Nomi delle funzioni e separatori
Prima di incollare qualsiasi cosa, due avvertenze che fanno perdere più tempo di tutto il resto messo insieme.
Il separatore di argomenti. Le formule qui usano il punto e virgola, che è quello delle impostazioni internazionali italiane. Se il tuo Excel usa la virgola, sostituisci con una , tutti i ; che non si trovano dentro una stringa fra virgolette: quelli vanno lasciati come sono.
I nomi delle funzioni. Excel li traduce nella lingua dell’interfaccia: in un Excel italiano UPPER non esiste e va scritto MAIUSC. Le formule di questa pagina sono in inglese, che è la forma usata da Google Fogli, da LibreOffice Calc e dal formato di file .xlsx. Questa è la corrispondenza per tutte le funzioni usate:
| Inglese | Excel in italiano |
|---|---|
| LET | LET |
| SEQUENCE | SEQUENZA |
| MID | STRINGA.ESTRAI |
| LEN | LUNGHEZZA |
| LEFT | SINISTRA |
| RIGHT | DESTRA |
| UPPER | MAIUSC |
| TRIM | ANNULLA.SPAZI |
| SUBSTITUTE | SOSTITUISCI |
| TEXTJOIN | TESTO.UNISCI |
| IF | SE |
| IFERROR | SE.ERRORE |
| ISNUMBER | VAL.NUMERO |
| ISODD | VAL.DISPARI |
| FIND | TROVA |
| CODE | CODICE |
| SUM | SOMMA |
| MIN | MIN |
| MOD | RESTO |
| VALUE | VALORE |
| EXACT | IDENTICO |
| YEAR | ANNO |
| MONTH | MESE |
| DAY | GIORNO |
| XLOOKUP | CERCA.X |
| TRUE | VERO |
Attenzione a due trappole della traduzione: ISODD diventa VAL.DISPARI e non DISPARI, che in italiano è invece la traduzione di ODD e fa una cosa completamente diversa; e MOD diventa RESTO.
Calcolare il codice: l’impianto del foglio
Per generare un codice fiscale da zero, invece, una formula unica non è la strada giusta. Si può scrivere, ma diventa una riga di alcune migliaia di caratteri che nessuno riuscirà più a correggere. Con le colonne di appoggio ogni passaggio resta ispezionabile, e quando un codice non torna si vede subito dove.
| Cella | Contenuto | Esempio |
|---|---|---|
| A2 | Cognome (testo) | Rossi |
| B2 | Nome (testo) | Mario |
| C2 | Data di nascita (data vera, non testo) | 01/08/1985 |
| D2 | Sesso (M o F) | M |
| E2 | Codice catastale | H501 |
| F2 | Cognome normalizzato | ROSSI |
| G2 | Nome normalizzato | MARIO |
| H2 | Terna del cognome | RSS |
| I2 | Terna del nome | MRA |
| J2 | Anno | 85 |
| K2 | Lettera del mese | M |
| L2 | Giorno con il codice del sesso | 01 |
| M2 | Primi quindici caratteri | RSSMRA85M01H501 |
| N2 | Carattere di controllo | Q |
| O2 | Codice fiscale | RSSMRA85M01H501Q |
Le prime cinque celle sono i dati che inserisci; dalla F2 in poi sono tutte formule. I valori della colonna “Esempio” sono quelli effettivamente prodotti dalla simulazione per Rossi Mario, nato a Roma il 1º agosto 1985.
Consonanti e vocali
È la parte in cui Excel dà il peggio di sé, perché non ha modo di scorrere i caratteri di una stringa. Il giro che funziona è SEQUENCE per generare gli indici, MID per estrarre un carattere alla volta e TEXTJOIN per rimettere insieme quelli che servono. Prima però va normalizzato il testo: via accenti, apostrofi e spazi.
=LET(
maiusc; UPPER(A2);
acc_a; SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(maiusc;"À";"A");"Á";"A");"Â";"A");"Ã";"A");"Ä";"A");"Å";"A");
acc_e; SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(acc_a;"È";"E");"É";"E");"Ê";"E");"Ë";"E");
acc_i; SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(acc_e;"Ì";"I");"Í";"I");"Î";"I");"Ï";"I");
acc_o; SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(acc_i;"Ò";"O");"Ó";"O");"Ô";"O");"Õ";"O");"Ö";"O");
acc_u; SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(acc_o;"Ù";"U");"Ú";"U");"Û";"U");"Ü";"U");
acc_v; SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(acc_u;"Ç";"C");"Ñ";"N");"Ý";"Y");
k; SEQUENCE(LEN(acc_v));
ch; MID(acc_v;k;1);
TEXTJOIN("";TRUE; IF((CODE(ch)>=65)*(CODE(ch)<=90); ch; ""))
)La catena di SUBSTITUTE è brutta e lo resta: Excel non conosce la normalizzazione Unicode, quindi le lettere accentate vanno elencate a mano. Quelle qui sopra coprono l’alfabeto latino occidentale; un cognome con caratteri fuori da questo elenco perderebbe quelle lettere invece di convertirle. Il filtro finale su CODE tiene solo i codici da 65 a 90, cioè le lettere maiuscole non accentate, ed elimina così apostrofi, spazi e trattini.
Ottenuto il testo pulito, la terna del cognome sono le prime tre consonanti, completate con le vocali e poi con delle X:
=LET(
s; F2;
k; SEQUENCE(LEN(s));
ch; MID(s;k;1);
vocale; ISNUMBER(FIND(ch;"AEIOU"));
cons; TEXTJOIN("";TRUE; IF(vocale;"";ch));
voc; TEXTJOIN("";TRUE; IF(vocale;ch;""));
LEFT(cons & voc & "XXX"; 3)
)Per il nome cambia una regola sola, ed è quella che quasi tutti dimenticano: con quattro o più consonanti si prendono la prima, la terza e la quarta. GIOVANNI dà GNN, non GVN.
=LET(
s; G2;
k; SEQUENCE(LEN(s));
ch; MID(s;k;1);
vocale; ISNUMBER(FIND(ch;"AEIOU"));
cons; TEXTJOIN("";TRUE; IF(vocale;"";ch));
voc; TEXTJOIN("";TRUE; IF(vocale;ch;""));
IF(LEN(cons)>=4;
MID(cons;1;1) & MID(cons;3;1) & MID(cons;4;1);
LEFT(cons & voc & "XXX"; 3))
)Anno, mese e giorno
Questa parte, al contrario, in Excel è banale, a patto che C2 contenga una data vera e non del testo che le somiglia.
J2 =RIGHT("0" & MOD(YEAR(C2);100); 2) anno, due cifre
K2 =MID("ABCDEHLMPRST"; MONTH(C2); 1) lettera del mese
L2 =RIGHT("0" & (DAY(C2) + IF(UPPER(D2)="F";40;0)); 2) giorno, +40 se FLe dodici lettere ABCDEHLMPRST sono i mesi da gennaio a dicembre nell’ordine, quindi MONTH indicizza direttamente la stringa. La tabella dei mesi. Per le donne al giorno si sommano 40, ed è per questo che il 25 diventa 65.
Sull’anno una nota: la costruzione RIGHT("0" & MOD(YEAR(C2);100); 2) evita di proposito TEXT. I codici di formato di TEXT sono tradotti insieme all’interfaccia (in un Excel italiano l’anno si scrive aa, non yy) e una formula che li usa smette di funzionare passando da una lingua all’altra.
Restano da concatenare i pezzi:
M2 =H2 & I2 & J2 & K2 & L2 & UPPER(E2) i primi quindici caratteri
O2 =M2 & N2 il codice fiscale completoIl carattere di controllo
Ogni carattere vale due numeri diversi a seconda che si trovi in posizione dispari o pari; si sommano i quindici valori e il resto della divisione per 26 indica la lettera finale. In Excel sembra il punto in cui serve per forza una tabella di ricerca, e invece si può evitare.
Il valore di posizione pari, infatti, è semplicemente la posizione del carattere nell’alfabeto 0-9A-Z: le cifre valgono da 0 a 9, le lettere da 0 a 25. E il valore di posizione dispari dipende solo da quello pari, sempre e comunque. La A e lo 0 valgono entrambi 1 in posizione dispari. Basta quindi una stringa di 52 cifre, letta a coppie:
=LET(
s; M2;
k; SEQUENCE(15);
p; FIND(MID(s;k;1); "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");
pari; IF(p<=10; p-1; p-11);
dispari; VALUE(MID("0100050709131517192102041820110306081214161022252423"; pari*2+1; 2));
MID("ABCDEFGHIJKLMNOPQRSTUVWXYZ"; MOD(SUM(IF(ISODD(k); dispari; pari));26)+1; 1)
)Se preferisci una versione che si possa leggere e controllare a occhio, la stessa cosa con una vera tabella di ricerca. Crea una tabella chiamata Valori con le tre colonne Carattere, Dispari e Pari riportate qui sotto:
=LET(
s; M2;
k; SEQUENCE(15);
ch; MID(s;k;1);
dispari; XLOOKUP(ch; Valori[Carattere]; Valori[Dispari]);
pari; XLOOKUP(ch; Valori[Carattere]; Valori[Pari]);
MID("ABCDEFGHIJKLMNOPQRSTUVWXYZ"; MOD(SUM(IF(ISODD(k); dispari; pari));26)+1; 1)
)La tabella completa dei valori
Trentasei righe, generate dalle stesse costanti che usa il decoder di questo sito, quindi non possono divergere da esso. Le posizioni si contano da uno: la prima, la terza, la quinta e così via sono dispari.
| Carattere | Dispari | Pari |
|---|---|---|
| 0 | 1 | 0 |
| 1 | 0 | 1 |
| 2 | 5 | 2 |
| 3 | 7 | 3 |
| 4 | 9 | 4 |
| 5 | 13 | 5 |
| 6 | 15 | 6 |
| 7 | 17 | 7 |
| 8 | 19 | 8 |
| 9 | 21 | 9 |
| A | 1 | 0 |
| B | 0 | 1 |
| C | 5 | 2 |
| D | 7 | 3 |
| E | 9 | 4 |
| F | 13 | 5 |
| G | 15 | 6 |
| H | 17 | 7 |
| I | 19 | 8 |
| J | 21 | 9 |
| K | 2 | 10 |
| L | 4 | 11 |
| M | 18 | 12 |
| N | 20 | 13 |
| O | 11 | 14 |
| P | 3 | 15 |
| Q | 6 | 16 |
| R | 8 | 17 |
| S | 12 | 18 |
| T | 14 | 19 |
| U | 16 | 20 |
| V | 10 | 21 |
| W | 22 | 22 |
| X | 25 | 23 |
| Y | 24 | 24 |
| Z | 23 | 25 |
La stringa di 52 cifre usata nella formula compatta è esattamente la colonna “Dispari” di questa tabella, scritta a due cifre per volta e ordinata per valore pari crescente. Il calcolo passo per passo
Quattro cose che in Excel non conviene fare
Meglio saperlo prima di passarci un pomeriggio.
Cercare il comune dal codice catastale
Tecnicamente è un CERCA.X, ma prima devi importare e tenere aggiornate 7.896 righe dentro la cartella di lavoro. Se ti serve, i dati pronti sono in /comuni-lookup.json; tieni presente che l’elenco non comprende i comuni soppressi né i codici Z degli Stati esteri, quindi non va usato per invalidare un codice.
Generare le varianti omocodiche
Richiede di sostituire le cifre da destra verso sinistra, una alla volta, e di ricalcolare il carattere di controllo a ogni passaggio: sette colonne in più per un caso che non capita quasi mai. Verificare un codice omocodico, invece, funziona già: la formula di verifica qui sopra lo accetta senza modifiche.
Ricavare il secolo di nascita
Due cifre non bastano a distinguere il 1925 dal 2025 e la scelta richiede una regola, di solito “il secolo più recente che dia una data già passata”. Scriverla in Excel si può, ma è il genere di logica che merita una colonna dedicata e un commento, non un innesto dentro una formula già lunga.
Risalire a nome e cognome
Non è una questione di Excel: non lo può fare nessuno strumento. La codifica tiene tre caratteri per il cognome e tre per il nome e scarta tutto il resto, quindi ROSSI, RUSSO e ROSSO danno tutti RSS. Perché non è possibile
Domande frequenti
Se il foglio di calcolo ti sta stretto, lo stesso algoritmo è disponibile in JavaScript e in Python, dove è più corto e molto più facile da testare. Per controllare pochi codici senza scrivere formule c’è la verifica multipla. Fonte: DM 23 dicembre 1976 (Ministero delle Finanze). Fonti e metodo