Tutorial: Creación de un flujo de trabajo de actualización de estado

En este tutorial de un extremo a otro, creará un flujo de tareas translítico que realiza un seguimiento del estado del proyecto, escribe las actualizaciones en una base de datos y publica notificaciones de un informe de Power BI en Microsoft Teams. La solución mantiene un historial completo de todas las actualizaciones de estado, por lo que puede realizar un seguimiento de cómo ha cambiado el estado del proyecto con el tiempo. En este tutorial se muestra cómo combinar la escritura diferida de datos con llamadas API externas para crear un flujo de trabajo de comunicación completo.

En este tutorial aprenderá a:

  • Cree una base de datos SQL en Fabric con tablas de seguimiento de proyectos y estado que mantengan el historial completo.
  • Configure una biblioteca de variables para almacenar la configuración por separado.
  • Configure funciones de datos de usuario que actualicen el estado, las actualizaciones de solicitudes y publiquen notificaciones en Teams.
  • Opcionalmente, configure los accesos directos de Lakehouse con vistas materializadas al lago para las vistas de Direct Lake.
  • Integre las funciones de datos de usuario con un informe de Power BI mediante botones de función de datos.

Si no tiene una capacidad de Fabric existente, inicie una versión de prueba de Fabric.

Prerrequisitos

  • Power BI Escritorio. Si no tiene Power BI Desktop instalado en el dispositivo, siga las instrucciones de Obtención de Power BI Desktop.
  • Un canal de Microsoft Teams donde tienes permiso para agregar webhooks entrantes.

Visión general

En este tutorial se crea una solución de seguimiento de proyectos en la que los usuarios pueden actualizar el estado del proyecto directamente desde un informe de Power BI. Cuando un usuario actualiza un estado, el sistema:

  1. Escribe el nuevo estado en la base de datos SQL, manteniendo un historial completo de todas las actualizaciones de estado.
  2. Envía una notificación de Adaptive Card a Microsoft Teams.
  3. Actualiza el informe para mostrar los datos actualizados.

Flujo de usuario

El flujo de trabajo crea un bucle de comentarios continuo entre los usuarios del informe:

  1. Solicitud de actualización a través de Teams desde el informe : un usuario selecciona un proyecto en el informe y envía una solicitud de actualización de estado. La solicitud publica en Teams con un vínculo de regreso al informe.

  2. Recibir notificación en Teams y abrir informe : el propietario del proyecto ve la notificación en Teams y selecciona el vínculo para abrir el informe.

  3. Estado de actualización en el informe : el propietario del proyecto selecciona el proyecto, elige un nuevo estado, agrega notas y selecciona el botón actualizar.

  4. Vea la actualización en tiempo real y envíe notificaciones — El informe se actualiza inmediatamente para mostrar el nuevo estado y se envía una notificación a Teams confirmando el cambio.

Architecture

La solución conecta estos componentes dentro de Microsoft Fabric:

Componente propósito
Fabric SQL Database Almacena registros de actualización de proyecto y estado con historial completo. Contiene la tabla Project, la tabla Status updates (que mantiene un historial completo de todos los cambios) y la vista Project status.
Lakehouse (opcional) Proporciona accesos directos a las tablas de base de datos SQL para las vistas de Direct Lake. Use cuando necesite vistas de lago materializadas para el análisis.
Biblioteca de variables Almacena valores de configuración como la dirección URL del webhook de Teams y la dirección URL del informe. Actualice los valores sin volver a publicar las funciones.
Funciones de datos de usuario Funciones de Python que gestionan la escritura de retorno en SQL y envían notificaciones a Microsoft Teams a través de tarjetas adaptables.
Modelo semántico de Power BI Define el modelo de datos, las relaciones y las medidas. Compilado con el informe en Power BI Desktop, pero existe como un elemento independiente en el servicio Power BI.
Informe de Power BI La interfaz de usuario en la que los usuarios ven proyectos, seleccionan nuevos estados y desencadenan actualizaciones a través de botones de función de datos.
Equipos de Microsoft Recibe las notificaciones de Tarjeta Adaptativa con cambios de estado y enlaces al informe.

Los datos fluyen en dos direcciones:

  • Ruta de lectura: Power BI lee datos de la base de datos SQL (a través de DirectQuery) o Lakehouse (a través de Direct Lake) para mostrar el estado actual del proyecto.
  • Ruta de escritura: Cuando un usuario selecciona un botón de función de datos, Power BI llama a la función de datos del usuario, que escribe en la base de datos SQL y publica en Teams.

Creación de una base de datos SQL

En este escenario se usan datos de seguimiento de proyectos. Siga los pasos descritos en Creación de una base de datos SQL en Fabric para crear una nueva base de datos SQL en el área de trabajo de Fabric.

