Macro VBA: dividere un foglio Excel in file separati per valore di colonna
Quasi tutte le macro che si trovano per questo scopo aggiungono un foglio per valore dentro lo stesso file. Se invece ti serve un .xlsx salvato per ogni regione, cliente o fornitore, qui trovi una routine che fa esattamente questo — e l'elenco onesto di ciò che ti lascia comunque da fare a mano.
La macro
Premi Alt+F11, poi Inserisci → Modulo, e incolla entrambe le procedure. Imposta splitCol sul numero della colonna con cui dividere: la colonna B è 2, la colonna D è 4.
Sub SplitToFilesByColumn()
Dim wsData As Worksheet, wsNew As Worksheet, wbNew As Workbook
Dim lastRow As Long, lastCol As Long, i As Long
Dim splitCol As Long, savePath As String, n As Long
Dim dict As Object, key As Variant
splitCol = 2 ' <-- colonna di divisione
Set wsData = ActiveSheet
savePath = ThisWorkbook.Path & "\split\"
lastRow = wsData.Cells(wsData.Rows.Count, splitCol).End(xlUp).Row
lastCol = wsData.Cells(1, wsData.Columns.Count).End(xlToLeft).Column
If lastRow < 2 Then MsgBox "Nessun dato trovato.": Exit Sub
If Dir(savePath, vbDirectory) = "" Then MkDir savePath
' 1. raccoglie i valori unici della colonna
Set dict = CreateObject("Scripting.Dictionary")
For i = 2 To lastRow
key = Trim(CStr(wsData.Cells(i, splitCol).Value))
If Len(key) > 0 Then dict(key) = 1
Next i
Application.ScreenUpdating = False
Application.DisplayAlerts = False
' 2. una copia filtrata per valore, salvata come file a sé
For Each key In dict.Keys
Set wbNew = Workbooks.Add(xlWBATWorksheet)
Set wsNew = wbNew.Worksheets(1)
If wsData.AutoFilterMode Then wsData.AutoFilterMode = False
wsData.Range(wsData.Cells(1, 1), wsData.Cells(lastRow, lastCol)) _
.AutoFilter Field:=splitCol, Criteria1:=key
wsData.Rows(1).Copy wsNew.Rows(1)
On Error Resume Next
wsData.Range(wsData.Cells(2, 1), wsData.Cells(lastRow, lastCol)) _
.SpecialCells(xlCellTypeVisible).Copy wsNew.Cells(2, 1)
On Error GoTo 0
wbNew.SaveAs savePath & SafeFileName(CStr(key)) & ".xlsx", xlOpenXMLWorkbook
wbNew.Close SaveChanges:=False
n = n + 1
Next key
If wsData.AutoFilterMode Then wsData.AutoFilterMode = False
Application.DisplayAlerts = True
Application.ScreenUpdating = True
MsgBox n & " file salvati in " & savePath
End Sub
Function SafeFileName(s As String) As String
Dim bad As Variant, ch As Variant
bad = Array("\", "/", ":", "*", "?", """", "<", ">", "|")
For Each ch In bad
s = Replace(s, ch, "_")
Next ch
SafeFileName = Left(Trim(s), 100)
End Function
- Salva prima il file come
.xlsm— un.xlsxnormale non può contenere macro. - Seleziona il foglio con i dati, con le intestazioni nella riga 1.
- Premi F5 dentro l'editor. I file compaiono nella sottocartella
splitaccanto al tuo documento.
⚠ La prima volta eseguila su una copia. La macro attiva e disattiva i filtri sul foglio vero. Non cancella nulla, ma una prova su un duplicato costa poco.
Cosa la macro non risolve
La routine qui sopra è la metà facile. Tre cose restano sulle tue spalle, e sono il motivo per cui questo lavoro continua a portare via una mattinata.
| Limite | Cosa significa in pratica |
|---|---|
| Non invia nulla | Devi comunque allegare venti file a venti messaggi quasi identici, ognuno a un indirizzo diverso. Aggiungere l'automazione di Outlook è un secondo progetto, per giunta fragile. |
| L'impaginazione si perde in parte | La formattazione delle celle viaggia con le righe copiate. Larghezze delle colonne, riquadri bloccati e formattazione condizionale no, a meno di scrivere codice apposta per ciascuno. |
| Le macro sono spesso bloccate | Molte aziende bloccano le macro nei file ricevuti dall'esterno. Il collega a cui passi il documento potrebbe semplicemente non riuscire a eseguirla. |
C'è poi la manutenzione: se qualcuno inserisce una colonna, splitCol = 2 punta in silenzio ai dati sbagliati, e la macro continua a girare senza protestare.
Quando il VBA è comunque la risposta giusta
Se la divisione gira senza presidio a orari stabiliti, vive dentro una macro più grande che già mantieni, o deve funzionare su una macchina senza accesso a internet, il VBA è lo strumento corretto e il codice qui sopra è un punto di partenza ragionevole.
Quando non lo è
Se stai scrivendo questa macro perché ogni settimana devi fare la stessa divisione e poi mandare ogni parte a una persona diversa, stai per costruire la metà facile e tenerti la metà noiosa. Split & Send fa entrambe in un colpo solo: scegli la colonna e ottieni un file formattato per ogni valore e una bozza email pronta per ciascuno — destinatario giusto, messaggio scritto una volta sola, file già allegato. Funziona nel browser, senza macro e senza installare nulla, e il tuo file non viene caricato da nessuna parte.
Non viene inviato nulla in automatico: le bozze finiscono nel tuo client di posta e le controlli prima che partano.
Provalo col tuo file — gratis, senza registrazione →Domande frequenti
Perché la mia macro crea fogli invece di file?
Quasi tutti gli esempi online aggiungono un foglio per valore dentro lo stesso documento. Per ottenere file separati serve un nuovo oggetto Workbook per ogni valore e una chiamata a SaveAs, come nella routine qui sopra.
La macro mantiene la formattazione originale?
In parte. Copiando le righe la formattazione delle celle viene con loro, ma larghezze delle colonne, riquadri bloccati, formattazione condizionale e impostazione generale del foglio non vengono riprodotti se non li copi esplicitamente.
La macro può inviare ogni file a una persona diversa?
Da sola no. Dovresti aggiungere l'automazione di Outlook: un riferimento al modello a oggetti di Outlook e il codice che associa ogni valore a un indirizzo. Funziona, ma è un secondo progetto da scrivere e da mantenere.
E se in azienda le macro sono bloccate?
Succede spesso, e di solito viene fuori quando passi il file a un collega. Uno strumento nel browser non richiede alcuna macro, quindi non c'è niente da sbloccare.
Posso dividere per più di una colonna?
Con il VBA sì: costruisci la chiave del dizionario unendo i valori delle due celle con un separatore, e nel ciclo usa due criteri di filtro. È una modifica piccola al codice qui sopra.
Correlato: Dividere un Excel per colonna e inviare ogni parte · Stampa unione con un allegato diverso per ogni destinatario.