Home

Grupos calculados en Power BI Desktop

Llegó la magia a Power BI. Desde que aparecieron los grupos calculados con SQL Server 2019 para Analisys Services y Power BI Premium, los usuarios pro esperábamos como agua de mayo esta implementación. Tabular editor fue la primera herramienta externa que permitió su implementación, pero seguía sin funcionar en Power BI Desktop que no admitía los grupos calculados. Y ha sido hoy, con el update de Julio cuando se han introducido, en primer lugar la implementación de herramientas externas en Power BI como Dax Studio o Tabular Editor y, por fin, la aparición de los Grupos Calculados que tanto ahorro de métricas nos pueden conllevar. En el siguiente vídeo, explico sus ventajas y como crear de manera muy sencilla un Grupo Calculado de Time Intelligence

Control total de las actualizaciones de nuestros datasets y dataflows con Power Automate

La actualización de datasets y dataflows en el servicio de power bi pueden programarse, con el límite de 8 al día en el servicio de Power BI para que se lleven a cabo a una hora concreta en intervalos de 30 minutos. Sin embargo en determinados escenarios podemos necesitar que la hora de inicio de la actualización sea dinámica, dependa de un evento anterior. Imaginad por ejemplo que trabajamos sobre un modelo de datos que ataca un DataWarehouse, o datos en una capa de staging que se almacenan en un proceso que se realiza cada noche y que puede no tener una hora de conclusión fija.

Por otro lado, cuando actualizamos un dataflow necesitamos actualizar con posterioridad todos los datasets que dependen de él y esto es aun más complicado porque no podemos saber de manera alguna actualmente cuando ha acabado la actualización de ese dataset.

Todas estas casuísticas podemos solucionarlas haciendo depender la actualización no de la programación en el servicio, demasiado estática, sino creando el mapa de actualizaciones en powerautomate.

En el siguiente video os muestro como hacerlo.

Webscrapping con Power BI

Hace unas semanas tuve el privilegio de compartir una hora en el Power BI User Group de Panamá con Pablo Moreno y un centenar de asistentes, hablando de webscrapping con Power BI. Repasé varios aspectos de power query como creación de funciones o uso del RelativePath con Web.Contents para poder actualizar los datos. Con permiso de Pablo que gustoso me ha cedido la grabación la ponemos a disposición de quien la necesite.

Tip Excel: Crear una tabla plana a partir de una visualización de tabla de power BI conectandonos al modelo en el servicio

¿Cuantas veces no os ha pedido un cliente o un usuario de negocio que le saquéis un informe en Excel? Por más que le expliques que Power BI no es excel y que tiene muchísimas más ventajas que excel, él quiere su informe en excel.

Le enseñas a exportarse los datos desde el servicio y dentro de dos días te llama para decirte que el excel no está actualizado, que lo exportó antes de ayer y ya faltan datos, que el quiere ver en el excel la tabla que tiene en Power BI hoy.

Como sabeis, excel te permite conectarte al servicio para crear una tabla dinámica conectada al modelo, pero en el siguiente video, voy más allá y os voy a enseñar un pequeño truco para reproducir la tabla con todos los datos tal cual realiza la exportación desde el servicio, pero con la ventaja de que no será una foto estática de los datos sino que la podremos actualizar.

Sin más preámbulos, dentro vídeo.

Excel Tip. Crear tabla plana conectada a Power BI

Comprendiendo el SUMX

El grupo de usuarios de telegram de Power BI en español es una fuente inagotable de contenido sobre Power BI. Allí muchos usuarios plantean sus dudas y otros usuarios les ayudan desinteresadamente. Tengo la suerte de ser uno de los administradores del grupo desde hace un par de meses y en las últimas semanas hemos lanzado algún juego tipo encuesta para luego explicarlo y ayudar a la gente sobre temas controvertidos.

Él último quiz lo planteé yo sobre la utilización de SUMX y posteriormente elaboré un video con la explicación que pongo a vuestra disposición por si os sirve de ayuda:

Éste era el objeto del quiz
Éste el resultado totalmente anónimo del mismo

Y os dejo el video explicativo que publiqué en el canal de youtube de Quolutions

Os dejo el enlace del grupo de telegram por si os interesa entrar;

