Del via


Tutorial: Opret en workflow-opdatering for statusopdateringer

I denne ende-til-ende vejledning opretter du et translytisk opgaveflow, der sporer projektstatus og poster opdateringer fra en Power BI-rapport til Microsoft Teams. Denne vejledning demonstrerer, hvordan man kombinerer data-write-back med eksterne API-kald for at skabe en komplet kommunikationsarbejdsgang.

I dette selvstudium lærer du, hvordan du:

  • Opret en SQL-database i Fabric med projekt- og status-tracking-tabeller.
  • Opsæt et variabelt bibliotek til at gemme konfigurationen separat.
  • Konfigurer brugerdatafunktioner, der opdaterer status, anmoder om opdateringer og sender Teams-notifikationer.
  • Eventuelt kan du opsætte Lakehouse-genveje med materialiserede søudsigter for direkte søudsigt.
  • Integrér brugerdatafunktioner med en Power BI-rapport ved hjælp af datafunktionsknapper.

Hvis du ikke har en eksisterende Fabric-kapacitet, kan du starte en Fabric-prøveversion.

Forudsætninger

  • Power BI Desktop. Hvis du ikke har Power BI Desktop installeret på din enhed, skal du følge vejledningen i Hent Power BI Desktop.
  • En Microsoft Teams-kanal, hvor du har tilladelse til at tilføje indkommende webhooks.

Oversigt

Denne vejledning skaber en projektsporingsløsning, hvor brugere kan opdatere projektstatus direkte fra en Power BI-rapport. Når en bruger opdaterer en status, gør systemet:

  1. Skriver den nye status til SQL-databasen.
  2. Sender en adaptiv kortnotifikation til Microsoft Teams.
  3. Opdaterer rapporten for at vise de opdaterede data.

Brugerflow

Arbejdsgangen skaber en kontinuerlig feedback-loop mellem rapportbrugere:

  1. Anmod om opdatering via Teams fra rapporten — En bruger vælger et projekt i rapporten og sender en statusopdateringsanmodning. Anmodningen postes i Teams med et link tilbage til rapporten.

  2. Modtag notifikation i Teams og åbn rapport — Projektejeren ser notifikationen i Teams og vælger linket for at åbne rapporten.

  3. Opdater status i rapporten — Projektejeren vælger projektet, vælger en ny status, tilføjer noter og vælger opdateringsknappen.

  4. Se opdatering i realtid og send notifikation — Rapporten opdateres straks for at vise den nye status, og en notifikation postes i Teams, der bekræfter ændringen.

Arkitektur

Løsningen forbinder disse komponenter inden for Microsoft Fabric:

Komponent Formål
Fabric SQL Database Lagres projekt- og statusopdateringsposter. Indeholder tabellen Project , Status updates tabellen og Project status visningen.
Lakehouse (valgfrit) Giver genveje til SQL-databasetabellerne for Direct Lake-visninger. Brug den, når du har brug for materialiserede søudsigter til analyse.
Variabelbibliotek Gemmer konfigurationsværdier som Teams webhook URL og rapport-URL. Opdater værdier uden at genudgive funktioner.
Funktioner til brugerdata Python-funktioner, der håndterer tilbageskrivning til SQL og sender Teams-notifikationer via adaptive kort.
Power BI Semantisk Model Definerer datamodellen, relationer og målinger. Bygget med rapporten i Power BI Desktop, men eksisterer som et separat element i Power BI-tjenesten.
Power BI Rapport Brugergrænsefladen, hvor brugere ser projekter, vælger nye statusser og udløser opdateringer via datafunktionsknapper.
Microsoft Teams Modtager adaptive kort-notifikationer med statusændringer og links tilbage til rapporten.

Dataene flyder i to retninger:

  • Læs sti: Power BI læser fra SQL-databasen (via DirectQuery) eller Lakehouse (via Direct Lake) for at vise den aktuelle projektstatus.
  • Skrivesti: Når en bruger vælger en datafunktionsknap, kalder Power BI brugerens datafunktion, som skriver til SQL-databasen og poster i Teams.

Opret en SQL-database

Dette scenarie bruger projektsporingsdata. Følg trinene i Opret en SQL-database i Fabric for at oprette en ny SQL-database i dit Fabric-arbejdsområde.