Creación de tablas de base de datos

  1. En la base de datos SQL, abra una nueva ventana de consulta.

  2. Ejecute el siguiente script SQL para crear la tabla Project:

    CREATE TABLE [Project] (
        [Project id] INT NOT NULL,
        [Project name] NVARCHAR(200) NOT NULL,
        [Product name] NVARCHAR(200),
        [Description] NVARCHAR(4000),
        [Priority] NVARCHAR(20),
        [Start date] DATE,
        [Target end date] DATE,
        [Budget] DECIMAL(18,2),
        [Project manager] NVARCHAR(100),
        [Department] NVARCHAR(100),
        [Created date] DATETIME2,
        [Created by] NVARCHAR(100),
        [Is active] BIT,
        CONSTRAINT PK_Project PRIMARY KEY NONCLUSTERED ([Project id])
    );
    
  3. Cree la tabla Actualizaciones de estado para realizar un seguimiento de los cambios de estado a lo largo del tiempo:

    CREATE TABLE [Status updates] (
        [Update id] INT NOT NULL,
        [Project id] INT NOT NULL,
        [Status] NVARCHAR(50) NOT NULL,
        [Updated date] DATETIME2 NOT NULL,
        [Updated by] NVARCHAR(100) NOT NULL,
        [Notes] NVARCHAR(4000),
        CONSTRAINT PK_StatusUpdates PRIMARY KEY NONCLUSTERED ([Update id])
    );
    
  4. Cree una vista que devuelva el estado más reciente de cada proyecto:

    CREATE VIEW [Project status] AS
    SELECT 
        p.[Project id],
        p.[Project name],
        COALESCE(ls.[Latest status], 'Not Started') AS [Latest status],
        ls.[Latest notes]
    FROM [Project] p
    LEFT JOIN (
        SELECT 
            [Project id],
            [Status] AS [Latest status],
            [Notes] AS [Latest notes],
            ROW_NUMBER() OVER (PARTITION BY [Project id] ORDER BY [Update id] DESC) AS RowNum
        FROM [Status updates]
    ) ls ON p.[Project id] = ls.[Project id] AND ls.RowNum = 1;
    
  5. Insertar datos de proyecto de ejemplo:

    INSERT INTO [Project] ([Project id], [Project name], [Product name], [Description], [Priority], [Start date], [Target end date], [Budget], [Project manager], [Department], [Created date], [Created by], [Is active])
    VALUES
    (1, 'Best Practices with Power BI - FabCon Atlanta', 'FabCon Atlanta', 'Session covering Power BI best practices for enterprise deployments', 'High', '2026-01-15', '2026-03-20', 5000.00, 'person1@somecompany.com', 'Developer Relations', '2026-01-15', 'Admin', 1),
    (2, 'Translytical Task Flows - Build', 'Microsoft Build', 'Deep dive into translytical workloads and real-time analytics patterns', 'Critical', '2026-02-01', '2026-05-19', 7500.00, 'person2@somecompany.com', 'Product Engineering', '2026-02-01', 'Admin', 1),
    (3, 'Advanced DAX Patterns - FabCon Barcelona', 'FabCon Barcelona', 'Workshop on complex DAX calculations and optimization techniques', 'High', '2026-03-01', '2026-09-15', 6000.00, 'person1@somecompany.com', 'Developer Relations', '2026-02-20', 'Admin', 1),
    (4, 'Semantic Modeling Deep Dive - Ignite', 'Microsoft Ignite', 'Comprehensive session on semantic model design and best practices', 'High', '2026-01-10', '2026-11-18', 8000.00, 'person2@somecompany.com', 'Product Engineering', '2026-01-10', 'Admin', 1),
    (5, 'Custom Visuals in Power BI - FabCon Atlanta', 'FabCon Atlanta', 'Hands-on lab for building custom visuals with the Power BI SDK', 'Medium', '2025-12-01', '2026-03-20', 4500.00, 'person1@somecompany.com', 'Developer Relations', '2025-12-01', 'Admin', 1),
    (6, 'TMDL for Version Control - Build', 'Microsoft Build', 'Session on using TMDL for semantic model source control and CI/CD', 'Critical', '2025-11-15', '2026-02-15', 5500.00, 'person2@somecompany.com', 'Product Engineering', '2025-11-15', 'Admin', 1),
    (7, 'Real-time Analytics with Power BI - Ignite', 'Microsoft Ignite', 'Showcase of Direct Lake and real-time streaming capabilities', 'High', '2026-02-10', '2026-11-18', 7000.00, 'person1@somecompany.com', 'Developer Relations', '2026-02-10', 'Admin', 1),
    (8, 'Semantic Modeling Workshop - FabCon Barcelona', 'FabCon Barcelona', 'Interactive workshop on building enterprise-grade semantic models', 'High', '2026-04-01', '2026-09-15', 6500.00, 'person2@somecompany.com', 'Product Engineering', '2026-02-25', 'Admin', 1);
    
  6. Insertar actualizaciones de estado de ejemplo:

    INSERT INTO [Status updates] ([Update id], [Project id], [Status], [Updated date], [Updated by], [Notes])
    VALUES
    (1, 1, 'Not Started', '2026-01-15', 'person1@somecompany.com', 'Session abstract submitted and approved'),
    (2, 1, 'In Progress', '2026-01-25', 'person1@somecompany.com', 'Outline completed, starting slide deck'),
    (3, 1, 'In Progress', '2026-02-10', 'person1@somecompany.com', 'Demo environment setup in progress'),
    (4, 1, 'In Progress', '2026-02-25', 'person1@somecompany.com', 'First draft of presentation complete, scheduling dry run'),
    (5, 2, 'Not Started', '2026-02-01', 'person2@somecompany.com', 'Session proposal accepted for Build'),
    (6, 2, 'In Progress', '2026-02-08', 'person2@somecompany.com', 'Research phase - gathering customer scenarios'),
    (7, 2, 'In Progress', '2026-02-15', 'person2@somecompany.com', 'Architecture diagrams drafted'),
    (8, 2, 'In Progress', '2026-02-24', 'person2@somecompany.com', 'Building demo lakehouse environment'),
    (9, 3, 'Not Started', '2026-02-20', 'person1@somecompany.com', 'Call for speakers submission pending review'),
    (10, 4, 'Not Started', '2026-01-10', 'person2@somecompany.com', 'Initial brainstorming session with PM team'),
    (11, 4, 'In Progress', '2026-01-20', 'person2@somecompany.com', 'Content outline approved by leadership'),
    (12, 4, 'In Progress', '2026-02-05', 'person2@somecompany.com', 'Sample semantic models being developed'),
    (13, 5, 'Not Started', '2025-12-01', 'person1@somecompany.com', 'Lab environment requirements documented'),
    (14, 5, 'In Progress', '2025-12-15', 'person1@somecompany.com', 'SDK samples being prepared'),
    (15, 5, 'On Hold', '2026-01-10', 'person1@somecompany.com', 'Paused - waiting on SDK v5 release for new features'),
    (16, 6, 'Not Started', '2025-11-15', 'person2@somecompany.com', 'Session planning initiated'),
    (17, 6, 'In Progress', '2025-12-01', 'person2@somecompany.com', 'GitHub Actions workflow samples created'),
    (18, 6, 'In Progress', '2026-01-15', 'person2@somecompany.com', 'Dry run completed with internal team'),
    (19, 6, 'Completed', '2026-02-15', 'person2@somecompany.com', 'Session delivered at internal summit, ready for Build'),
    (20, 7, 'Not Started', '2026-02-10', 'person1@somecompany.com', 'Topic approved for Ignite breakout session'),
    (21, 7, 'In Progress', '2026-02-18', 'person1@somecompany.com', 'Eventstream demo scenarios identified'),
    (22, 7, 'In Progress', '2026-02-26', 'person1@somecompany.com', 'Direct Lake performance benchmarks in progress'),
    (23, 8, 'Not Started', '2026-02-25', 'person2@somecompany.com', 'Workshop format and duration confirmed');
    