https://t.me/powerbiespanol

El tema dio para muchísimo debate en el grupo por la implicación también que esta medida puede tener en cuanto a rendimiento.

Conectar un informe realizado sobre el conjunto de datos a un conjunto de datos del Servicio de Power BI

Es curioso muchas veces como tendemos a complicarnos la vida y las soluciones más sencillas se nos escapan a la vista.

Hace mucho tiempo ya que Power BI permite conectar un informe al Servicio de Power BI. Esto nos permite, crear un modelo y a partir de ese modelo poder hacer diferentes informes sobre el mismo. Es más, es una buena práctica que evita que cuando se hacen cambios en el modelo pueda eliminarnos accidentalmente algún informe.

Hace mucho tiempo también que publiqué sobre ello en mi anterior blog y como mediante la modificación de la estructura del archivo pbix comprimido se podía cambiar un informe que estuviera armado sobre el modelo, a un informe conectado al servicio.

Esta práctica últimamente me estaba dando muchos quebraderos de cabeza. Imágenes que no se registraban y aparecían en negro, cambios en los archivos que estructuran el pbix y un sin fin más de problemas que me hicieron abandonar esta práctica y hace poco en el PUG Spain un usuario contestó sobre el asunto con una manera sencilla pero que me hacía dudar si funcionaría:

«Elimina todas las tablas y crea la conexión».

Hoy tenía necesidad de convertir un modelo a informe conectado al servicio y era buen momento de probarlo.

He eliminado todas las tablas del pbix

Todas las visualizaciones se han roto por completo

He creado la conexión al servicio:

Conjunto de Datos de Power BI

Y mi informe vuelve a contener todas las visuales correctamente y como podéis ver en la parte izquierda del informe no contiene el modelo de datos, sino que está conectado a un modelo de datos en el servicio

Por supuesto no puedo dejar de mencionar a la persona que expuso la idea en el foro que fue Josep M PuigDollers, yo simplemente he probado que funcionara y la he reflejado en este post por si es de utilidad.

Otorgar licencias de Power BI a usuarios externos a la organización.

No suelo escribir sobre temas de administración de O365, pero preguntaban hoy en el grupo de Power BI Español en Telegram, fuente inagotable últimamente de ideas para este blog, sobre si existía esa posibilidad y pensé que en alguna ocasión se me dio el caso de tener que compartir un informe con un usuario externo que no tenía licencia de power bi pro y siempre me decanté por tener un usuario de power bi de mi propio tenant para ello.

Pero revisando información sobre el tema vi varios post en la comunidad que afirmaban esta posibilidad y me aventuré a probarlo. Es más, no sólo me aventuré a probar si se podía dar una licencia de nuestro tenant a un usuario externo, sino que probé otorgar una licencia de Power BI PRO a una cuenta personal de outlook.

Como imagino que todos sabréis no se puede entrar al servicio de Power BI con una cuenta personal de microsoft

Sin embargo, nada impide compartir un informe de Power BI con un usuario de cuenta personal, siempre y cuando sea una cuenta de Microsoft.

Si compartes con un usuario de gmail, por ejemplo, no te lo impide,

e incluso registra la dirección en el active directory como invitado

pero ni envía el link al correo para entrar en el informe, ni te permite loguearte como es normal en power bi.

Pero con mi usuario externo, cuenta personal de outlook, me envía el email con el enlace al informe y me deja loguearme sin problema en Power BI a través de es enlace.

Este es el email que se recibe y siguiendo ese enlace se puede acceder al login del servicio de Power BI y no te da el error de cuenta personal

Sin embargo, debido a un bug que hay esta semana en el servicio de power bi que afecta a los usuarios externos no me lleva al informe sino que me redirecciona a una página de inicio. Sin ese bug debería simplemente avisarme de que no tengo licencia de power bi pro para ver el informe.

Si intentamos abrir el informe que muestra como compartido, al carecer de licencia no hace absolutamente nada.

Pero si podemos dar una licencia de nuestro tenant a un usuario externo.

Simplemente nos iremos al Centro de administración de Office 365 y en licencias podremos asignar la licencia al usuario externo:

Al usuario de gmail no me va a dejar asignarsela
Pero al de outlook sin problema