Opret databasetabellerne

  1. I din SQL-database skal du åbne et nyt forespørgselsvindue.

  2. Kør følgende SQL-script for at oprette projekttabellen:

    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. Opret tabellen Statusopdateringer for at spore statusændringer over tid:

    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. Opret en visning, der returnerer den seneste status for hvert projekt:

    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. Indsæt eksempler på projektdata:

    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. Indsæt eksempler på statusopdateringer:

    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');
    

Opsæt et variabelbibliotek

Et variabelt bibliotek gemmer konfigurationsværdier separat fra din funktionskode. Denne adskillelse giver en vigtig fordel: du kan opdatere værdier som webhook-URL'er eller rapportlinks uden at redigere eller genudgive dine brugerdatafunktioner.

For eksempel, hvis din Teams-kanal ændres, eller du skal pege på en anden rapport, opdater værdien af variabelbiblioteket, og ændringen træder straks i kraft – ingen kodeændringer nødvendige.

  1. I dit Fabric-arbejdsområde vælger du + Nyt element.

  2. Rul ned til sektionen Udvikl data , og vælg Variabelbibliotek.

  3. Navngiv variabelbiblioteket ProjectVariables og vælg Opret dem.

  4. Vælg + Ny variabel og tilføj følgende variable:

    Variabelt navn Type Beskrivelse
    TEAMS_WEBHOOK_URL String Din Teams indkommende webhook-URL
    POWERBI_REPORT_URL String URL til din Power BI-rapport (tilføjet efter offentliggørelse)
  5. Vælg Save efter at have tilføjet hver variabel.

Få en Teams webhook URL

Følg trinene i Opret en indkommende webhook for at oprette en webhook til din Teams-kanal. Efter at have oprettet webhooken, kopier URL'en og tilføj den til dit variabelbibliotek som TEAMS_WEBHOOK_URL.

Vigtigt!

Alle med denne URL kan poste beskeder i din Teams-kanal.

Opret brugerdatafunktionerne

Opret et element med brugerdatafunktioner, der håndterer statusopdateringer og Teams-notifikationer.

  1. I dit Fabric-arbejdsområde vælger du + Nye elementer>Brugerdatafunktioner.

  2. Erstat standardkoden med følgende Python-kode:

    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. Konfigurér forbindelserne:

    • Vælg Indstillinger eller forbindelsespanelet.
    • Tilføj forbindelsespegel ProjectTrackingDb til din Fabric SQL-database.
    • Tilføj forbindelsespegning ProjectVariables til dit variabelbibliotek.
  4. Vælg Publicér for at udrulle funktionen.

Bemærkning

Funktioner, der bruges med Power BI data-funktionsknapper, skal returnere en streng (-> str). Power BI viser denne returværdi til brugeren efter funktionen udføres, hvilket giver feedback om handlingens resultat.

Forstå update_project_status funktion

Funktionen update_project_status skriver en ny statuspost til SQL-databasen og sender en Teams-notifikation. Når en bruger vælger opdateringsknappen i rapporten, sker følgende flow:

Diagram, der viser dataflowet ved opdatering af projektstatus: Power BI kalder funktionen, som skriver til SQL-databasen og sender en Teams-notifikation.

  1. Power BI kalder funktionen - Datafunktionsknappen sender parametre (projekt-ID, ny status, noter osv.) til brugerdatafunktionen.

  2. Valider input - Funktionen validerer datoformatet og tjekker, at statusværdien er en af de tilladte muligheder.

  3. Forespørg aktiel tilstand - Funktionen henter den tidligere status og projektnavn fra databasen.

  4. Indsæt ny post - En ny række indsættes Status updates i tabellen med den nye status, tidsstempel og noter.

  5. Send Teams-notifikation – Hjælpefunktionen _send_teams_update poster et Adaptivt Kort på din Teams-kanal, der viser statusændringen.

  6. Returner resultat - Funktionen returnerer en succesbesked, som Power BI viser brugeren.

Forstå request_status_update funktionen

Funktionen request_status_update sender en Teams-notifikation, hvor en projektejer bliver bedt om at give en statusopdatering. Denne funktion skriver ikke til databasen – den sender kun en besked.