Configuración de una biblioteca de variables

Una biblioteca de variables almacena los valores de configuración por separado del código de función. Esta separación proporciona una ventaja clave: puede actualizar valores como direcciones URL de webhook o vínculos de informe sin editar ni volver a publicar las funciones de datos de usuario.

Por ejemplo, si el canal de Teams cambia o necesita apuntar a un informe diferente, actualice el valor de la biblioteca de variables y el cambio surte efecto inmediatamente, no se requiere ningún cambio de código.

  1. En el Área de trabajo Fabric, seleccione + Nuevo elemento.

  2. Desplácese hacia abajo hasta la sección Desarrollar datos y seleccione Biblioteca de variables.

  3. Asigne un nombre a la biblioteca ProjectVariables de variables y seleccione Crear.

  4. Seleccione + Nueva variable y agregue las siguientes variables:

    Nombre de la variable Tipo Descripción
    TEAMS_WEBHOOK_URL String URL de webhook entrante de Teams
    POWERBI_REPORT_URL String Dirección URL al informe de Power BI (agregado después de la publicación)
  5. Seleccione Guardar después de agregar cada variable.

Obtener un URL de webhook de Teams

Siga los pasos descritos en Creación de un webhook entrante para crear un webhook para el canal de Teams. Después de crear el webhook, copie la dirección URL y agréguela a la biblioteca de variables como TEAMS_WEBHOOK_URL.

Importante

Cualquier persona con esta dirección URL puede publicar mensajes en el canal de Teams.

Creación de las funciones de datos de usuario

