viernes, 4 de noviembre de 2022

Power Query: Identifica múltiples rangos

En este artículo veremos cómo conseguir extraer múltiples rangos de datos de un listado de información.
Para simplificar el caso, y centrarnos en la técnica, trabajaremos sobre datos en el mismo fichero...
Asignaremos al conjunto de datos un nombre definido 'ndBBDD', que luego cargaremos al editor de Power Query.
Obviamente, el caso normal será que la base de datos estuviera en otro fichero ;-)
Power Query: Identifica múltiples rangos


El objetivo, por tanto, es extraer aquellos rangos correspondientes a un año, por ejemplo al 2022...
El patrón es claro, localizar las líneas donde aparezcan las palabras 'INICIO' y '2022', y de otra parte la coincidencia múltiple 'FIN' y '2022'...
Veamos el código M necesario:
let
    Origen = Excel.CurrentWorkbook(){[Name="ndBBDD"]}[Content],

    Lst=Origen[Column1],
    //número de palabras/conceptos a buscar simultáneamente
    Contador=2,
    //creamos una 'función' recursiva para la búsqueda múltiple
    BusquedaTextoMultiple=(TablaTemporal,ListaBusqueda,n) =>
        let
            TablaFinal=Table.FindText(
                TablaTemporal,
                ListaBusqueda{n}     )
        in 
            //controlamos la finalización del proceso cuando lleguemos a la última búsqueda
            if n+1=Contador then TablaFinal // terminamos
                else @BusquedaTextoMultiple(TablaFinal,ListaBusqueda,n+1),   // mantenemos el ciclo de búsqueda
            
    //aplicamos nuestra función recursiva anterior sobre la Tabla con los textos originales
    INI=BusquedaTextoMultiple(Origen,{"INICIO","2022"}, 0),
    FIN=BusquedaTextoMultiple(Origen,{"FIN","2022"}, 0),
    //otra opción en este caso de pocas coincidencias
    INI2=Table.FindText(Table.FindText(Origen, "INICIO"),"2022"),
    FIN2=Table.FindText(Table.FindText(Origen, "FIN"),"2022"),

    //determinamos las posiciones de cada texto encontrado
    FilaINI=List.Transform(INI[Column1], each List.PositionOf(Lst,_)),
    FilaFIN=List.Transform(FIN[Column1], each List.PositionOf(Lst,_)),

    //Unimos ambos resultados en una tabla con campos 'desde' 'hasta'
    lstZIP=List.Zip({FilaINI, FilaFIN}),
    TablaPARES=Table.FromRows(lstZIP,{"desde","hasta"}),

    //Extraemos con Table.Range las filas determinadas
    Extraccion=Table.AddColumn(TablaPARES, "DATA", each Table.Range(Origen, [desde], [hasta]-[desde]+1)),
    //y expandimos para mostrarlas..
    ExpandeDATA = Table.ExpandTableColumn(Extraccion, "DATA", {"Column1"}, {"Column1"}),
    OtrasColumnasQuitadas = Table.SelectColumns(ExpandeDATA,{"Column1"})

in 
    OtrasColumnasQuitadas


He optado por una función recursiva dentro del código para realizar la búsqueda múltiple de varios textos...
Si bien, la opción más sencilla para este caso de doble búsqueda sería anidar dos veces Table.FindText.
Nuestra función devuelve una lista de filas coincidentes con la búsqueda múltiple... que luego emplearemos para determinar sus posiciones dentro de la tabla 'Origen', y finalmente la extracción con Table.Range de esas filas, tal como describo en los comentarios del código.

No hay comentarios:

Publicar un comentario

Nota: solo los miembros de este blog pueden publicar comentarios.