La métrica en cuestión era la siguiente:
BIM Info =
// Autor
métrica: Brian Julius
VAR TableInfo =
ADDCOLUMNS (
INFO.VIEW.TABLES (),
"Component", "Tables"
)
VAR ColumnInfo =
ADDCOLUMNS (
INFO.VIEW.COLUMNS (),
"Component", "Columns"
)
VAR RelationshipInfo =
ADDCOLUMNS (
INFO.VIEW.RELATIONSHIPS (),
"Component", "Relationships"
)
VAR MeasureInfo =
ADDCOLUMNS (
INFO.VIEW.MEASURES (),
"Component", "Measures"
)
VAR Result =
TOCSV ( TableInfo )
& TOCSV ( ColumnInfo )
& TOCSV ( RelationshipInfo )
& TOCSV ( MeasureInfo )
RETURN
Result
Bien, ahora que habéis refrescado la memoria de las funciones INFO.VIEW, podemos meternos en “harina” como se suele decir.
Tenemos el siguiente “Panel de control” del modelo semántico que se alimenta de las funciones INFO.VIEW.XXXX():
Vemos que tenemos debidamente documentado nuestro modelo semántico, tanto las descripciones de las medidas, columnas y tablas. Algo que nos facilita mucho las vistas TMDL+VSC+Copilot (aquí el post). Con este informe que llamamos panel de control, tenemos una vista un “pelín” técnica de nuestro modelo semántico. Pero… ¿qué ocurre si queremos una descripción menos técnica, que nos detecte puntos débiles de nuestro modelo, así como nos ofrezca posibles mejoras de rendimiento o propuestas de valor para el modelo que no hemos detectado? Aquí es donde entra en acción Brian Julius con su métrica.
Si vamos a la vista de consultas DAX y pegamos la métrica anterior, obtenemos:
Un error, ¿por qué? Por qué “Result” no es una expresión tipo tabla. Para solucionarlo podemos hacer 3 opciones:
- Llamar a nuestro vecino para que nos la arregle.
- Modificar la expresión completa para adaptarla.
- Envolver con {} Result de manera que lo convirtamos en salida tipo tabla.
Yo opto por la tercera opción ya que es más rápida y sencilla para este caso:
Copiamos el valor devuelto y vamos a Copilot, ChatGPT o a la
IA que queramos, le pegamos dicha información con un prompt similar al
siguiente:
“Como experto en el modelo tabular, te copio información sobre mi modelo de datos de Power BI. Explicame de manera clara y precisa todo lo que puedas saber del modelo semántico: (y aquí pegamos el valor devuelto por la métrica anterior)”
Y nos devuelve lo siguiente (son pantallazos de lo que ha devuelto ChatGPT en este caso y no son todos):
¿Cómo os quedáis? Yo cuando lo ví, dije: “Wauu”. Pero a la vez me hizo pensar (sí, raro en mí ya lo sé pero por una vez que piense no pasa nada ¿no?) Me hice las siguientes preguntas:
El potencial que tiene es espectacular
pero esto es sólo la punta del iceberg.
- Me está devolviendo las tablas de control que tengo. ¿Las puedo quitar?
- ¿Qué pasaría si integrásemos todo en el reporte de Power BI?”
La respuesta a la primera pregunta es “Sí, sí se puede” y lo hice adaptando la
métrica de Brian Julius a mi modelo y nomenclatura:
BIM_Info_Table =
VAR ExcludedTables =
FILTER(
INFO.VIEW.TABLES(),
NOT LEFT([Name], 5) = "Tabla" // Excluye tablas cuyo nombre empieza con "Tabla" ya que todas las tablas de las funciones INFO.VIEW comienzan “Tabla”
)
// Normalizamos la estructura para que todas las tablas tengan las mismas columnas
VAR TableInfo =
SELECTCOLUMNS(
ExcludedTables,
"Nombre", [Name], // Nombre de la tabla
"Tipo", "Table", // Indica que es una tabla
"Tabla de Origen", BLANK(),
"Dato Relacionado", BLANK(),
"Expresión", BLANK(),
"Descripción", [Description] // Descripción de la tabla
)
VAR ColumnInfo =
SELECTCOLUMNS(
EXCEPT(
INFO.VIEW.COLUMNS(),
FILTER(INFO.VIEW.COLUMNS(), LEFT([Table], 5) = "Tabla")
),
"Nombre", [Name], // Nombre de la columna
"Tipo", "Column", // Indica que es una columna
"Tabla de Origen", [Table], // Tabla a la que pertenece la columna
"Dato Relacionado", BLANK(),
"Expresión", BLANK(),
"Descripción", [Description] // Descripción de la columna
)
VAR RelationshipInfo =
SELECTCOLUMNS(
EXCEPT(
INFO.VIEW.RELATIONSHIPS(),
FILTER(INFO.VIEW.RELATIONSHIPS(), LEFT([FromTable], 5) = "Tabla" || LEFT([ToTable], 5) = "Tabla")
),
"Nombre", BLANK(), // Las relaciones no tienen un nombre específico
"Tipo", "Relationship", // Indica que es una relación
"Tabla de Origen", [FromTable], // Tabla de origen de la relación
"Dato Relacionado", [ToTable], // Tabla de destino de la relación
"Expresión", [Relationship],
"Descripción", [CrossFilteringBehavior] & " - " & [IsActive]
)
VAR MeasureInfo =
SELECTCOLUMNS(
EXCEPT(
INFO.VIEW.MEASURES(),
FILTER(INFO.VIEW.MEASURES(), LEFT([Table], 5) = "Tabla")
),
"Nombre", [Name], // Nombre de la medida
"Tipo", "Measure", // Indica que es una medida
"Tabla de Origen", [Table], // Tabla a la que pertenece la medida
"Dato Relacionado", BLANK(),
"Expresión", [Expression], // Código DAX de la medida
"Descripción", [Description] // Descripción de la medida
)
// Unimos todas las tablas en una única tabla con la misma estructura
RETURN
UNION(
TableInfo,
ColumnInfo,
RelationshipInfo,
MeasureInfo
)
Por otro lado, esta métrica la convierto en tabla, es decir, materializo una tabla en mi modelo de datos llama BIM_Info_Table. Y diréis, ¿por qué hago una tabla si la medida es mejor? Estamos de acuerdo, pero si quiero ejecutar una consulta DAX mediante Power Automate, las funciones INFO ya no están disponibles por seguridad, por lo que materializo una tabla con las funciones INFO, y desde Power Automate lanzo la consulta de la tabla (no de las funciones INFO).
Una vez hecho el paso anterior, empecé a trastear y llegue a la siguiente infraestructura:
Y rellenamos los campos área de trabajo, el conjunto de datos y el texto de la consulta. Como podéis ver, estamos ejecutando una simple consulta EVALUATE a la tabla que hemos creado previamente. Importante, el informe tiene que estar publicado en el servicio de Power BI.
A continuación, añadimos un nuevo paso, que en este caso es HTTP (es un conector premium eso sí…). Seleccionamos el método que vamos a usar, que es “POST” ¿Por qué? Porque vamos a mandar (o por lo menos intentarlo 😊) a ChatGPT el mensaje del que queremos respuesta.
En el segundo paso, URI, introducimos lo siguiente:¡Nos vemos en los datos!