Cree un elemento de funciones de datos de usuario que controle las actualizaciones de estado y las notificaciones de Teams.

  1. En el área de trabajo de Fabric, seleccione + Nuevo elemento>Funciones de datos de usuario.

  2. Reemplace el código predeterminado por el código de Python siguiente:

    import fabric.functions as fn
    import logging
    from datetime import datetime
    
    udf = fn.UserDataFunctions()
    
    
    @udf.connection(argName="sqlDb", alias="ProjectTrackingDb")
    @udf.connection(argName="varLib", alias="ProjectVariables")
    @udf.function()
    def update_project_status(
        sqlDb: fn.FabricSqlConnection,
        varLib: fn.FabricVariablesClient,
        projectId: int,
        newStatus: str,
        updatedBy: str,
        notes: str,
        updatedDate: str
    ) -> str:
        """
        Updates the status of a project by inserting a new record 
        into the Status updates table and sends a Teams notification.
        """
        logging.info(f"Updating status for Project ID: {projectId}")
    
        # Parse and validate the date
        try:
            parsed_date = datetime.fromisoformat(updatedDate)
        except ValueError:
            raise fn.UserThrownError(
                f"Invalid date format. Use ISO format: '2026-02-27T14:30:00'",
                {"providedDate": updatedDate}
            )
    
        # Validate status value
        valid_statuses = ['Not Started', 'In Progress', 'On Hold', 'Completed', 'Cancelled']
        if newStatus not in valid_statuses:
            raise fn.UserThrownError(
                f"Invalid status. Must be one of: {', '.join(valid_statuses)}",
                {"providedStatus": newStatus}
            )
    
        connection = sqlDb.connect()
        cursor = connection.cursor()
    
        try:
            # Get the previous status
            cursor.execute("""
                SELECT TOP 1 [Status] 
                FROM [Status updates] 
                WHERE [Project id] = ? 
                ORDER BY [Update id] DESC
            """, (projectId,))
            prev_row = cursor.fetchone()
            previous_status = prev_row[0] if prev_row else "Not Started"
    
            # Get the next Update ID
            cursor.execute("SELECT ISNULL(MAX([Update id]), 0) + 1 FROM [Status updates]")
            next_update_id = cursor.fetchone()[0]
    
            # Verify the project exists
            cursor.execute("SELECT [Project name] FROM [Project] WHERE [Project id] = ?", (projectId,))
            project_row = cursor.fetchone()
    
            if not project_row:
                raise fn.UserThrownError(f"Project with ID {projectId} not found.")
    
            project_name = project_row[0]
    
            # Insert the new status update
            cursor.execute("""
                INSERT INTO [Status updates] 
                ([Update id], [Project id], [Status], [Updated date], [Updated by], [Notes])
                VALUES (?, ?, ?, ?, ?, ?)
            """, (next_update_id, projectId, newStatus, parsed_date, updatedBy, notes))
    
            connection.commit()
    
            # Send Teams notification
            _send_teams_update(varLib, project_name, previous_status, newStatus, updatedBy, notes)
    
            return f"Status updated for '{project_name}': {previous_status} → {newStatus}"
    
        except Exception as e:
            connection.rollback()
            raise
        finally:
            cursor.close()
            connection.close()
    
    
    def _send_teams_update(varLib, project_name, previous_status, new_status, updated_by, notes):
        """Helper function to send Teams notification."""
        import requests
        import json
    
        variables = varLib.getVariables()
        webhook_url = variables.get("TEAMS_WEBHOOK_URL")
        report_url = variables.get("POWERBI_REPORT_URL")
    
        if not webhook_url:
            return
    
        adaptive_card = {
            "type": "message",
            "attachments": [{
                "contentType": "application/vnd.microsoft.card.adaptive",
                "content": {
                    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
                    "type": "AdaptiveCard",
                    "version": "1.4",
                    "body": [
                        {
                            "type": "TextBlock",
                            "size": "Large",
                            "weight": "Bolder",
                            "text": "📋 Project Status Update"
                        },
                        {
                            "type": "FactSet",
                            "facts": [
                                {"title": "Project:", "value": project_name},
                                {"title": "Status:", "value": f"{previous_status} → {new_status}"},
                                {"title": "Updated By:", "value": updated_by}
                            ]
                        },
                        {
                            "type": "TextBlock",
                            "text": f"**Notes:** {notes}" if notes else "",
                            "wrap": True
                        }
                    ],
                    "actions": [
                        {"type": "Action.OpenUrl", "title": "View Project", "url": report_url}
                    ] if report_url else []
                }
            }]
        }
    
        requests.post(webhook_url, headers={"Content-Type": "application/json"}, 
                      data=json.dumps(adaptive_card), timeout=30)
    
    
    @udf.connection(argName="sqlDb", alias="ProjectTrackingDb")
    @udf.connection(argName="varLib", alias="ProjectVariables")
    @udf.function()
    def request_status_update(
        sqlDb: fn.FabricSqlConnection,
        varLib: fn.FabricVariablesClient,
        projectId: int,
        requestedBy: str,
        message: str
    ) -> str:
        """
        Sends a Teams notification requesting a status update for a project.
        """
        logging.info(f"Requesting status update for Project ID: {projectId}")
    
        connection = sqlDb.connect()
        cursor = connection.cursor()
    
        try:
            # Get project details
            cursor.execute("""
                SELECT [Project name], [Project manager] 
                FROM [Project] 
                WHERE [Project id] = ?
            """, (projectId,))
            project_row = cursor.fetchone()
    
            if not project_row:
                raise fn.UserThrownError(f"Project with ID {projectId} not found.")
    
            project_name = project_row[0]
            project_manager = project_row[1]
    
            # Get current status
            cursor.execute("""
                SELECT TOP 1 [Status], [Updated date]
                FROM [Status updates] 
                WHERE [Project id] = ? 
                ORDER BY [Update id] DESC
            """, (projectId,))
            status_row = cursor.fetchone()
            current_status = status_row[0] if status_row else "Not Started"
            last_updated = status_row[1].strftime("%Y-%m-%d") if status_row else "Never"
    
            # Send Teams notification
            _send_status_request(varLib, project_name, project_manager, 
                                current_status, last_updated, requestedBy, message)
    
            return f"Status update requested for '{project_name}' from {project_manager}"
    
        finally:
            cursor.close()
            connection.close()
    
    
    def _send_status_request(varLib, project_name, project_manager, current_status, 
                            last_updated, requested_by, message):
        """Helper function to send status update request via Teams."""
        import requests
        import json
    
        variables = varLib.getVariables()
        webhook_url = variables.get("TEAMS_WEBHOOK_URL")
        report_url = variables.get("POWERBI_REPORT_URL")
    
        if not webhook_url:
            return
    
        adaptive_card = {
            "type": "message",
            "attachments": [{
                "contentType": "application/vnd.microsoft.card.adaptive",
                "content": {
                    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
                    "type": "AdaptiveCard",
                    "version": "1.4",
                    "body": [
                        {
                            "type": "TextBlock",
                            "size": "Large",
                            "weight": "Bolder",
                            "text": "📢 Status Update Requested"
                        },
                        {
                            "type": "FactSet",
                            "facts": [
                                {"title": "Project:", "value": project_name},
                                {"title": "Owner:", "value": project_manager},
                                {"title": "Current Status:", "value": current_status},
                                {"title": "Last Updated:", "value": last_updated},
                                {"title": "Requested By:", "value": requested_by}
                            ]
                        },
                        {
                            "type": "TextBlock",
                            "text": f"**Message:** {message}" if message else "",
                            "wrap": True
                        }
                    ],
                    "actions": [
                        {"type": "Action.OpenUrl", "title": "Update Status", "url": report_url}
                    ] if report_url else []
                }
            }]
        }
    
        requests.post(webhook_url, headers={"Content-Type": "application/json"}, 
                      data=json.dumps(adaptive_card), timeout=30)
    
  3. Configure las conexiones:

    • Seleccione Configuración o el panel de conexiones.
    • Agregue una conexión ProjectTrackingDb que apunte a su base de datos SQL de Fabric.
    • Agregue una conexión ProjectVariables que apunte a la biblioteca de variables.
  4. Seleccione Publicar para implementar la función.

Nota:

Las funciones usadas con botones de función de datos de Power BI deben devolver una cadena (-> str). Power BI muestra este valor devuelto al usuario después de que se ejecute la función, proporcionando comentarios sobre el resultado de la acción.

Descripción de la función update_project_status

La update_project_status función escribe un nuevo registro de estado en la base de datos SQL y envía una notificación de Teams. Cuando un usuario selecciona el botón actualizar del informe, se produce el siguiente flujo:

Diagrama que muestra el flujo de datos al actualizar el estado del proyecto: Power BI llama a la función , que escribe en la base de datos SQL y envía una notificación de Teams.

  1. Power BI llama a la función: el botón de función de datos pasa parámetros (id. de proyecto, nuevo estado, notas, etc.) a la función de datos del usuario.

  2. Validar entradas : la función valida el formato de fecha y comprueba que el valor de estado es una de las opciones permitidas.

  3. Consultar el estado actual : la función recupera el estado anterior y el nombre del proyecto de la base de datos.

  4. Insertar nuevo registro : se inserta una nueva fila en la Status updates tabla con el nuevo estado, la marca de tiempo y las notas.

  5. Enviar notificación de Teams : la función _send_teams_update auxiliar publica una tarjeta adaptable en el canal de Teams que muestra el cambio de estado.

  6. Resultado devuelto : la función devuelve un mensaje correcto que Power BI muestra al usuario.

Descripción de la función request_status_update

La request_status_update función envía una notificación de Teams que pide al propietario de un proyecto que proporcione una actualización de estado. Esta función no escribe en la base de datos; solo envía un mensaje.

Diagrama que muestra el flujo de datos al solicitar una actualización de estado: Power BI llama a la función , que consulta los detalles del proyecto y envía una notificación de Teams.

  1. Power BI llama a la función - el botón de la función de datos pasa el identificador del proyecto, el nombre del solicitante y el mensaje a la función.

  2. Consultar los detalles del proyecto : la función recupera el nombre del proyecto, el administrador de proyectos y el estado actual de la base de datos.

  3. Enviar notificación de Teams : la función _send_status_request auxiliar publica una tarjeta adaptable en el canal de Teams con los detalles de la solicitud y un botón Actualizar estado del proyecto que vincula al informe.

  4. Resultado devuelto : la función devuelve un mensaje de confirmación que Power BI muestra al usuario.

(Opcional) Configurar accesos directos de Lakehouse para vistas de Direct Lake

Fabric SQL Database almacena todos los datos como tablas delta en OneLake, por lo que puede crear un modelo semántico de Direct Lake directamente en las tablas de base de datos SQL. Sin embargo, Direct Lake no puede leer vistas de una base de datos SQL, solo tablas. Para usar una vista con Direct Lake, cree accesos directos a las tablas de base de datos SQL en una instancia de Lakehouse y, a continuación, defina la vista allí.

Creación de accesos directos a las tablas de SQL Database

  1. En el área de trabajo de Fabric, cree un nuevo Lakehouse y active los esquemas.

  2. En el Explorador de Lakehouse, haga clic con el botón derecho en cualquier esquema (como dbo) y seleccione Nuevo acceso directo de tabla.

  3. En el catálogo de OneLake, vaya a la base de datos SQL y seleccione la Project tabla.

  4. Repita esta operación para crear un acceso directo para la Status updates tabla.

Los accesos directos proporcionan acceso de lectura a las tablas Delta subyacentes sin duplicar los datos.

Captura de pantalla que muestra las opciones de Lakehouse para agregar accesos directos y vistas de lago materializadas.

Creación de una vista de lago materializada

Cree una vista de lago materializada en Lakehouse que calcule el estado más reciente para cada proyecto:

  1. En Lakehouse, seleccione Administrar vistas materializadas del lago (versión preliminar).

  2. Abra un nuevo cuaderno con Spark SQL.

  3. Ejecute la siguiente consulta:

    CREATE MATERIALIZED LAKE VIEW IF NOT EXISTS dbo.project_status AS
    SELECT 
        p.`Project id` AS ProjectId,
        p.`Project name` AS ProjectName,
        COALESCE(ls.LatestStatus, 'Not Started') AS LatestStatus,
        ls.LatestNotes
    FROM dbo.Project p
    LEFT JOIN (
        SELECT 
            `Project id` AS ProjectId,
            `Status` AS LatestStatus,
            `Notes` AS LatestNotes,
            ROW_NUMBER() OVER (PARTITION BY `Project id` ORDER BY `Update id` DESC) AS RowNum
        FROM dbo.`Status updates`
    ) ls ON p.`Project id` = ls.ProjectId AND ls.RowNum = 1;
    
  4. Programe la actualización de la vista seleccionando Programaciones>Activado y estableciendo la frecuencia.

Captura de pantalla que muestra la programación de la vista materializada del lago y las opciones de creación.

Nota:

La base de datos SQL sigue siendo el destino de escritura para las funciones de datos de usuario. Los accesos directos de Lakehouse proporcionan acceso de solo lectura para el análisis a través de la vista materializada del lago.

Creación del informe de Power BI

Puede conectarse a los datos mediante DirectQuery o Direct Lake:

  • DirectQuery a SQL Database: los datos en tiempo real admiten la escritura diferida a través de funciones de datos de usuario.
  • Tablas de Direct Lake a SQL Database: Fabric SQL Database almacena datos como tablas delta en OneLake, por lo que Direct Lake puede leer tablas directamente.
  • Direct Lake vía Lakehouse (para vistas): Direct Lake no puede leer vistas desde una base de datos SQL. Para usar vistas con Direct Lake, cree accesos directos a las tablas de base de datos SQL en una instancia de Lakehouse y, a continuación, defina las vistas materializadas del lago allí.

Sugerencia

También se puede usar el modo de importación: no hay ninguna limitación en el modo de almacenamiento. Con Import, el modelo semántico debe actualizarse antes de que aparezcan los valores actualizados en el informe.

Opción A: Conectarse a través de DirectQuery

  1. Abra Power BI Escritorio.

  2. Seleccione Catálogo de OneLake.

  3. Busque la base de datos SQL de Fabric.

  4. Seleccione Conectar al punto de conexión de SQL Analytics.

  5. Seleccione las tablas Project, Status updates, y la vista Project status.

  6. Cuando se le solicite el modo de almacenamiento, seleccione DirectQuery.