Diagram viser dataflowet, når der anmodes om statusopdatering: Power BI kalder funktionen, som forespørger projektdetaljer og sender en Teams-notifikation.

  1. Power BI kalder funktionen - Datafunktionsknappen sender projekt-ID, anmodningsnavn og besked til funktionen.

  2. Forespørg projektdetaljer - Funktionen henter projektnavn, projektleder og nuværende status fra databasen.

  3. Send Teams-notifikation - Hjælpefunktionen _send_status_request poster et Adaptivt Kort til din Teams-kanal med anmodningsdetaljer og en knap til at opdatere projektstatus , der linker tilbage til rapporten.

  4. Returneringsresultat - Funktionen returnerer en bekræftelsesmeddelelse, som Power BI viser brugeren.

(Valgfrit) Sæt genveje i Lakehouse op til direkte søudsigt

Fabric SQL Database gemmer alle data som Delta-tabeller i OneLake, så du kan oprette en Direct Lake semantisk model direkte på SQL-databasetabellerne. Dog kan Direct Lake ikke læse visninger fra en SQL-database—kun tabeller. For at bruge en visning med Direct Lake, lav genveje til SQL-databasetabellerne i et Lakehouse, og definer derefter visningen der.

Opret genveje til SQL-databasetabellerne

  1. Opret et nyt Lakehouse i dit Fabric-arbejdsområde og aktiver skemaer.

  2. I Lakehouse Explorer højreklikker du på et skema (såsom dbo) og vælger genvej til Ny tabel.

  3. I OneLake-kataloget skal du gå til din SQL-database og vælge tabellen Project .

  4. Gentag for at lave en genvej til tabellen Status updates .

Genvejene giver læseadgang til de underliggende Delta-tabeller uden at duplikere data.

Skærmbillede, der viser Lakehouse-mulighederne for at tilføje genveje og materialiserede søudsigter.

Oprette en materialiseret søvisning

Opret et materialiseret søbillede i Lakehouse, der beregner den seneste status for hvert projekt:

  1. I Lakehouse vælger du Administrer materialiserede søudsigter (forhåndsvisning).

  2. Åbn en ny notesbog med Spark SQL.

  3. Kør følgende forespørgsel:

    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. Planlæg visningsopdateringen ved at vælge Schedules>On og indstille frekvensen.

Skærmbillede, der viser den materialiserede søvisning, plan og oprettelsesmuligheder.

Bemærkning

SQL-databasen forbliver skrivemålet for brugerdatafunktioner. Lakehouse-genvejene giver skrivebeskyttet adgang til analyser via det materialiserede søsyn.

Opret Power BI-rapporten

Du kan forbinde til dine data ved enten DirectQuery eller Direct Lake:

  • DirectQuery til SQL-database: Realtidsdata understøtter write-back via brugerdatafunktioner.
  • Direct Lake til SQL Database-tabeller: Fabric SQL Database gemmer data som Delta-tabeller i OneLake, så Direct Lake kan læse tabeller direkte.
  • Direct Lake via Lakehouse (for udsigter): Direct Lake kan ikke læse visninger fra SQL Database. For at bruge visninger med Direct Lake, lav genveje til SQL-databasetabellerne i et Lakehouse, og definer derefter materialiserede søvisninger der.

Tips

Importtilstand kan også bruges—der er ingen begrænsning på lagertilstand. Med Import skal den semantiske model opdateres, før opdaterede værdier vises i rapporten.

Mulighed A: Forbind via DirectQuery

  1. Åbn Power BI Desktop.

  2. Vælg OneLake-kataloget.

  3. Find din Fabric SQL-database.

  4. Vælg Connect til SQL analytics endpoint.

  5. Vælg Project, Status updates, og Project status tabeller/visning.

  6. Når du bliver bedt om opbevaringstilstand, vælg DirectQuery.

Skærmbillede, der viser DirectQuerys semantiske model i Power BI.

Mulighed B: Forbind via Direct Lake (for analysepræstation)

  1. I Power BI-tjenesten vælger du Opret>OneLake-katalog.

  2. Find dit Lakehouse.

  3. Vælg genvejstabellerne (Project, Status updates) og den materialiserede søvisning (project_status).

  4. Rediger den semantiske model i webmodelleringsoplevelsen for at tilføje målinger og relationer.

