Quanto vado a proporre e' una macro excel, che apre il file sorgente e genera tanti differenti file quante sono le S.O. trovate nel corpo della riga.
I file sono creati nella stessa directory in cui e' posizionato il file sorgente. Eventuali file gia' presenti nella directory (es per elaborazioni precedenti) potrebbero essere SOVRASCRITTI, quindi si suggerisce di posizionare il file sorgente in una directory inizialmente vuota.
Contemporaneamente sul foglio Excel attivo verra' creato un riepilogo di quali file sono stati creati e quanti record ogni file contiene.
Il codice della macro:
- Codice: Seleziona tutto
Sub sOsO()
Dim SOCnt(), iSo As Long, sLine As String, fPath As String
Dim FullNome As String, soNum As String, cUF As Long
Dim mySplit, myMatch, Rispo
'
ReDim SOCnt(1 To 50) 'Max 50 Strutture Ospedaliere
'
Rispo = MsgBox("Selezionare il File da splittare" & vbCrLf & _
"I file presenti nella stessa directory potrebbero venire sovrascritti" & vbCrLf & _
" OK per continuare, CANCELLA per interrompere", vbOKCancel)
If Rispo <> vbOK Then Exit Sub
Range("A1:B1000").ClearContents
'Chiedi il file da gestire:
With Application.FileDialog(msoFileDialogFilePicker)
.Title = "..Seleziona il file da splittare.."
.AllowMultiSelect = False
.Filters.Clear
.Filters.Add "Text", "*.txt", 1 '<<< Filtro per estensione
.Show
If .SelectedItems.Count = 0 Then
MsgBox ("Nessuna voce selezionata, procedura annullata")
Exit Sub
End If
FullNome = .SelectedItems(1) 'Directory e Nome del file selezionato
End With
Close #1
'
'Si comincia:
Open FullNome For Input As #1
cUF = cUF + 1
mySplit = Split(FullNome, "\", , vbTextCompare)
Cells(1, "A") = mySplit(UBound(mySplit))
fPath = Replace(FullNome, mySplit(UBound(mySplit)), "", , , vbTextCompare)
'Esamina ogni record
Do Until EOF(1)
Line Input #1, sLine
If Len(sLine) > 15 Then
'solo righe "piene"
soNum = Mid(sLine, 5, 9)
SOCnt(1) = SOCnt(1) + 1
reCUF:
myMatch = Application.Match("SO_" & soNum, Range("A1:A1000"), False)
If IsError(myMatch) Then
cUF = cUF + 1
Close #cUF
Range("A1000").End(xlUp).Offset(1, 0) = "SO_" & soNum
Open fPath & "SO_" & soNum & ".txt" For Output As #cUF
GoTo reCUF
Else
Print #myMatch, sLine
SOCnt(myMatch) = SOCnt(myMatch) + 1
End If
End If
Loop
For iSo = 1 To cUF
Close #iSo
Next iSo
Range("B1:B" & cUF).Value = Application.WorksheetFunction.Transpose(SOCnt)
MsgBox ("Completato..." & vbCrLf & "Record Totali: " & SOCnt(1) & vbCrLf _
& "File creati: " & cUF - 1)
End Sub
Operativamente:
1) Crea un nuovo file Excel
2) Inserisci la macro:
-premi Alt-F11 per aprire l'editor delle macro
-Menu /Inserisci /Modulo
-Copia il codice e incollalo nel frame dx del modulo appena creato
3) Salva il file nel formato .xlsm (macro enabled)
4) Poi torna su Excel, attiva il foglio su cui vuoi avere l'elenco dei file e lancia la macro sOsO:
-premi Alt-F8
-seleziona sOsO dall'elenco di macro disponibili
-premi Esegui
Un primo messaggio informa dell'avvio delle operazioni; una finestra di dialogo consente di sfogliare le directory e selezionare il file da splittare; un ultimo messaggio (dopo il tempo necessario a sfogliare il file di partenza e creare i file di output) informera' del completamento delle operazioni.
I file creati sono reperibili nella directory del file di partenza.
Sul foglio Excel viene creato un elenco con il nome del file di partenza, il nome dei file generati e il numero di record presenti in ognuno.
Io ho provato con un file da circa 50mila record, il tempo di elaborazione e' stato di alcuni secondi.
Prova anche tu con un file limitato prima di partire con 3 milioni di record, cosi' puoi stimare quanto tempo sara' necessario.
Fai sapere...