Una vez con la licencia asignada, el mismo link del email nos sirve para entrar en nuestro informe compartido con el usuario externo siendo este una cuenta personal y no profesional

El mismo proceso de asignación de licencia se puede llevar acabo en el azure active directory, aunque es bastante más sencilla esta vía a través del centro de administración de Office 365.

Es muy importante en AAD configurar la ubicación de uso porque si no da un error
En Licencias, Tareas se accede a la página donde se asigna la licencia
Y la asignación es bastante sencilla salvo por el tema de que si no estableces la ubicación de uso, da error

Integración de varios archivos con la misma estructura desde una carpeta de sharepoint en dataflows.

Solución de problemas e introducción a la creación de funciones en Power Query

Siempre digo que soy un #dataflow_lover. Todos mis proyectos intento desarrollarlos mediante flujo de datos aunque en ocasiones las cosas se ponen complicadas debido a algunos errores que pueden aparecer. En las últimas semanas, la integración de carpetas con sharepoint está dando algún quebradero de cabeza. Vamos a analizar uno concreto, la integración de archivos con una misma estructura desde una carpeta de sharepoint.

Para empezar, en cuanto creamos un dataflow y elegimos Carpeta de Sharepoint como Origen de datos nos encontramos con el primer error. La secuencia es la siguiente:

Escogemos Carpeta de Sharepoint como origen de datos
Introducimos la URL (ya sabeis que tiene que ser el directorio Raíz, sin la carpeta Documentos) e iniciamos sesión con nuestra cuenta de Microsoft (al ser un origen Cloud no necesitamos gateway)

Y lo primero que nos encontramos es que la carpeta aparece vacía.

Esto es muy sencillo de resolver. El conector del Dataflow no está escribiendo correctamente la sentencia y basta con añadir al código lo siguiente:

SharePoint.Files("https://quolutions.sharepoint.com/sites/quolutions", [ApiVersion = 15])
Con [ApiVerion]=15 primer problema resuelto

Vamos a escoger sólo dos archivos de la carpeta para el ejemplo:

Le damos a las flechitas para combinar y nos devuelve un error

Antes de crear las funciones de combinación de manera automática como el desktop, el primer paso de filtrado de archivos ocultos devuelve un error.

Esto no pasa en el desktop que va a mostrar el cuadro de diálogo de combinación de archivos y va a crear las funciones necesarias después de aceptar:

¿Cómo podemos resolver esto en Dataflow? No he encontrado documentación por ningún sitio. Incluso hay un hilo en la comunidad sin resolver: https://community.powerbi.com/t5/Service/quot-Unexpected-error-quot-when-reading-sharepoint-folder-full/td-p/841277

Como yo lo resuelvo es simplemente creando yo la función de combinación. De hecho incluso en el desktop, no me gusta la forma en que Power Query realiza la automatización de la función y suelo crear yo mi propia función. El procedimiento es sencillo.

1º Escojo sólo un archivo con el que trabajar las transformaciones, hago doble click sobre binary en uno de ellos y me devuelve la información del csv en este caso. Valdría igual con excel o cualquier otro origen.

El código que me genera es el siguiente:

let
  Origen = SharePoint.Files("https://quolutions.sharepoint.com/sites/quolutions", [ApiVersion = 15]),
  Navegación = Origen{[Name = "LOG_20200513.csv", #"Folder Path" = "https://quolutions.sharepoint.com/sites/quolutions/Documentos compartidos/General/Argomaniz/DATOS_VISION/"]}[Content],
  #"CSV importado" = Csv.Document(Navegación, [Delimiter = ";", Columns = 17, QuoteStyle = QuoteStyle.None]),
  #"Encabezados promovidos" = Table.PromoteHeaders(#"CSV importado", [PromoteAllScalars = true]),
  #"Tipo de columna cambiado" = Table.TransformColumnTypes(#"Encabezados promovidos", {{"FECHA", Int64.Type}, {"HORA", type text}, {"LADO", type text}, {"A1", Int64.Type}, {"A2", Int64.Type}, {"R1_A", Int64.Type}, {"R1_B", Int64.Type}, {"R2", Int64.Type}, {"R3", Int64.Type}, {"R4", Int64.Type}, {"R5", Int64.Type}, {"R6", Int64.Type}, {"B1", Int64.Type}, {"B2", Int64.Type}, {"B3", Int64.Type}, {"B4", Int64.Type}, {"RESULTADO", type text}})
in
  #"Tipo de columna cambiado"

Ahora lo que quiero es simplemente crear una función que tenga como parámetro el nombre del archivo. Para crear la función, tengo que envolver todo el código anterior en un let …. in en el que creo el parámetro y sustituir en el código anterior el nombre del archivo por el parámetro. El código de la función quedaría así:

let
  archivos = (nombrearchivo as text) =>  //este es el parámetro creado



let
  Origen = SharePoint.Files("https://quolutions.sharepoint.com/sites/quolutions", [ApiVersion = 15]),
  Navegación = Origen{[Name = nombrearchivo, #"Folder Path" = "https://quolutions.sharepoint.com/sites/quolutions/Documentos compartidos/General/Argomaniz/DATOS_VISION/"]}[Content], //aquí cambiamos el nombre del archivo por el parámetro
  #"CSV importado" = Csv.Document(Navegación, [Delimiter = ";", Columns = 17, QuoteStyle = QuoteStyle.None]),
  #"Encabezados promovidos" = Table.PromoteHeaders(#"CSV importado", [PromoteAllScalars = true]),
  #"Tipo de columna cambiado" = Table.TransformColumnTypes(#"Encabezados promovidos", {{"FECHA", Int64.Type}, {"HORA", type text}, {"LADO", type text}, {"A1", Int64.Type}, {"A2", Int64.Type}, {"R1_A", Int64.Type}, {"R1_B", Int64.Type}, {"R2", Int64.Type}, {"R3", Int64.Type}, {"R4", Int64.Type}, {"R5", Int64.Type}, {"R6", Int64.Type}, {"B1", Int64.Type}, {"B2", Int64.Type}, {"B3", Int64.Type}, {"B4", Int64.Type}, {"RESULTADO", type text}})
in
  #"Tipo de columna cambiado"
in
  archivos
Y ya tenemos nuestra función creada

No os lo había advertido pero lo mejor es crear la función sobre una copia de la consulta antes de hacer las transformaciones de la tabla porque ahora sobre ese archivo original es sobre el que invocaremos la función.

Vamos a quedarnos para este ejemplo con 3 logs unicamente

Nos quedamos sólo con la columna name e invocamos la función que previamente habíamos creado.

En este punto, el usuario si no tiene mucha experiencia puede entrar en pánico porque esto no existe en los dataflow

Pero a poco que conozcamos un poco como funciona M, la invocación de una función no es más que agregar una columna personalizada y eso si podemos hacerlo en los dataflow y en la fórmula pondremos:

Nombrefunción([ColumnaParametro])

Mi función se llama consulta y la columna que quiero invocar en el parámetro es el nombre del archivo (name)

Le damos a aceptar y ya nos trae cada una de las tablas con todas las transformaciones que hayamos hecho. En el ejemplo no he hecho ninguna transformación pero podríamos hacer las que quisiéramos. Sólo tenemos que expandir la tabla y listo.

Espero que sea de utilidad y que estas pequeñas piedras en el camino no os aparten de la senda de los Dataflow

Calendarios Personalizados (I). El Año Fiscal

En muchísimos contextos sobre todo financieros, el Año Fiscal no tiene por qué coincidir con el año natural. Ello conlleva que haya que realizar algunos cambios en nuestra Dimensión Fecha y que las funciones de inteligencia temporal no puedan usarse de igual modo que con el calendario normalizado. No vamos a entrar en este momento a tratar el tema de los cálculos de inteligencia temporal, que abordaremos después de que veamos todas las funciones de inteligencia temporal con los calendarios normalizados. En este post lo que voy a enseñar es como introducir las columnas propias del calendario fiscal en nuestra Dimensión Fecha.

En primer lugar estableceremos una nueva variable en nuestro calendario que denominaremos __PrimerMesFiscal, para poder dinamizar los cálculos en función de esta variable.

P.ej. var __PrimerMesFiscal=7 para un calendario fiscal que comienza el 1 de julio, en las Sociedades Anónimas Deportivas en España tienen este calendario fiscal.

Y una vez que tenemos esa variable, las columnas que crearemos en nuestra tabla de fechas serán las siguientes:

"NumAñoFiscal", IF(MONTH([Date])<___PrimerMesFiscal,YEAR([Date])-1,YEAR([Date])),
"NumMesFiscal", IF(MONTH([Date])<___PrimerMesFiscal,13-___PrimerMesFiscal+MONTH([Date]),MONTH([Date])-___PrimerMesFiscal+1),
"NumTrimestreFiscal", ROUNDUP(IF(MONTH([Date])<___PrimerMesFiscal,13-___PrimerMesFiscal+MONTH([Date]),MONTH([Date])-___PrimerMesFiscal+1)/3,0),
"AñoFiscal", "FY-"&IF(MONTH([Date])<___PrimerMesFiscal,YEAR([Date])-1,YEAR([Date])),
"MesFiscal", "FM-"&FORMAT(IF(MONTH([Date])<___PrimerMesFiscal,13-___PrimerMesFiscal+MONTH([Date]),MONTH([Date])-___PrimerMesFiscal+1),"0#"),
"TrimestreFiscal", "FQ-"&ROUNDUP(IF(MONTH([Date])<___PrimerMesFiscal,13-___PrimerMesFiscal+MONTH([Date]),MONTH([Date])-___PrimerMesFiscal+1)/3,0),
"EjercicioMesFiscal", "FYM-"&IF(MONTH([Date])<___PrimerMesFiscal,YEAR([Date])-1,YEAR([Date]))&"-"&FORMAT(IF(MONTH([Date])<___PrimerMesFiscal,13-___PrimerMesFiscal+MONTH([Date]),MONTH([Date])-___PrimerMesFiscal+1),"0#"),
"EjercicioTrimestreFiscal", "FYQ-"&IF(MONTH([Date])<___PrimerMesFiscal,YEAR([Date])-1,YEAR([Date]))&"-"&ROUNDUP(IF(MONTH([Date])<___PrimerMesFiscal,13-___PrimerMesFiscal+MONTH([Date]),MONTH([Date])-___PrimerMesFiscal+1)/3,0)

Como podemos observar, el cálculo es diferente si el mes de la fecha es menor que el primer mes fiscal o mayor y por eso lo construimos siempre con IF

Como he dicho, en este post no vamos a ver cómo utilizar la inteligencia temporal con un calendario fiscal, algo que veremos con más detenimiento más adelante, pero si voy a hablar de la excepción a la regla. En principio, cuando utilizamos un calendario fiscal no nos van a servir las funciones de inteligencia temporal, sino que tendremos que estudiar unos patrones de cálculos, sin embargo, hay una función de inteligencia temporal que si nos va a admitir la configuración del calendario fiscal. Se trata de la acumulación con TOTALYTD.

La función TOTALYTD o la anterior CALCULATE(Expresion,DATESYTD…) que devuelve la expresión de manera acumulada en el ejercicio, puede contener un parámetro denominado fin de año, para ajustar el calendario fiscal. Por ejemplo para las ventas acumuladas en un calendario fiscal cuyo mes de inicio es el mes de julio, la métrica sería:

Ventas YTD = TOTALYTD([Ventas],dimFechas[Fecha],"30-6") 

que sitúa el 30 de junio como fin del calendario fiscal.

En el próximo post sobre inteligencia temporal hablaremos del cálculo de los desvíos en nuestro calendario fiscal y agregaremos diferentes períodos relacionados con el calendario fiscal en nuestra dimensión período.

Adjuntamos dimFechas con los nuevos cálculos de calendario fiscal.

Y si quereis estar al tanto de las novedades del blog no olvidéis suscribiros

Simulando seguridad a nivel de página con Power BI

Con la actualización de Mayo una de las principales novedades ha sido la posibilidad de establecer un sistema de navegación mediante acciones condicionadas. Gracias a esto y con una sencilla técnica podemos realizar algo que hasta ahora era imposible, obtener seguridad a nivel de página, podemos establecer qué usuarios pueden acceder a qué páginas dentro de un informe.

En el siguiente vídeo, os lo muestro.