Bemærkning

Med Direct Lake har kolonnenavne fra det materialiserede sø-view ikke mellemrum (for eksempel ProjectId i stedet for Project id). Omdøb kolonnerne i den semantiske model, så de matcher dine mål.

Skærmbillede, der viser Direct Lake semantiske model i Power BI.

Opret tabellen for beregnede Status Options

Opret en beregnet tabel, der giver statusværdierne for knap-sliceren. Kør dette TMDL-script i 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" }
				    }
				)

Skab støtteforanstaltninger

Opret en beregnet tabel til at indeholde de mål, der understøtter datafunktionsknapperne. Kør dette TMDL-script i 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}

Bemærkning

Dette script opretter Translytical task flow tabellen med en skjult kolonne. Skjul af alle kolonner konverterer den til en måltabel, som viser et specielt ikon og altid vises øverst i Datapanelet for nem adgang.

Disse tiltag tjener flere formål:

Måle Formål
Selected project id Fanger projekt-ID'et, når en enkelt projektrække vælges. Sendt som parameter til brugerdatafunktionerne.
Updated by Returnerer den nuværende brugers e-mail via USERPRINCIPALNAME(). Sporer, hvem der har foretaget hver statusopdatering.
Updated date Returnerer dagens dato i ISO-format (yyyy-mm-dd) for funktionstidsstempelparameteren.
Update status button text Giver dynamisk knapmærkning, der viser det valgte projekt og ny status (for eksempel "Opdater status for Session ABC til I Progress").
Latest status Viser den seneste status for et projekt ved LASTNONBLANKVALUE at finde den sidste post i tabellen Statusopdateringer.
Latest notes Viser de nyeste noter til et projekt. Vurderer kun, når et specifikt projekt er inden for scope.
Preview of status update Genererer en forhåndsvisning af Teams-notifikationen før afsendelse og hjælper brugerne med at bekræfte deres ændringer. Viser en advarsel, hvis der mangler valg.

Design rapporten

Rapportlayoutet guider brugerne gennem en klar arbejdsgang: vælg et projekt, vælg en ny status, tilføj noter, og udfør derefter opdateringen.

Skærmbillede, der viser hele Power BI-rapportdesignet med projekttabel, statusslicer, noteinput og handlingsknapper.

Opret projekttabellen

  1. Tilføj en tabel-visuel for at vise projektinformation.

  2. Tilføj disse kolonner fra dine data:

    • Product name
    • Project name
    • Target end date
    • Description
    • Latest status (fra statustabellen eller projektstatustabellen/visningen)
    • Latest notes
  3. Sæt titlen til 1) Vælg et projekt, der skal opdateres.

  4. Sortér efter Målslutdato stiger for at vise kommende deadlines først.

Opret knap-sliceren til statusvalg

  1. Tilføj en Button slicer-visuel .

  2. I feltet Værdier tilføjes Status Options[Status].

  3. I feltet Label tilføj FIRST(Status Options[Description]) for at vise beskrivelsen under hver status.

  4. I Format-panelet :

    • Set stilen til kortene.
    • Sæt orienteringen til horisontal.
    • Sæt maks tiles til 5 (én for hver status).
  5. Konfigurer betinget formatering til at farve hvert kort efter feltet Status Color .

  6. Sæt titlen til 2) Vælg en ny status.

Tilføj input-slicere til noter

  1. Tilføj en input-slicer, så brugerne kan indtaste noter om statusopdateringen.

  2. Sæt titlen til 3) Tilføj noter til denne statusopdatering.

  3. Tilføj en ekstra input-slicer til beskedfeltet, der bruges af knappen til opdatering af anmodningsstatus.

  4. Sæt titlen til Eller send en besked til teams-kanalen.

Tips

Giv hver input-slicer en beskrivende titel. Når du konfigurerer en datafunktionsknap, vises slicere i parameter-dropdown-menuen ved deres titel, hvilket gør det nemmere at identificere den rigtige. Efter konfiguration kan du skjule titlen på rapportlærredet, hvis det er nødvendigt.