Captura de pantalla que muestra el modelo semántico de DirectQuery en Power BI.

Opción B: Conexión a través de Direct Lake (para el rendimiento de análisis)

  1. En el servicio Power BI, seleccione Crear>catálogo de OneLake.

  2. Encuentra tu Lakehouse.

  3. Seleccione las tablas de atajos (Project, Status updates) y la vista materializada del lago (project_status).

  4. Edite el modelo semántico en la experiencia de modelado web para agregar medidas y relaciones.

Nota:

Con Direct Lake, los nombres de columna de la vista de lago materializado no tienen espacios (por ejemplo, ProjectId en lugar de Project id). Cambie el nombre de las columnas del modelo semántico para que coincidan con las medidas.

Captura de pantalla que muestra el modelo semántico de Direct Lake en Power BI.

Cree la tabla calculada de Opciones de estado

Cree una tabla calculada que proporcione los valores de estado para el segmentador de botones. Ejecute este script TMDL en Power BI Desktop:

createOrReplace

	table 'Status Options'

		column Status
			summarizeBy: none
			isNameInferred
			sourceColumn: [Status]
			sortByColumn: 'Sort Order'

		column Description
			summarizeBy: none
			isNameInferred
			sourceColumn: [Description]

		column 'Sort Order'
			isHidden
			formatString: 0
			summarizeBy: sum
			isNameInferred
			sourceColumn: [Sort Order]

		column 'Status Color'
			summarizeBy: none
			isNameInferred
			sourceColumn: [Status Color]

		partition 'Status Options' = calculated
			mode: import
			source =
				DATATABLE(
				    "Status", STRING,
				    "Description", STRING,
				    "Sort Order", INTEGER,
				    "Status Color", STRING,
				    {
				        { "Not Started", "Project has been created but work has not begun", 1, "#808080" },
				        { "In Progress", "Active work is being performed on the project", 2, "#0078D4" },
				        { "On Hold", "Project is paused pending resources, decisions, or dependencies", 3, "#FFB900" },
				        { "Completed", "All project deliverables have been finished", 4, "#107C10" },
				        { "Cancelled", "Project has been terminated and will not be completed", 5, "#D13438" }
				    }
				)

Creación de medidas auxiliares

Cree una tabla calculada para contener las medidas que respaldan los botones funcionales de datos. Ejecute este script TMDL en Power BI Desktop:

createOrReplace

	table 'Translytical task flow'

		/// Generates a preview of the Teams notification that will be sent when the user updates the status. Shows a warning if required selections are missing.
		measure 'Preview of status update' = ```
				VAR _ProjectId = SELECTEDVALUE(Project[Project id], 0)
				VAR _ProjectName = SELECTEDVALUE(Project[Project name], "")
				VAR _PreviousStatus = [Latest Status]
				VAR _NewStatus = SELECTEDVALUE('Status Options'[Status], "N/A")
				VAR _UpdatedBy = [Updated by]
				VAR _UpdatedDate = FORMAT(NOW(), "YYYY-MM-DD HH:mm")
				VAR _NL = UNICHAR(10)
				RETURN 
				IF(_ProjectId = 0 || _NewStatus = "N/A",
				    "⚠️ Select a project and new status to preview",
				    "📋 Teams Notification Preview" & _NL &
				    "━━━━━━━━━━━━━━━━━━━━" & _NL &
				    "Project: " & _ProjectName & _NL &
				    "Status: " & _PreviousStatus & " → " & _NewStatus & _NL &
				    "Updated By: " & _UpdatedBy & _NL &
				    "Date: " & _UpdatedDate & _NL &
				    "Notes: See above" & _NL &
				    "━━━━━━━━━━━━━━━━━━━━" & _NL &
				    "📨 This will be sent to Teams"
				)
				```

		/// Returns the email address of the current user. Used to track who made each status update.
		measure 'Updated by' = USERPRINCIPALNAME()

		/// Returns the most recent notes for the selected project. Only evaluates when a project is in scope.
		measure 'Latest notes' =
				IF(ISINSCOPE(Project[Project name]),
				LASTNONBLANKVALUE('Status updates'[Update id], MAX('Status updates'[Notes])),
				BLANK())

		/// Returns the most recent status for the selected project by finding the last non-blank status value.
		measure 'Latest status' =
				IF(HASONEVALUE(Project[Project id]),
				LASTNONBLANKVALUE('Status updates'[Update id], MAX('Status updates'[Status])),
				BLANK())

		/// Returns the Project ID when a single project is selected. Used as a parameter for the update_project_status and request_status_update functions.
		measure 'Selected project id' = SELECTEDVALUE(Project[Project id])
			formatString: 0

		/// Returns today's date in ISO format. Used as the timestamp for status updates.
		measure 'Updated date' = FORMAT(TODAY(), "yyyy-mm-dd")

		/// Provides dynamic text for the update button showing the selected project and new status.
		measure 'Update status button text' = "Update the status of " & SELECTEDVALUE(Project[Project name]) & " to " & SELECTEDVALUE('Status Options'[Status])

		column Value
			isHidden
			formatString: 0
			summarizeBy: sum
			isNameInferred
			sourceColumn: [Value]

		partition 'Translytical task flow' = calculated
			mode: import
			source = {1}

Nota:

Este script crea la Translytical task flow tabla con una columna oculta. Ocultar todas las columnas la convierte en una tabla de medida, que muestra un icono especial y siempre aparece en la parte superior del panel Datos para facilitar el acceso.

Estas medidas sirven para varios propósitos:

Medida propósito
Selected project id Captura el identificador de proyecto cuando se selecciona una sola fila de proyecto. Se pasa como parámetro a las funciones de datos de usuario.
Updated by Devuelve el correo electrónico del usuario actual a través de USERPRINCIPALNAME(). Realiza un seguimiento de quién realizó cada actualización de estado.
Updated date Devuelve la fecha de hoy en formato ISO (yyyy-mm-dd) para el parámetro timestamp de la función.
Update status button text Proporciona el etiquetado de botón dinámico que muestra el proyecto seleccionado y el nuevo estado (por ejemplo, "Actualizar el estado de Sesión ABC a En curso").
Latest status Muestra el estado más reciente de un proyecto mediante LASTNONBLANKVALUE para buscar la última entrada en la tabla Actualizaciones de estado.
Latest notes Muestra las notas más recientes de un proyecto. Solo se evalúa cuando un proyecto específico está dentro del alcance.
Preview of status update Genera una vista previa de la notificación de Teams antes de enviar, lo que ayuda a los usuarios a confirmar sus cambios. Muestra una advertencia si faltan selecciones.

Diseño del informe

El diseño del informe guía a los usuarios a través de un flujo de trabajo claro: seleccione un proyecto, elija un nuevo estado, agregue notas y, a continuación, ejecute la actualización.

Captura de pantalla que muestra el diseño completo del informe de Power BI con la tabla del proyecto, la segmentación de estado, la entrada de notas y los botones de acción.

Creación de la tabla del proyecto

  1. Agregue un objeto visual Table para mostrar la información del proyecto.

  2. Agregue estas columnas de los datos:

    • Product name
    • Project name
    • Target end date
    • Description
    • Latest status (en la tabla/vista Estado o Estado del proyecto)
    • Latest notes
  3. Establezca el título en 1) Elija un proyecto que se va a actualizar.

  4. Ordene por fecha de finalización de destino ascendente para mostrar primero las próximas fechas límite.

Crear el filtro de botones para la selección de estado

  1. Agregue un visual Button slicer.

  2. En el campo Valores , agregue Status Options[Status].

  3. En el campo Etiqueta , agregue FIRST(Status Options[Description]) para mostrar la descripción debajo de cada estado.

  4. En el panel Formato :

    • Establezca Estilo en Tarjetas.
    • Establezca Orientación en Horizontal.
    • Establezca Máximo de iconos en 5 (uno para cada estado).
  5. Configura el formato condicional para colorear cada tarjeta por el campo Status Color.

  6. Establezca el título en 2) Elija un nuevo estado.

Agregar segmentaciones de entrada para notas

  1. Agregue un control de entrada para que los usuarios escriban notas sobre la actualización de estado.

  2. Establezca el título en 3) Agregue notas para esta actualización de estado.

  3. Agregue otro selector de entrada para el campo de mensaje utilizado por el botón de actualización de estado de la solicitud.

  4. Establezca el título como o bien envíe un mensaje al canal de Teams.

Sugerencia

Asigne a cada segmentación de entrada un título que sea descriptivo. Al configurar un botón de función de datos, los filtros aparecen en la lista desplegable de parámetros por su título, lo que facilita la identificación del correcto. Después de la configuración, puede ocultar el título en el lienzo del informe si es necesario.

Adición de la tabla de vista previa

  1. Agregue un objeto visual Table con una sola columna: la [Preview of status update] medida.

  2. Establezca el título en Versión preliminar de la actualización.

Esto muestra a los usuarios el aspecto que tendrá su notificación de Teams antes de enviarlo.

Añadir los botones de función de datos

Agregue dos botones: uno para actualizar el estado y otro para solicitar una actualización de estado.

Botón Actualizar estado

  1. En la pestaña Insertar, seleccione Botón>Función de datos.

  2. En el panel Formato , configure el texto del botón:

    • Establezca Texto predeterminado como su [Update status button text] medida para el etiquetado dinámico.
    • Establezca Texto deshabilitado en texto estático como "Elige un proyecto, elige un nuevo estado y agrega notas primero".
  3. Seleccione su función publicada update_project_status.

  4. Mapear los parámetros de la función:

    Parámetro Tipo de enlace Vinculado a
    projectId Medida [Selected project id] medida
    newStatus Cortadora Objeto visual de segmentación de botones (habilitado para borrar automáticamente)
    updatedBy Medida [Updated by] medida
    notes Cortadora Visualización de segmentador de entrada (borrado automático habilitado)
    updatedDate Medida [Updated date] medida
  5. En el panel Formato en Acción, habilite Actualizar el informe después de un resultado correcto. Esta configuración actualiza automáticamente la página del informe después de que la función se ejecute correctamente.

    Sugerencia

    Habilite Auto-borrado para los parámetros del slicer de manera que el slicer de botones y el texto de las notas se reinicien después de que el usuario desencadene la función.

Nota:

El botón Actualizar el informe después de un resultado correcto solo actualiza la página del informe cuando la función se ejecuta correctamente. En el caso de los modos de almacenamiento de DirectQuery y Direct Lake, la página actualizada muestra los datos actualizados inmediatamente. Para el modo de importación, el modelo semántico se debe actualizar por separado antes de que aparezcan los valores actualizados en el informe.

Captura de pantalla que muestra el botón actualizar el estado del proyecto en el informe de Power BI.

Botón de actualización de estado de la solicitud

  1. Agregue otra Button>función de datos.

  2. En el panel Formato , configure el texto del botón:

    • Establezca Texto predeterminado en texto estático como "Enviar mensaje de Teams al canal".
    • Establezca Texto deshabilitado en "Elegir un proyecto y escriba primero un mensaje".
  3. Seleccione su función publicada request_status_update.

  4. Mapear los parámetros de la función:

    Parámetro Tipo de enlace Vinculado a
    projectId Medida [Selected project id] medida
    requestedBy Medida [Updated by] medida
    message Cortadora Visualización de segmentador de entrada (borrado automático habilitado)
  5. Opcionalmente, habilite Actualizar el informe después de un resultado correcto en el panel Formato en Acción.

