domingo, 18 de noviembre de 2018

► Recorrer los ficheros de un directorio


NOTA: Con conexiones a Google Drive u otros proveedores de almacenamiento web, NO FUNCIONAN LOS COMODINES * ni ? 

En multitud de ocasiones necesitamos recorrer todos los ficheros de un directorio. Por ejemplo, cuando necesitamos cargar datos históricos y tenemos muchos ficheros con el mismo formato pero de fechas diferentes.

Crear un script que lea un fichero y reescribir el código tantas veces como ficheros hay, aparte de ser tedioso, es poco efectivo. Lo mejor es crear un bucle que haga el trabajo automáticamente.

Este trabajo lo podemos hacer de 2 formas:

1.-  Esta forma es eficaz cuando hablamos de un solo directorio.


Lo primero es crear una variable que contenga el formato de los ficheros porque escribir el formato del nombre directamente dentro de la función filelist() puede dar problemas.

SET FormatoNombre = ..\DATOS\*.dat;

y después, con un bucle, leemos los ficheros

FOR each File in filelist(FormatoNombre) 

   //Y dentro del bucle iniciamos una lista de acciones, por ejemplo, guardarlos en una tabla (concatenate implícito)

   TABLA_TMP:
   LOAD campo1,
        campo2,
        .........
        campoN    
   FROM [$(File)] (txt, utf8, embedded labels, delimiter is '\t', msq);
   
       
NEXT File;
// Siguiente fichero


Hay que tener en cuenta que la variable “File” tiene el Path completo del fichero, por eso debe escribirse entre corchetes “[]”.

Y que la variable de FileList(variable) no lleva expansión de $.
FileList($(variable)) no funciona correctamente.

2.- Ideal cuando los ficheros están distribuidos en un árbol de directorios.


Esta forma es la recomendada por el propio Qlik en la documentación. Utilizaremos una función recursiva que lea cada directorio y cada fichero de ese directorio.
La función recibe como parámetro el path raíz desde donde queremos comenzar a leer carpetas y ficheros.

En este ejemplo leeremos una biblioteca en el que hay una carpeta por cada autor y a su vez cada libro de ese autor está en su propia carpeta junto con otro tipo de información como metadatos, portadas.... etc.

LET Raiz = '\Biblioteca\Autores\';

//Creación de la función
sub DoDir (Root)
    FOR each File in filelist (Root&'\*.*')  //bucle para la lectura de ficheros

         LIBROS_TMP:
         LOAD 
            '$(Root)' AS Directorio,
            '$(File)' AS path_original,
            Filesize('$(File)') AS Tamaño,
            Date(FileTime('$(File)')) AS Fecha_Fichero
         autogenerate 1;

      NEXT File

   FOR each Dir in dirlist (Root&'\*' )  //bucle para la lectura de directorios

      call DoDir (Dir)  //lamada a si misma pasando como parámetro el nombre del directorio actual

   next Dir

end sub   //Fin de la función

..........

// Llamada a la función pasándo como parámetro la variable con el Path desde el que vamos a comenzar a leer.
call DoDir (Raiz);


3.- Variante cuando queremos obtener cierta información del nombre del fichero. En este ejemplo los ficheros tienen la fecha de creación en el nombre en formato numérico y se va a utilizar esta fecha para cargar solamente ficheros entre un rango de fechas.
Además los ficheros se encuentran en Google Drive y, como se advertía al comienzo del artículo, con conexiones a Google Drive u otros proveedores de almacenamiento web, NO FUNCIONAN LOS COMODINES * ni ? 


SET QVD_Path_FLYDE_campañas = 'lib://Google_Drive carpeta (user_xxx)/1z0qlAfk14erbVQk026XrpO1F9h49QAC0';


LET Inicio=45203;  //La fecha en numero corresponde al 04/10/2023
LET Fin=num(today())-1;  //Hasta ayer

// Comenzamos generando una tabla con todas las fechas entre las de inicio y fin
FECHAS_TMP:
LOAD recno()+$(Inicio)-1 AS pp,
     text(date(recno()+$(Inicio)-1,'YYYYMMDD')) AS fecha
AUTOGENERATE $(Fin) - $(Inicio) +1;

// Comenzamos un bucle para leer todos los ficheros. En este caso el nombre del fichero se va generando para cada línea leída de la tabla temporal generada antes.

FOR i=1 TO NoOfRows('FECHAS_TMP')
   LET vFecha=Peek('fecha',-$(i),'FECHAS_TMP');
   SET vFile='$(QVD_Path_FLYDE_campañas)/campaignsqlik_$(vFecha)-170017.csv'; 

// Lectura de los campos de cada fichero, extrayendo la fecha del propio nombre del fichero.
TABLA_DATOS:
LOAD rowno() AS Num_linea,
    date(date#(subfield(subfield(FileName(),'-',1),'_',2),'YYYYMMDD'),'DD/MM/YYYY') AS Fecha,
    campo1,
    campo2,
    ..........
    campo n
FROM [$(vFile)]
// FROM [$(QVD_Path_FLY)/campaignsqlik__$(vFecha)-120017.csv]
// FROM [lib://Google_Drive carpeta (user_xxx)/1z0qlAfk14erbVQk026XrpO1F9h49QAC0/campaignsqlik_20231004-170017.csv]
(txt, codepage is 28591, embedded labels, delimiter is ',', msq)
;
   
NEXT i

No hay comentarios:

Publicar un comentario