Volcar el contenido de un Datasource a un fichero ASCII

Seguramente pensarás en ExportToCSV y la verdad es que funciona para pequeñas cantidades de registros como 3.000 ó 4.000 registros.

Yo me tuve que enfrentar a una exportación de 500.000 registros y la verdad se moria… Cuando habían pasado 45 minutos, cancelé el proceso y busque otra forma de hacerlo. Aquí está el resultado que realizó el mismo proceso en menos de 1 minuto.

// Resumen: Vuelca el contenido de un Data Source a un fichero 
// ASCII, entrecomillando los campos y separando con un TABULADOR
//
// Sintaxis:
//
//[ <Result> = ] DataSourceToCSV (<nFileNum> is int, <dsTabla> 
//            is data source, <sTextoProgressBar> is string)
//
// Parámetros:
//            nFileNum (int): Identificador creado por FOPEN.  
//                    Será usado para escribir en el fichero
//            dsTabla (data source): Data source a tratar
//            sTextoProgressBar (ANSI string): Texto que se 
//                    mostrará en la barra de status junto al 
//                    ProgressBar
//            nFactorEscrituras (int OPCIONAL): Sirve para reducir 
//                    el número de veces que se escribe en disco.  
//                    Se acumulan tantas líneas como el factor 
//                    especificado y cuando se cumple, se escribe 
//                    en el fichero
// Valor de retorno:
//            boolean: // Ninguno
//
//
PROCEDURE DataSourceToCSV(LOCAL nFileNum is int, LOCAL dsTabla is Data Source, 
          LOCAL sTextoProgressBar is string, 
          LOCAL nFactorEscrituras is int = 100):boolean
 
bReturn is boolean = True
 
nLinea, nLineas are int
vValue is Variant
sLineToWrite is string
sListItm is string
 
// Cadena de texto que se usará para acumular texto y reducir el número 
// de escrituras en disco
sCadenaTextoParaEscribir is string
 
WHEN EXCEPTION IN
               
     nLinea  = 1
               
     // Número de registros en el Data Source
     nLineas = HNbRec(dsTabla)
               
     // Lista campos en el Data Source
     sListItm = HListItem(dsTabla)
 
     sCadenaTextoParaEscribir = ""
 
     ProgressBar(nLinea, nLineas,sTextoProgressBar, DarkBlue)
     Multitask(-1)
               
    // Procesamos todos los registros           
    HReadFirst(dsTabla)
    WHILE HOut(dsTabla) = False
                              
        sLineToWrite = ""
                              
        // Creamos el contenido entre comillas y separado por TAB
        FOR EACH STRING sAnItem OF sListItm SEPARATED BY CR
            vValue = {"dsTabla." + sAnItem, indItem}
            sLineToWrite += [TAB] + """"+ vValue + """"
        END
                              
       // Si se cumple el factor, escribimos la cadena en el fichero
       IF modulo(nLinea, nFactorEscrituras) = 0 THEN
 
           // Si la ventana tiene una barra de estado con una barra 
           // de progreso, se muestra en ella
           ProgressBar(nLinea, nLineas,sTextoProgressBar, DarkBlue)
           Multitask(-1)
                                              
           // Añadimos la línea sin CR al final, ya que la función: fWriteLine, lo añadirá
           sCadenaTextoParaEscribir += sLineToWrite
                                              
           // Escribimos la línea
           fWriteLine(nFileNum, sCadenaTextoParaEscribir)
                                              
           sCadenaTextoParaEscribir = ""
       ELSE
          // Añadimos un retorno de carro
          sCadenaTextoParaEscribir += sLineToWrite + CR
       END
                              
       nLinea ++
                              
       HReadNext(dsTabla)
   END
 
   // Si ha quedado texto sin escribir
   IF sCadenaTextoParaEscribir <> "" THEN
      // Escribimos la línea
     fWriteLine(nFileNum, sCadenaTextoParaEscribir)
   END
DO
   bReturn = False
   Error( ExceptionInfo(errMessage) )
END
 
RESULT(bReturn)