Tilføj forhåndsvisningstabellen

  1. Tilføj et tabel-visuelt med en enkelt kolonne: målingen.[Preview of status update]

  2. Sæt titlen til Forhåndsvisningsopdatering.

Dette viser brugerne, hvordan deres Teams-notifikation vil se ud, før de sender den.

Tilføj datafunktionsknapperne

Tilføj to knapper: en til statusopdatering og en til at anmode om en statusopdatering.

Opdater statusknap

  1. I fanen Indsæt vælg funktionen Knapdata>.

  2. I Format-panelet konfigurerer du knapteksten:

    • Sæt standardtekst til dit [Update status button text] mål for dynamisk mærkning.
    • Sæt deaktiveret tekst til statisk tekst som "Vælg et projekt, ny status, og tilføj noter først".
  3. Vælg din udgivne update_project_status funktion.

  4. Kort funktionsparametrene:

    Parameter Bindingstype Bundet til
    projectId Måle [Selected project id] Mål
    newStatus Udsnitsfilter Button slicer-visuel (auto-clear aktiveret)
    updatedBy Måle [Updated by] Mål
    notes Udsnitsfilter Input slicer visual (auto-clear aktiveret)
    updatedDate Måle [Updated date] Mål
  5. I Format-panelet under Handling, aktiver Opdater rapporten efter succesfuldt resultat. Denne indstilling opdaterer automatisk rapportsiden, efter funktionen er udført korrekt.

    Tips

    Aktivér Auto-clear for slicer-parametre, så knap-sliceren og noteteksten nulstilles efter brugeren har aktiveret funktionen.

Bemærkning

Viskoen 'Opdater rapporten efter succesfuldt resultat' opdaterer kun rapportsiden, når funktionen kører succesfuldt. For DirectQuery- og Direct Lake-lagringstilstande viser den opdaterede side opdaterede data med det samme. For importtilstand skal den semantiske model opdateres separat, før de opdaterede værdier vises i rapporten.

Skærmbillede, der viser knappen 'opdater projektstatus' i Power BI-rapporten.

Anmodning om statusopdateringsknap

  1. Tilføj endnu en funktion til Knapdata>.

  2. I Format-panelet konfigurerer du knapteksten:

    • Sæt standardtekst til statisk tekst som "Send Teams-besked til kanal".
    • Sæt Disabled text til "Vælg et projekt og skriv en besked først".
  3. Vælg din udgivne request_status_update funktion.

  4. Kort funktionsparametrene:

    Parameter Bindingstype Bundet til
    projectId Måle [Selected project id] Mål
    requestedBy Måle [Updated by] Mål
    message Udsnitsfilter Input slicer visual (auto-clear aktiveret)
  5. Aktivér eventuelt Opdater rapporten efter et vellykket resultat i Format-panelet under Handling.

Skærmbillede, der viser knappen send Teams-besked i Power BI-rapporten.

Konfigurer dynamisk knaptekst

Brug dynamisk tekst på dine datafunktionsknapper for at vise brugerne præcis, hvilken handling der vil ske, når de vælger knappen. I stedet for en generisk etiket som "Opdater" kan knappen vise kontekstspecifik tekst som "Opdater status for Session ABC til I gang."

For at konfigurere dynamisk knaptekst:

  1. Opret et mål, der genererer knaplabelen. For eksempel kombinerer dette mål det valgte projektnavn og ny status:

    Update status button text = 
        "Update the status of " & SELECTEDVALUE(Project[Project name]) & " to " & SELECTEDVALUE('Status Options'[Status])
    
  2. I Format-panelet for data-funktionsknappen, udvid Knaptekst>.

  3. Sæt standardtekst til din dynamiske mål ([Update status button text]).

  4. Sæt deaktiveret tekst til statisk tekst, der fortæller brugerne, hvilke valg der kræves (for eksempel "Vælg et projekt, ny status og tilføj noter først").

Knappen viser den deaktiverede tekst, indtil alle nødvendige parametre har værdier. Når brugeren har foretaget sine valg, viser knappen den dynamiske tekst, der beskriver den specifikke handling.

