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)