[PowerQuery] Web Content por fila

Muchas veces me ha pasado de tener que consultar una API por el contenido de mi tabla o simplemente armar un scrap de muchas páginas, filas, años, etc. Ciertamente me resultaba complejo pensar en un único paso en power query que permita hacer un recorrido each para cada llamado. Entonces comprendí que me estaba complicando, trabajando más tiempo con power bi me ayudo a recordar las Custom Functions.

La forma de llamar de realizar muchos llamados a una URL es tan sencillo como hacerlo 1 vez.

Funciones en power Bi: en una palabras simples es una consulta que corre por otra consulta. El beneficio de tener una consulta que corre por otra es que podes repetir el los pasos del editor para la misma estructura de forma sencilla y ordenada.

Para construir nuestro recorrido, comencemos construyendo un único llamado hardcodeado con algún valor real de nuestra tabla origen o construida en caso que sean páginas de una web y hayamos construido una columna índice para los llamados. Por ejemplo, quiero obtener la capacity de un proyecto, iteración y usuario de mi azure dev ops. 

Para ello vamos a construir una nueva consulta web llamando a la URL correspondiente:

Web.Contests("https://dev.azure.com/[company name]/[ProjectSK]/_apis/work/teamsettings/iterations/[IterationSK]/capacities/[AssignedToUserSK]?api-version=5.0″)

NOTA: el contenido entre [ ] sería un caso real de su organización.

Separando el web content con buenas prácticas de Chris Webb donde la dirección deberá ser contenida en un relativa path y las variables en query:

Web.Contests("https://dev.azure.com/[company name]/", [RelativePath= [ProjectSK] & "/" & "_apis/work/teamsettings/iterations/" & [IterationSK] & "/capacities/" & [AssignedToUserSK] , Query=[#"api-version"="5.0"]]

La idea es lograr de dicho origen el resultado deseado para transformarlo en una función. ¿Como lo hacemos? en el editor avanzado de la tabla incluyendo dos let in. El primero de ellos con los parámetros y el segundo con todo el resultado que obtuvimos en los pasos anteriores hardcodeando el tiro. El formato debería ser algo así:

let
    Capacity = (ProjectSK as text, IterationSK as text, AssignedToUserSK as text) =>
      let
        Origen = Web.Contents("https://dev.azure.com/company/", [RelativePath= ProjectSK & "/" & "_apis/work/teamsettings/iterations/" & IterationSK & "/capacities/" & AssignedToUserSK , ManualStatusHandling={404}, Query=[#"api-version"="5.0"]] ),

     in
        Origenin   Capacity

En este momento tenemos nuestra función personalizada. El lugar donde iría el nombre de la tabla colocaremos el nombre que deseamos para nuestra función. Ejemplo:

image

Ahora podemos armar nuestro dataset que ejecutará multiples veces la tiro de API. Para ello necesitamos una tabla que contenga los parámetros proyecto, iteración y usuario. Podemos obtenerlo con un tiro diferente a la API para obtener los proyectos, iteraciones y usuarios o tal vez teniendo dicha distribución en un excel o donde fuese. Gracias a nuestra nueva función, basta con agregar una columna personalizada que llame la función con los parámetros de nuestra tabla. 

image

De esta sencilla manera solo restará desplegar los campos deseados en la tabla para contener un masivo llamado a una API o Web para completar los datos necesarios sin armar una iteración each.

También podemos utilizar este método para una API paginada. Traemos primero el total de páginas, en power bi desplegamos una tabla de una columna que vaya de la página 1 a la N y generamos la función custom que llame para cada número de página.

TIP: es necesario usar los parámetros RelativePath y Query para lograr un schedule refresh en el servicio de Power Bi. Caso contrario, será difícil para el mismo reconocer el origen de los datos y lanzará un error.

¡Espero que los ayude a obtener más datos!