Skærmbillede, der viser knapformatpanelet med dynamisk tekstkonfiguration ved brug af en måling for standardtekst og statisk tekst for deaktiveret tilstand.

(Valgfrit) Tilføj en bore-igennem-knap og side

Du kan tilføje en drill-through-side, der viser hele historikken over statusopdateringer for et udvalgt projekt.

  1. I fanen Indsæt vælg Knap>Blank.

  2. I Format-panelet under Knap skal du sætte teksten:

    • Standardtekst: "Se alle statusopdateringer"
    • Deaktiveret tekst: "Vælg et projekt for at se alle statusopdateringer"
  3. Under Handling aktiveres handlingen og sættes:

    • Type: Drillthrough
    • Destination: Vælg din statushistorik-side (oprettet i næste trin)
  4. Tilføj en ny side og navngiv den Statusopdateringshistorik.

  5. I Format-panelet for siden udvid sideinformation og aktiver Drillthrough. Tilføj Project[Product name] som bore-gennem-felt.

  6. Tilføj visuelle elementer for at vise statushistorikken:

    • Kort: Samlet antal statusopdateringer
    • Knapslicer: Opdeling efter status
    • Tabel: Alle statusopdateringer (Opdaterings-id, Opdateringsdato, Status, Noter, Opdateret af)
    • Linjediagram: Opdater aktiviteten over tid
  7. Tilføj en Tilbage-knap , så brugerne kan vende tilbage til hovedrapportsiden. I fanen Indsæt vælg Button>Back.

Udgiv rapporten

  1. Gem din rapport og publicér den til Power BI-tjenesten.

  2. Kopier rapportens URL og tilføj den til dit variabelbibliotek som POWERBI_REPORT_URL.

Test arbejdsgangen

Test opdateringsflowet for anmodningsstatus

Når den er offentliggjort, kan du bruge den translytiske opgavegang til at anmode om en statusopdatering:

Skærmbillede, der viser de nummererede trin for at anmode om en statusopdatering: 1) vælg et projekt, 2) indtast en besked, 3) vælg Send Teams-besked til kanal, 4) se bekræftelse, 5) Teams-notifikation vises med knappen Opdater Projektstatus.

  1. Vælg et projekt at opdatere - Vælg en projektrække i tabellen for at sætte filterets kontekst.

  2. Eller send en besked til teams-kanalen – Indtast en besked i input-sliceren (for eksempel: "Kan vi få en opdatering på dette?").

  3. Vælg knappen Send teams-besked til kanal .

  4. En bekræftelse af indsendt anmodning vises, når handlingen gennemføres med succes.

  5. Tjek din Teams-kanal for Project Status Update Adaptive Card med anmodningsdetaljerne.

  6. Projektejeren kan vælge Opdater Projektstatus i Adaptive Card for at åbne rapporten og opdatere deres status.

Skærmbillede, der viser Adaptive Card-notifikationen i Teams, der anmoder om en statusopdatering med knappen Opdater Projektstatus.

Test opdateringsstatusflowet

Når den er offentliggjort, kan du bruge den translytiske opgavegang til at opdatere en projektstatus:

Skærmbillede, der viser de nummererede trin til opdatering af et projektstatus: 1) vælg et projekt, 2) vælg en status, 3) tilføj noter, 4) vælg Opdater, 5) se bekræftelse, 6) Teams-notifikation vises.

  1. Vælg et projekt at opdatere - Vælg en projektrække i tabellen for at sætte filterets kontekst.

  2. Hvad er den nye status? - Brug knap-sliceren til at vælge en ny status (for eksempel I gang).

  3. Tilføj noter til denne statusopdatering - Indtast noter i input-sliceren (for eksempel "Startede til at optage demo").

  4. Vælg knappen Opdater for at skrive statusændringen tilbage til søhuset og send en Teams-notifikation.

  5. En bekræftelse af indsendt anmodning vises, når handlingen gennemføres med succes.

  6. Tjek din Teams-kanal for Project Status Update Adaptive Card med statusændringsdetaljerne.

Skærmbillede, der viser Notifikationen om Adaptive Card i Teams efter en statusopdatering.

Translytiske opgaveflow

Rapport-visuals

DAX-funktioner

Fabric-data

Microsoft Teams