用友 BIP 高级版 报表撰写
⚠️ 技能维护边界(最高优先级,先于一切能力与约定)
本技能的核心定位是用友 BIP 高级版报表撰写——基于数据字典检索与(可选的)数据库查询,产出用户需要的业务报表(取数 SQL / 视图 / 校验逻辑 / 报表说明)。它沉淀的是跨项目可复用的报表撰写方法论与技术坑,而非某个具体报表的内容。注意:本技能面向 BIP 高级版(如 2312 / 2505 等具体 Release),不覆盖 BIP 标准版 / 旗舰版等其他版本,数据字典与取数规则以高级版为准。
收录(通用方法论,须满足:跨项目可复用、不含具体场景):
- 数据字典检索能力(字段含义、外键 ref 解析、命名规律、特殊含义字段定向查找);
- 报表撰写的通用技术纪律(SQL 列名英文、不擅自加 WHERE 条件、创建视图外连接 ON 禁子查询、外键 ref 解析优先于全扫);
- 「可连库 / 不可连库」两种环境下的报表撰写工作流;
- 特殊含义字段定向查找的三类路径(用户定义属性 / 单据模板 / 档案关联追溯)。
绝不收录(具体项目内容,一律不放):
- 具体客户名 / 项目名 / 数据库 IP / 连接账号密码;
- 具体某张业务表的物理列清单与具体编码值(应从数据字典实时查,不写死);
- 具体某次报表的 SQL 成品(作为示例留痕于 references,不直接塞进正文约束);
- 用户在某次具体任务里给的原话、元指令、要求性说明文字。
新增任何内容前先自问:这是跨项目可复用的通识纪律,还是某个具体测试场景总结的定律?后者一律放 references,不放正文。 这是本技能最高优先级的边界,违背此边界等于把项目经验伪装成通用方法论。
何时使用
- 「帮我按照列A,列B,列C,列D……形成一个报表查询逻辑」
报表撰写核心工作流(最高优先级 · 先于一切技术细节)
本技能的本质是撰写报表。撰写前第一件事是判断当前环境能否连接目标数据库,并据此走不同路径。
第 0 步:判定环境模式(必做)
向用户确认或自行判断:当前是否能连接目标数据库?
| 模式 | 判定 | 后续路径 | |---|---|---| | 不可连库模式 | 无数据库连接 / 用户仅口述需求 / 仅提供字段清单 | 走 §A 纯字典推导路径 | | 可连库模式 | 已配置 Oracle 连接(如 oracledb / 直连脚本)/ 用户明确提供可访问环境 | 走 §B 字典+实查验证路径 |
不确定时先问用户,不要默认假设可连库。若用户只给了业务描述、没给连接信息,按不可连库模式处理。
§A 不可连库模式(仅数据字典 + 用户需求推导)
适用于:用户口述需求、提供截图/字段清单、或仅需要报表 SQL 骨架与字段口径。
工作流:
- 需求澄清:从用户描述中提炼报表要素——业务对象(报销单/付款单/余额表)、统计维度(部门/组织/期间/项目)、度量(金额/笔数)、过滤条件(dr=0、期间、启用状态)。
- 数据字典检索:用
dd_search.py定位主表与关联表,读ref解析外键,确认字段中文含义与类型(见第一部分)。 - 特殊含义字段查找(见第三部分):对 defitem/def1~defN、用户定义属性、档案类字段,按"单据模板+用户定义属性表"定向解析,不靠全扫猜列。
- 产出报表 SQL / 视图:按 SQL 约束铁律(第二部分)写出取数脚本,列名用英文别名、中文以注释呈现。
- 口径说明:在交付物中明确标注「本报表基于数据字典推导,未经实库验证,字段口径/取值需在可连库环境核对」。
§B 可连库模式(数据字典分析 + 特殊字段查找 + 实库查询验证)
适用于:已能访问目标库,需要出具经过数据验证的报表。
工作流:
- 需求澄清(同 §A-1)。
- 数据字典分析(同 §A-2、§A-3):先用字典锁定表结构与外键,再做特殊含义字段定向查找。
- 实库探查验证:用数据库查询确认关键假设——
- 主表行数、DR 分布、期间/组织过滤的实际取值;
- 外键关联键在目标库是否确实指向预期表(用
_fk_resolve.py思路或SELECT ... WHERE pk IN (...)抽样); - 特殊含义字段(def1~defN / 用户定义属性)的实际档案映射与取值分布;
- 度量字段的单位、方向符号(借/贷)、空值率。
- 撰写并验证报表 SQL:先写 SQL,再在库上跑「样本查询 / 勾稽校验」,确认结果自洽。
- 产出报表 + 验证结论:交付物含 SQL、字段口径、以及「已在目标库验证:样本行数 X、勾稽误差 Y」等结论。
§B 相对 §A 的关键增量是「步骤 3 实库探查」与「步骤 4 跑数验证」——不可连库时这两步用口径说明替代,可连库时必须做实,否则报表口径不可信。
第一部分:数据字典本地检索(辅助工具)
报表撰写的第一件事往往是"这个字段什么意思、外键指向谁"。本技能内置 scripts/dd_search.py,基于 BIP 高级版数据字典 做离线检索。该字典由「扩展数据包」提供,不内嵌于技能包,技能首次被调用涉及字段检索时自动落盘到 scripts/_dd2312/tables_uniq.jsonl(见顶部「强制前置检查」)。
1.0 强制前置检查(自动获取扩展数据 · 最高优先级)
执行铁律(agent 每次响应涉及本技能字段检索任务时,第一步必做):
- 先用
python <技能>/scripts/fetch_dd.py --ensure做一次幂等检查。- 若返回「数据字典已就位」,跳过、继续正常任务;
- 若检测到缺失,脚本会自动调用用友网盘接口换取最新免登录直链并下载合并(全程无需登录、无需浏览器、无需被分享人干预)。
- 仅当用户任务纯属取数 SQL 编写(且无需查字段含义)时,可跳过此检查——但首次执行
dd_search.py前必须先跑--ensure。
1.1 检索工具用法
python scripts/dd_search.py table <关键词> # 按表名/中文名找表(如 供应商 / bd_supplier)
python scripts/dd_search.py show <表名> # 看某表全部字段
python scripts/dd_search.py field <字段名> # 全库反查字段含义(如 enablestate 出现在 519 张表)
python scripts/dd_search.py md <表名>... # 导出 Markdown 字段表
1.2 命名规律
pk_*=主键/外键(char(20) UFID)。
1.3 外键解析:用【引用模型 ref】,不要全表扫描试 join
数据字典每个字段都带 ref(引用模型),它才是权威外键元数据。解析外键必须读 ref,绝不能"扫描所有含 ORG/SUPPLIER 的表逐个试 join"。
- 字段元数据里
ref形如组织_业务单元_财务组织 (financeorg):括号内 token=financeorg → 引用表org_financeorg;关联键 = 该引用表的主键(字典中pk=True的字段)。 - 示例通用表映射:financeorg→org_financeorg、corp→org_corp、dept→org_dept、supplier→bd_supplier、customer→bd_customer、psndoc→sm_user。
- 用户定义属性(defitem/def1~defN)落地须按"单据模板+用户定义属性表"定向 FK 解析(BD_USERDEFITEM → BD_USERDEFRULE → BD_USERDEFRULEREF → MD_CLASS;MD_CLASS.DEFAULTTABLENAME=物理表、PROPINDEX 决定 DEFITEMn/ZYXn),非全扫猜列。
1.4 溯源方法论(铁律)
先 FK 解析、再字典、最后才全表扫描。 外键列先跑 _fk_resolve 类工具(或 dd_search.py field + 读 ref)定位目标表与键;FK/字典无果才允许全扫且须限定视图/过滤条件。严禁"全量检索大表找值形态"反推字段含义。
第二部分:取数 SQL 约束(以报销单为示例)
2.1 输出列名一律英文,中文含义以备注呈现
SELECT pk_bxbz AS pk_bxbz -- 报销主表主键
, billno AS billno -- 单据编号
, money AS money -- 报销金额(原币)
FROM ER_BXZB
- 输出列名(
AS别名)一律英文,中文含义以-- 注释形式呈现,绝不可中文当列名。 - 视图
CREATE VIEW同此约束:列名英文、含义注释。
2.2 不擅自加 WHERE 条件:
- 优化他人 SQL 时,不得自作主张加原 SQL 没有的
WHERE条件(如DR=0)——并非所有表都需判断 DR 等过滤;保留原始过滤策略。 - 自己写时,仅对明确需要过滤的表加对应条件(如 ER_BXZB 主表过滤删除记录)。
2.3 创建视图外连接 ON 子句禁子查询
- Oracle 视图定义里,外连接
ON子句禁子查询(ORA-01799)→ 改写为内联视图放FROM。
2.4 视图 / 取数 SQL 好习惯(沉淀,通用必守)
- 档案字段三要素必带:任何涉及档案(财务组织、结算方式、人员、自定义档案、客商等)的关联,输出时主键 + 编码 + 名称尽量全部带出(如
PK_FINANCEORG/CODE/NAME),便于后续排查与跨表核对,不要只取名称或只取编码。 - 多行聚合用
LISTAGG:表体一对多、需把多行某字段拼到主表一行时,用LISTAGG(col, '/') WITHIN GROUP (ORDER BY col)(Oracle 19c 起支持LISTAGG(DISTINCT ...)去重),禁止用MAX/MIN取巧——MAX/MIN会丢失其它行值、掩盖数据真相,且多值场景语义错误。 - 视图内不保留实例名(schema 前缀):视图 SQL 中的表不要写死实例名前缀(如
BIP2505.)——保留实例名在跨实例复用时必报错。视图依赖部署时的当前 schema 解析;若确需限定,应在部署环节由 DBA 按目标实例统一处理,而非写死在视图定义里。 - 参照对照优先用主键(外键)而非编码:当某档案的编码在表中非唯一、主键唯一时(如
BD_BILLTYPE.PK_BILLTYPECODE不唯一,但PK_BILLTYPEID唯一),其子表外键应直接连主键,而不要用编码去 JOIN——用编码对照会在1:N处静默扇出、污染聚合结果(实案:ER_BXZB.DJLXBM存编码 → 同一单据对照出多个单据类型名称、视图体多出近千行冗余;改用ER_BXZB.PK_TRADETYPEID = BD_BILLTYPE.PK_BILLTYPEID后零扇出、行数干净)。判断准则:外键是 UUID 形态 → 必然指向目标表主键,直接用主键对照;编码仅是展示值,仅在确证其唯一时才可用于对照。
第三部分:特殊含义字段定向查找(报表撰写必做)
实际系统配置的时候,大量业务含义藏在用户定义属性、档案引用列中,它们在不同项目/单据模板下含义完全不同。绝不能用"全表扫描猜列"的方式反推字段含义,必须按以下路径定向查找。
3.1 通过用户定义属性,定向查找特殊字段
- 用户定义属性(内部订单号、募集资金号、政府项目号、费用大类等)不写死物理列——它们通过
BD_USERDEFITEM(属性项, PROPINDEX 物理列序号/SHOWNAME, PK_USERDEFRULE) →BD_USERDEFRULE(PK_USERDEFRULE) →BD_USERDEFRULEREF(PK_USERDEFRULE, REFCLASS=元数据类 UUID) →MD_CLASS(ID=REFCLASS, DEFAULTTABLENAME=物理表名) 绑定到具体表的物理列;物理列由PROPINDEX决定(表体→DEFITEMn、表头→ZYXn)。 - 反向(从表值解析档案):主表上用户定义属性列值是档案 PK,须遍历解析到对应档案表。
- 具体绑定到哪张表的哪个物理列,每个项目/单据模板都不同,必须从数据字典实时定向解析,不可写死、不可照搬他项目。
3.2 通过单据模板,定向查找特殊字段
- 列定位技巧:
PUB_PAGE_TEMPLET(APPCODE 关联菜单) →PUB_AREA(TEMPLETID = PUB_PAGE_TEMPLET.PK_PAGE_TEMPLET,注意不是 CODE,写成 CODE 会 0 行) →PUB_FORM_PROPERTY(AREAID=PK_AREA)。PUB_FORM_PROPERTY无propName列——属性标识用CODE、显示名用LABEL、元数据绑定用METADATAPROPERTY;检索可按CODE/METADATAPROPERTY,LABEL在部分环境为~空值不可单独依赖。 - 禁止用
pub_billtemplet反查;定位某单据模板时,从SM_APPMENUITEM按菜单名模糊匹配拿到APPCODE,再沿上述链路反查。
3.3 通过档案与特殊字段的关联关系,定向查找特殊字段
- 部分特殊字段通过某个档案与其他表关联,仅用 3.1(用户定义属性)与 3.2(单据模板)可能定位不到。此时可借助当前查询中已经出现的档案,反向追溯该特殊字段与档案之间的关联关系,从而定位其业务含义与对应物理列。
- 注意:采用本路径时,3.1(用户定义属性)与 3.2(单据模板)的定向查找方法同样适用——追溯出档案关联关系后,仍需回到属性绑定与单据模板两条路径确认具体物理列与取值口径,三者结合才能完整定位。
3.4 实库验证时(§B 模式)的特殊字段核对
可连库时,对上述特殊字段须抽样确认:
SELECT该列 DISTINCT 值,对照档案表确认映射是否齐全;- 确认空值率,避免报表统计口径因空值漏算;
- 对"系统短码↔外部编码"类映射,须抽样验证缺口比例,缺口可能属映射漏配(非 bug),报表需注明。
脚本与资源
数据字典检索(第一部分)
scripts/dd_search.py— 数据字典本地检索工具(table / show / field / md)。- 2312 版数据字典
tables_uniq.jsonl不在本技能包内,由「扩展数据包」提供(仅数据字典部分,不涉及接口清单)。
扩展数据包获取(获取重型数据用)
scripts/fetch_dd.py— 一键获取数据字典(免登录实时换直链 → 下载 → 仅提取scripts/_dd2312/合并到技能目录,接口清单部分自动忽略)。仅依赖 Python 标准库。
报表取数示例(references,仅作示例落痕,非技能正文)
references/baoxiao_sql_examples.md— 取数 SQL 示例与 FK 解析实战(以报销单为示例,含研发费用过滤、用户定义属性落地;具体业务场景由用户实际需求决定)。
提示:脚本内配置区标注了需要由客户提供的环境参数,使用时替换为实际值即可运行。
扩展数据包获取指引
本技能未内嵌重型数据(2312 数据字典)。安装技能后,这些数据由 fetch_dd.py --ensure 在首次调用技能时自动拉取(见第一部分「强制前置检查」),被分享人无需手动执行任何命令。
自动获取(默认行为,被分享人零操作)
技能顶部的「强制前置检查」已要求 agent 在涉及字段检索的任务前,自动运行:
python <技能目录>/scripts/fetch_dd.py --ensure
--ensure 为幂等模式:数据已就位则静默跳过;缺失则自动完成。
本技能只取数据字典,不涉及接口清单——fetch_dd.py 在合并时只提取 scripts/_dd2312/ 目录,接口清单部分自动忽略,技能职责与定位清晰。
Scan to join WeChat group