Access

Cómo dividir un CSV grande en varios CSV más pequeños

Hace poco me encontré con una pregunta en un foro en la que el usuario necesitaba una forma de dividir un archivo CSV enorme en varios archivos más pequeños y conservar la fila de encabezado en cada uno de los archivos más pequeños. En este caso, la pregunta giraba en torno a JavaScript, pero me hizo pensar en cómo se podría abordar en VB/VBA/VBScript.

Bien, a continuación se presenta un primer intento por abordar una posible solución a esta cuestión.

Función VBA para dividir un archivo CSV

Function CSV_Split(ByVal sSrcCSVFile As String, _
                 ByVal sOutputFolder As String, _
                 ByVal lSplitCSVMaxRowCount As Long, _
                 Optional ByVal sOpenDestFolder As Boolean = True) As Boolean
    Dim iFileNumber           As Integer
    Dim sLine                 As String
    Dim sHeader               As String
    Dim lLineCounter          As Long
    Dim iFileCounter          As Integer
    Dim sOutputFile           As String
    Dim iOutputFileNumber           As Integer

    If Right(sOutputFolder, 1)  "\" Then sOutputFolder = sOutputFolder & "\" ' Ensure the proper formatting of the folder path
    iFileCounter = 1    ' Initialize the split file counter

    ' Open the source CSV for reading its content
    iFileNumber = FreeFile
    Open sSrcCSVFile For Input As #iFileNumber

    Line Input #iFileNumber, sHeader    'Grab the 1st line as the Header to be used in each file we create

    ' Loop through each line of the source CSV file
    Do While Not EOF(iFileNumber)
        ' If line count is zero, create a new output file and write the sHeader line to it
        If lLineCounter = 0 Then
            sOutputFile = sOutputFolder & iFileCounter & ".csv"
            iOutputFileNumber = FreeFile
            Open sOutputFile For Output As #iOutputFileNumber
            Print #iOutputFileNumber, sHeader
        End If

        Line Input #iFileNumber, sLine    ' Read a single line from the source file
        Print #iOutputFileNumber, sLine    ' Write the current line to the output file

        lLineCounter = lLineCounter + 1    ' Increment line counter

        ' If the current line count reaches the max allowable row count, 
        ' close the current output file and reset the line count and index the file counter
        If lLineCounter >= lSplitCSVMaxRowCount Then
            Close #iOutputFileNumber
            lLineCounter = 0
            iFileCounter = iFileCounter + 1
        End If
    Loop

    ' Close any open files
    If lLineCounter > 0 Then Close #iOutputFileNumber
    Close #iFileNumber

    CSV_Split = True 'If we made it here, everything worked and we should have the split files in the output folder
    If sOpenDestFolder Then Application.FollowHyperlink sOutputFolder 'Open the destination folder if requested
End Function

Luego para utilizar la función simplemente haces:

'Take the C:\Temp\testing.csv and break it into files containing a maximum of 15000 rows and save the resulting split CSVs in the C:\Temp\SplitCSV\ folder and don't open the folder once the operation is complete.
If CSV_Split("C:\Temp\testing.csv", "C:\Temp\SplitCSV\", 15000, False) Then
    'We're here because everything worked
End If

Como es habitual, no olvides añadir un manejo de errores adecuado en todo momento.

Algo para considerar

Un enfoque alternativo sería leer el archivo CSV en la memoria (en una variable VBA) de una sola vez en lugar de hacerlo línea por línea, dividir la variable en una matriz y procesar la matriz. Sospecho que esto sería un poco más rápido.

Recursos

Publicaciones relacionadas

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Botón volver arriba