Captura de pantalla que muestra el botón enviar mensaje de Teams en el informe de Power BI.

Configuración del texto del botón dinámico

Use texto dinámico en los botones de función de datos para mostrar a los usuarios exactamente qué acción se producirá cuando seleccionen el botón. En lugar de una etiqueta genérica como "Actualizar", el botón puede mostrar texto específico del contexto, como "Actualizar el estado de Sesión ABC a En curso".

Para configurar el texto del botón dinámico:

  1. Cree una medida que genere la etiqueta del botón. Por ejemplo, esta medida combina el nombre del proyecto seleccionado y el nuevo estado:

    Update status button text = 
        "Update the status of " & SELECTEDVALUE(Project[Project name]) & " to " & SELECTEDVALUE('Status Options'[Status])
    
  2. En el panel Formato del botón de función de datos, expanda Botón>Texto

  3. Establezca Texto predeterminado para la medida dinámica ([Update status button text]).

  4. Establezca Deshabilitar texto como texto estático que informe a los usuarios sobre las selecciones requeridas (por ejemplo, "Elija un proyecto, seleccione el nuevo estado y añada notas primero").

El botón muestra el texto deshabilitado hasta que todos los parámetros necesarios tengan valores. Una vez que el usuario realiza sus selecciones, el botón muestra el texto dinámico que describe la acción específica.

Captura de pantalla que muestra el panel de formato de botón con configuración de texto dinámico mediante una medida para el texto predeterminado y el texto estático para el estado deshabilitado.

(Opcional) Agregar un botón y una página de perforación

Puede agregar una página de desglose para mostrar el historial completo de actualizaciones del estado para un proyecto seleccionado.

  1. En la pestaña Insertar, seleccione Botón>Blank

  2. En el panel Formato , en Botón, establezca el texto:

    • Texto predeterminado: "Ver todas las actualizaciones de estado"
    • Texto deshabilitado: "Elegir un proyecto para ver todas las actualizaciones de estado"
  3. En Acción, habilite la acción y establezca:

    • Tipo: Obtención de detalles
    • Destino: seleccione la página del historial de estado (creada en los pasos siguientes)
  4. Agregue una nueva página y asígnele el nombre Historial de actualizaciones de estado.

  5. En el panel Formato de la página, expanda Información de la página y habilite Drillthrough. Agregue Project[Product name] como campo de exploración detallada.

  6. Agregue objetos visuales para mostrar el historial de estado:

    • Tarjeta: recuento total de actualizaciones de estado
    • Rebanadora de botones: Desglose según el estado
    • Tabla: Todas las actualizaciones de estado (Id. de actualización, Fecha actualizada, Estado, Notas, Actualizada por)
    • Gráfico de líneas: actualización de la actividad a lo largo del tiempo
  7. Agregue un botón Atrás para que los usuarios puedan volver a la página principal del informe. En la pestaña Insertar , seleccione Botón>Atrás.

Publicación del informe

  1. Guarde el informe y publíquelo en el servicio Power BI.

  2. Copie la dirección URL del informe y agréguela a la biblioteca de variables como POWERBI_REPORT_URL.

Prueba del flujo de trabajo

Prueba del flujo de actualización del estado de la solicitud

Una vez publicado, puede usar el flujo de tareas translítico para solicitar una actualización de estado:

Captura de pantalla que muestra los pasos numerados para solicitar una actualización de estado: 1) seleccionar un proyecto, 2) escribir un mensaje, 3) seleccionar Enviar mensaje de teams al canal, 4) ver confirmación, 5) La notificación de Teams aparece con el botón Actualizar estado del proyecto.

  1. Elegir un proyecto para actualizar : seleccione una fila de proyecto en la tabla para establecer el contexto de filtro.

  2. O bien, envíe un mensaje al canal de Teams, escriba un mensaje en el cuadro de entrada (por ejemplo, "¿Podemos obtener una actualización de esto?").

  3. Seleccione el botón Enviar mensaje al canal de Teams.

  4. Aparece una confirmación de solicitud enviada cuando la acción se completa correctamente.

  5. Compruebe el canal de Teams para ver la tarjeta adaptable de actualización de estado del proyecto con los detalles de la solicitud.

  6. El propietario del proyecto puede seleccionar Actualizar estado del proyecto en la tarjeta adaptable para abrir el informe y actualizar su estado.

Captura de pantalla que muestra la notificación de la Tarjeta Adaptativa en Teams, solicitando una actualización de estado mediante el botón Actualizar estado del proyecto.

Prueba del flujo de estado de actualización

Una vez publicado, puede usar el flujo de tareas translítico para actualizar un estado del proyecto:

Captura de pantalla que muestra los pasos numerados para actualizar un estado del proyecto: 1) seleccionar un proyecto, 2) elegir un estado, 3) agregar notas, 4) seleccionar Actualizar, 5) ver confirmación, 6) Notificación de Teams aparece.

  1. Elegir un proyecto para actualizar : seleccione una fila de proyecto en la tabla para establecer el contexto de filtro.

  2. ¿Cuál es el nuevo estado? - Use el filtro de botones para seleccionar un nuevo estado (por ejemplo, En curso).

  3. Agregar notas para esta actualización de estado: escriba notas en el control de entrada (por ejemplo, "Empezó a grabar la demostración").

  4. Seleccione el botón Actualizar para escribir el cambio de estado en lakehouse y enviar una notificación de Teams.

  5. Aparece una confirmación de solicitud enviada cuando la acción se completa correctamente.

  6. Compruebe el canal de Teams para ver la tarjeta adaptable de actualización de estado del proyecto con los detalles del cambio de estado.

Captura de pantalla que muestra la notificación de tarjeta adaptable en Teams después de una actualización de estado.

Flujos de tareas translíticos

Visualizaciones del informe

Funciones DAX

Datos de tejido

Equipos de Microsoft