其他
用 pbi CLI 与 Python 生成器构建 IPPF…
当需要为 Power BI 语义模型添加 DAX 度量、写入品牌主题、暂存页面配方,或从 Excel 端到端生成完整可用的 .pbip 仪表板时使用。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 35/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 38/100 ×0.15
适用场景
用 pbi CLI 与 Python 生特定
解决思路
- 预检按顺序执行,首次失败即停止并给出提示:1) 运行 `pipx list | grep pbi-cli-tool` 确认 pbi 已安装,若为空则提示运行 `pipx install pbi-cli-tool && pipx ensurepath && pbi skills install` 并打开新 shell 让 PATH 生效。
- 2) 确认 Power BI Desktop 正在运行且已打开项目:先裸跑一次 `pbi connect` 从 “Auto-detected Power BI Desktop on localhost:<port>” 行读取端口,用 `pbi disconnect` 断开,再用显式名称重连 `pbi connect -d localhost:<port> -n PBIDesktop-<pbip-basename>-<port>`(必须用模型派生名,pbi-cli 默认的 `localhost-<port>` 会被 MCP 服务器拒绝并报 `Connection 'localhost-<port>' not found`);若无活动项目则提示打开 Power BI Desktop 并加载 `.pbip`;若 Analysis Services 端口中途变化(引擎重启、文件重开、切换 Model 视图等),用新端口重跑此步。
- 3) 确认活动项目是文本格式 `.pbip` 而非旧版二进制 `.pbix`:若 `pbi connect` 输出路径以 `.pbix` 结尾则停止,提示先 File → Save as → 将 Save as type 设为 Power BI Project 另存为 `.pbip`。
- 4) 确认品牌层可导入:检查 `${WORK_FOLDER_ROOT}/ane_package/reporting/powerbi_dashboard/__init__.py` 存在,缺失则提示检查 OneDrive 同步。
- 解析意图:从提示词和本会话最近的分析产物中确定指标(取自 `MEL_DAX_LIBRARY`,含糊时询问可用键)、受众层级(默认 Tier 1 working brief,仅当提示明确指定才用 Tier 2 publication)、页面集(默认每个指标 `(indicator_dashboard, equity_disaggregation, methodology_card)`)、来源行(从先前产物推导,缺失则问一次)、暂存目录(默认 `${PWD}/powerbi-build-output/`,存放 theme.json、measures.json 和页面配方)。
- 用 Python 在内存中生成全部产物:从 `ane_package.reporting.powerbi_dashboard` 导入 `MEL_DAX_LIBRARY`、`build_equity_disaggregation_page`、`build_indicator_dashboard_page`、`build_ippf_theme`、`build_methodology_card_page`;调用 `build_ippf_theme()` 生成主题,按选中指标从 `MEL_DAX_LIBRARY` 取度量;对每个指标依次调用 `build_indicator_dashboard_page(indicator, target, source)` 和 `build_equity_disaggregation_page(indicator, ("age", "gender", "geography", "wgss_disability"), source)`,最后追加 `build_methodology_card_page(method_note, evidence_base_sources, glossary_terms)`;将 theme.json、measures.json 和每个 `page_<page_id>.json` 写入 `powerbi-build-output/`。
- 通过 `pbi measure create` 应用 DAX 度量:从 DAX 表达式中的 `[bracketed]` 引用推断表(启发式:表达式中第一个 `Table[Column]` 引用,若只引用其他度量则用 `_Measures`),执行 `pbi measure create <measure-key> --table <inferred-table> --expression "<dax-expression>"`(度量名是位置参数,不是 `--name` 标志,已对 pbi-cli-tool 0.5.6 验证);原样暴露错误,绝不重试——pbi 失败通常意味着模型中没有所引用的表或列,pbi-cli 在 “table not found” 时会回滚事务,度量不会以红色图标落地;要么预置桩表,要么先修正 DAX 再重试。
- 保存纪律:每次 `pbi table` / `pbi measure` / `pbi column` / `pbi relationship` 写入后,立即让用户切到 Power BI Desktop 按 Ctrl+S;外部 pbi 写入只存在于 Analysis Services 引擎内存中,磁盘上的 `.pbip` 由 Power BI Desktop 在 File → Save 时更新,若引擎在保存前重启(端口变化、文件重开、有时切换 Model 视图),写入会丢失。
- 写入主题 JSON:将主题 JSON 直接写入 `.pbip` 报告文件夹的两处路径(Power BI Desktop 2.140+):`<project>.Report/StaticResources/SharedResources/BaseThemes/ippf-visual-identity-2025.json` 和 `<project>.Report/StaticResources/RegisteredResources/ippf-visual-identity-2025.json`;然后更新 `report.json` 注册该主题(Power BI Desktop 从 report.json 元数据读取主题名,未注册则主题只出现在 Themes 画廊但不会自动应用);若 `<project>.Report/` 不存在,说明用户未启用 PBIP 报告格式预览(File → Options → Preview features → Power BI Project (.pbip) source control),给出明确提示。
- 主题重试时做缓存清除:Power BI Desktop 会按文件名缓存已注册主题,导入失败后即使文件已修复,用同一文件名重新导入仍会显示旧的校验错误;任何校验失败后的重试都要用带版本号的新文件名(`ippf-visual-identity-2025-v2.json`、`-v3` 等)写入,让 Power BI 当作新文件解析。
- 页面配方在 v1 仅暂存:将每个页面配方以 JSON 保存到暂存目录,v1 不要尝试把 PBIR 页面文件写入 `.pbip` 文件夹(PBIR 格式仍在预览、schema 不稳定);在聊天输出中明确告诉用户哪个文件对应哪个页面配方、需要手动创建哪些视觉对象(例如 `powerbi-build-output/page_cyp_total-dashboard.json` → 新建页面 “cyp_total Dashboard” → Card 视觉对象:度量 [cyp_total],位置 (40, 40, 280, 120);Line chart:x=Date[Month], y=[cyp_total],位置 (360, 40, 880, 320);Bar chart:x=Geography[country], y=[cyp_total],位置 (40, 380, 1200, 280)),每个页面重复。
- 当来源是 Excel 且用户想要完整可用的仪表板交接时,改用完整 `.pbip` 编写路线:用可重复运行的 Python 生成器编写整个 `.pbip`(因为 pbi CLI 无法导入 Excel 数据——PowerBI 兼容模式下 DataSourceOperationsTool 被跳过——也没有报告页面/视觉对象 API);参考构建 `${WORK_FOLDER_ROOT}/scripts/gen_cerv_dashboard_pbip.py`;若目标 `.pbip` 已存在,应用 `mel_wiki/wiki/concepts/edit-preservation-protocol.md`;若用户已打开目标项目,编写到新的项目文件夹(避免文件锁),让用户不保存关闭后重新打开。
- 完整编写路线步骤:1) 镜像 schema——读取现有空 `.pbip` 骨架并复制其确切版本(compatibilityLevel 1600;report.json 3.3.0;visual 2.9.0;page 2.1.0;pbism 4.2),要求 Desktop 中启用 PBIP + PBIR 预览功能。2) 用 openpyxl 检查 Excel:sheet 名、精确表头字符串(不要 strip——尾随空格会破坏列引用)、表头行位置、每列值类型;与工作簿内现有仪表板标签页的预期聚合值对账。3) 编写 SemanticModel TMDL(TAB 缩进):`database.tmdl`、`model.tmdl`(含 `ref table X` 行 + `relationship` 块)、`cultures/`、`tables/*.tmdl`(列 + 度量 + M `partition`);M 块比 `source =` 缩进更深。4) 编写报告 PBIR:`definition.pbir`(用相对 `byPath` 指向 SemanticModel——该链接在文件夹移动后仍有效)、`report.json`(注册 IPPF 自定义主题 + 基础主题)、`pages/<id>/page.json`、`pages/<id>/visuals/<id>/visual.json`。5) 对照源聚合值核对度量,然后让用户打开并 Refresh;加载后通过 CLI 验证:`pbi connect`,再 `pbi dax execute "EVALUATE <Table>"` 并读取 `RowCount=`(CLI 不打印单元格值;用表 EVALUATE 并读行数)。
- Power Query M 陷阱(每个都曾导致一次刷新错误循环,需预先应用):`Excel.Workbook(File.Contents(path), null, true)` 会丢弃开头完全空白的行,因此固定 `Table.Skip(n)` 会错位表头——动态定位:`HeaderRow = List.PositionOf(Sheet[Column1], "<key header>")`,然后 `Table.Skip(Sheet, HeaderRow)`,再 `Table.PromoteHeaders(.., [PromoteAllScalars=true])`;是 `List.PositionOf`(列表 + 值),不是 `Table.PositionOf`(表 + 记录),后者会抛 “cannot convert List to Table”;只对仪表板需要的列做硬类型(金额 → `type number`,计数 → `Int64.Type`),对计算列 / “(auto)” 列做类型会在未填行返回非数值("" / "Pending")时抛每单元格 “N errors”,这些列保持不类型化;多行 / 合并表头 sheet:跳过 PromoteHeaders,用位置式 `Table.Range` + `Table.SelectColumns({"Column1",...})` + 重命名;M 文件路径是字面量(无反斜杠转义),把源路径放在共享表达式里一次或一致地内联。
- PBIR 视觉对象 JSON(盲写也能全部正确渲染):最小 `visual.query.queryState.<role>.projections[{field:{Measure|Column:{Expression:{SourceRef:{Entity}},Property}}, queryRef:"Entity.Prop", nativeQueryRef:"Prop"}]`;角色:`card`→`Values`;`clusteredColumnChart`/`clusteredBarChart`→`Category`+`Y`(多度量图省略 `Category`);`tableEx`→`Values`(列表);省略 title 对象,让 IPPF 主题和自动标题样式化一切;附加:切片器多选 + Select-all = `objects.selection[{properties:{singleSelect:{Literal false}, selectAllCheckboxEnabled:{Literal true}}}]`;导航栏 = visualType `pageNavigator`;logo = visualType `image` 配 `ResourcePackageItem(RegisteredResources)`,把 PNG 复制到 `StaticResources/RegisteredResources/` 并在 report.json 注册;页眉带 = 带 `visualContainerObjects.background` 的 textbox。
- 采用易读布局(1280×720):紧凑的全宽切片器条(切片器渲染为下拉框)、KPI 卡片行、然后全宽大图表——避免半宽切片器行浪费其右侧区域;将页面 `displayOption` 设为 `FitToWidth`,使其填满显示器并垂直滚动。
- 向用户说明分发与许可:`.pbip` 是开发/源码控制格式,刷新前打开为空,不适合新手;给新手查看者分发 `.pbix`(File → Save As → `.pbix` 内嵌数据、打开即有内容、无需许可证),只有 Power BI Desktop 能写 `.pbix`,任何 CLI/脚本都不能,且内嵌数据需要先做一次实时刷新;Power BI Service 发布时,免费层同事只有在工作区位于 Premium(P SKU)或 Fabric F64+ 容量时才能查看,否则每个查看者也需要 Pro/PPU;敏感数据(SRHR / 财务 / 子受赠方)绝不要用 “Publish to web”,它是公开的;页面导航器和按钮在 Reading 视图 / 已发布状态下单击导航,在 Editing 视图下需 Ctrl+click(这是 Power BI 固有行为,不是 bug);被绝对本地/OneDrive 路径引用的 Excel 源移到 SharePoint 后会断,需通过 SharePoint 连接器重新指向以支持云端计划刷新,刷新每次都会重读源。
- 输出 Tier 1 working brief:报告已应用的度量数量与键列表、主题写入路径、暂存目录中每个页面配方文件及其视觉对象数量、推导出的来源行。
- 常见错误处理:安装后 `pbi: command not found` → `pipx ensurepath` 并打开新 shell;`pbi connect` 无会话 → 打开 Power BI Desktop 并加载 `.pbip`;`pbi measure create` 报 “table not found” → 核对数据模型与度量假设,添加表或调整 DAX;指标不在 `MEL_DAX_LIBRARY` → 在 `dax_library.py` 中添加并附 wiki 条目,向 anework-package 提 PR;主题未应用 → 启用 PBIP 预览并检查 `report.json` 是否带主题名;页面配方中的 visualType 用户找不到 → 按视觉画廊对应(card = “Card”;lineChart = “Line chart”;barChart / stackedBarChart = “Stacked bar chart”;slicer = “Slicer”;table = “Table”;textbox = “Text box”);`Connection 'localhost-<port>' not found` → 用 `-n PBIDesktop-<pbip-basename>-<port>` 重连;pbi 模型写入在命令间消失 → 每次写入后按 Ctrl+S;主题导入报引用同一键的 `oneOf` 校验错误 → 用 `-v2`/`-v3` 文件名重写并重新浏览;`pbi table refresh` 报 `Invalid operation: Refresh` → pbi-cli 0.5.6 上游 bug,改在 Power BI Desktop 手动刷新(Home → Refresh);`pbi measure get` 或 `pbi table export-tmdl` 报 `References is required` → 上游 bug,用 `pbi measure list --table <name>` 确认度量存在,用 Desktop 的 Tabular Editor 视图检查 TMDL;刷新报 “The column '<key>' of the table wasn't found”(提升表头表)→ 用 `Table.Skip(Sheet, List.PositionOf(Sheet[Column1], "<key>"))` 动态定位表头;刷新报 “We cannot convert a value of type List to type Table” → 用 `List.PositionOf(list, value)` 而非 `Table.PositionOf(table, record)`;刷新报某表 “N rows loaded. M errors” → 去掉该列的类型转换,只类型化仪表板需要的列;报告打开但刷新后所有视觉对象空白 → 导入模型加载 0 行(M 失败),不是绑定 bug,用 `pbi` 连接后 `pbi dax execute "EVALUATE <Table>"` 读 `RowCount=`,修 M 而非视觉对象;接收者打开 `.pbip` 看到空报告 → `.pbip` 不存数据,分发 `.pbix`(内嵌数据)或发布到 Service。
适用边界 · 注意事项
- 未安装 pbi CLI(`pbi-cli-tool`)或未打开带 `.pbip` 项目的 Power BI Desktop 时无法使用。
- 项目仍是旧版二进制 `.pbix` 而非文本格式 `.pbip` 时,本技能不适用。
- 需要完整页面与视觉对象自动化时 v1 不适用(v1 仅写度量 + 主题 + 暂存页面配方,页面需手动应用)。