关于 platform-custom-report-type-generate
面向 Salesforce 报表开发的技能,指导创建自定义报表类型元数据,定义主对象、关联对象和可用字段。也涵盖连接方式及部署验证规则。
主要功能
- 01生成自定义报表类型元数据
- 02配置主对象与关联对象
- 03选择内连接或外连接行为
- 04按对象组织可用报表字段
- 05检查关系路径与部署设置
适用场景
- 01为自定义对象组合创建报表类型
- 02控制没有关联记录的主记录是否纳入报表
- 03为报表生成器整理可选字段
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ forcedotcom/ sf-skills --skill platform-custom-report-type-generate安装后在 Claude Code 中输入/platform-custom-report-type-generate确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
examples/AccountProjectsWithTasks.reportType-meta.xmlAccountsWithIndustry.reportType-meta.xmlAccountsWithProjects.reportType-meta.xmlreferences/category-values.mderrors-and-troubleshooting.md详细介绍
规范
Salesforce 自定义报表类型元数据知识
概述
自定义报表类型(CRT)定义 Salesforce 报表的数据框架。它们指定一个主对象、最多 3 个相关对象、对象之间的关系(联接),以及报表生成器中可用的字段。
用途
- 支持跨自定义对象和标准报表类型未涵盖的自定义关系进行报表分析
- 为报表生成器整理一组精简的字段(包括通过查找关系访问的字段)
- 控制内联接/外联接行为,以包含或排除没有相关记录的主记录
配置
文件扩展名: .reportType-meta.xml。文件名(不含扩展名)是报表类型的开发者名称(例如 AccountsWithProjects.reportType-meta.xml)。每个 CRT 都是一个单独的文件,不嵌套在对象文件夹下。
关键元素
顶层 <ReportType> 子元素:
| 元素 | 必填 | 说明 |
|---|---|---|
<fullName> | 是 | API 标识符;必须与文件名一致。可使用字母、数字和下划线;必须以字母开头;不能包含空格;不能以下划线结尾;不能包含连续的下划线 |
<label> | 是 | 显示在报表类型选择器中的易读名称 |
<description> | 建议填写 | 说明业务层面的“原因”——谁会使用它,以及能从中了解到什么 |
<baseObject> | 是 | 主对象的 API 名称(例如 Account、Project__c)。创建后不能更改。支持所有对象,包括自定义对象和外部对象(API 38.0+ 起支持外部对象) |
<category> | 建议填写 | 报表生成器类别——请参阅 references/category-values.md |
<deployed> | 是 | 设为 true 可向用户开放;构建或迭代期间设为 false |
<join> | 有条件必填 | 添加相关对象及其联接行为。对于更深层的关系,可嵌套更多 <join> 块 |
<sections> | 建议填写 | 对报表类型可用列进行分组。虽然不是严格必需,但没有列的报表并无实用价值 |
<sections>(列组)子元素:
| 元素 | 必填 | 说明 |
|---|---|---|
<masterLabel> | 是 | 报表生成器中显示的分组标题 |
<columns> | 有条件必填 | 每个在该分组中公开的字段对应一个 |
<columns>(单个字段)子元素:
| 元素 | 必填 | 说明 |
|---|---|---|
<field> | 是 | 字段 API 名称(或点分隔的查找关系遍历路径) |
<table> | 是 | 字段所属的对象——基对象名称或点分隔的关系路径 |
<checkedByDefault> | 是 | 如果该列在报表生成器中默认选中,则设为 true |
<displayNameOverride> | 否 | 在报表生成器中显示的自定义列标签,用于覆盖字段的默认标签 |
关键规则(请先阅读)
规则 1:如果存在 <fullName>,其值必须与文件名一致
在源格式中,fullName 继承自 Metadata,并根据文件名生成,因此 <fullName> 元素在技术上是可选的。仓库约定是包含该元素。如果包含 <fullName>,其值必须与文件名完全一致(即 .reportType-meta.xml 之前的所有内容)——字符、大小写和下划线都必须相同。
错误——文件名和 <fullName> 不一致:
- 文件:
account_projects.reportType-meta.xml <fullName>AccountProjects</fullName>(不一致:文件名使用account_projects,fullName 使用AccountProjects)
正确——文件名和 <fullName> 完全相同:
- 文件:
AccountProjects.reportType-meta.xml <fullName>AccountProjects</fullName>
规则 2:联接语义 — outerJoin 控制纳入范围
每个 <join> 块都有一个 <outerJoin> 元素,用于确定报告中显示哪些主记录:
<outerJoin> 值 | 行为 | 报告生成器中的标签 |
|---|---|---|
false | 内联接 — 仅显示至少有一条相关记录的主记录 | “每条 ‘A’ 记录都必须至少有一条相关的 ‘B’ 记录” |
true | 外联接 — 显示所有主记录,无论是否有相关记录 | “‘A’ 记录可能有相关的 ‘B’ 记录,也可能没有” |
未指定时的默认值: 如果用户希望查看所有主记录,无论是否存在子记录,请使用 true(外联接)。如果只有在存在子记录时报告才有意义,请使用 false。
规则 3:每个对象都需要自己的 <sections> 块
CRT 中的每个对象(主对象和每个联接对象)都必须有对应的 <sections> 块,列出可用于报告的字段。如果某个对象没有对应的区段,该对象的字段都不会出现在报告生成器中。
- 每个区段上的
<masterLabel>是报告生成器中的区段标题 <columns>条目列出字段 — 每个条目都包含<field>(API 名称)和<table>(对象 API 名称)- 对于通过查找关系访问的字段,请在
<field>中使用关系路径(例如,Owner.Name),并将<table>设为所属对象
规则 4:使用字段 API 名称,而非标签
字段必须使用准确的 API 名称:标准字段使用其定义的名称(Name、CreatedDate、OwnerId),自定义字段使用 Field__c。自定义对象必须包含 __c。
错误:
<field>Account Name</field>
正确:
<field>Name</field>,并设置<table>Account</table>
规则 5:联接对象的关系路径
添加 <join> 时,<relationship> 元素必须使用从子对象指向父对象的查找/主从关系字段上定义的子关系名称。对于自定义关系,名称通常以 __r 结尾。
错误:
<relationship>Project</relationship>(用于自定义子关系)
正确:
<relationship>Projects__r</relationship>(子关系名称)<relationship>Contacts</relationship>(标准非自定义子关系)
规则 6:联接链中最多包含 4 个对象
单个 CRT 最多可联接四个对象(基对象加上最多 3 个通过嵌套 <join> 块添加的对象)。
规则 7:外联接之后不能使用内联接
联接链中一旦出现外联接(<outerJoin>true</outerJoin>),之后的每个嵌套联接也必须是外联接。序列中外联接之后不能再出现内联接。
错误:
<join>
<outerJoin>true</outerJoin>
<relationship>Contacts</relationship>
<join>
<outerJoin>false</outerJoin>
<relationship>Assets</relationship>
</join>
</join>
正确:
<join>
<outerJoin>true</outerJoin>
<relationship>Contacts</relationship>
<join>
<outerJoin>true</outerJoin>
<relationship>Assets</relationship>
</join>
</join>
规则 8:联接对象的 <table> 使用点分路径
在 <sections> 中,<table> 元素用于标识每列属于联接链中的哪个对象。对于基对象,直接使用对象名称(例如 Account)。对于联接对象,使用从基对象开始的点分关系路径。
| 链中的对象 | <table> 值 |
|---|---|
| 基对象(Account) | Account |
| 第一个联接(Account → Contacts) | Account.Contacts |
| 嵌套联接(Account → Contacts → Assets) | Account.Contacts.Assets |
规则 9:字段路径可以遍历查找关系
<field> 值可以使用点表示法引用通过查找关系访问的字段 — 例如 Owner.Email(所有者 User 的电子邮件)或 ReportsTo.CreatedBy.Contact.Owner.MobilePhone。<table> 仍必须是拥有起始字段的对象。
规则 10:历史趋势字段使用 _hst 后缀
对于 trackTrending=true 的字段,<field> 和 <table> 中的 API 名称使用 _hst 后缀:
<columns>
<checkedByDefault>false</checkedByDefault>
<field>Field2__c_hst</field>
<table>CustomTrendedObject__c.CustomTrendedObject__c_hst</table>
</columns>
规则 11:部署后无法更改主对象
部署后,CRT 的 <baseObject> 将被锁定。要更改主对象,请创建新的 CRT,并停用旧 CRT。
规则 12:autogenerated 仅用于历史趋势
<autogenerated> 元素(API 29.0+)用于标记 Salesforce 在对象启用历史趋势时自动创建的 CRT。请勿在手动编写的 CRT 上手动设置此元素。
生成工作流
步骤 1:收集需求
- 主要对象 API 名称(例如
Account、Project__c) - 相关对象及其关系(每个对象通过哪个 lookup/master-detail 关系关联到哪个对象)
- 对于每种关系:使用内连接(必须有子记录)还是外连接(子记录可选)?
- 每个对象要公开哪些字段——应以与任务相关的字段为主,而非完整字段列表
- 受众和类别——应在报表生成器选择器中的什么位置显示?
- 现在是否以
deployed=true发布,还是在迭代期间保持deployed=false
步骤 2:检查现有示例
- 在项目中查找项目内 CRT 模式
- 如果已从组织检索现有报表类型,请将其结构进行比较
步骤 3:编写规格说明
编写前先记录:
fullName和labelbaseObject- 类别和
deployed状态 - 连接链:对于每个相关对象,列出关系名称以及使用外连接还是内连接
- 区段布局:每个对象一个区段,并按顺序列出字段
- 验收标准:运行报表时应显示哪些记录,以及生成器中应提供哪些字段
步骤 4:编写元数据文件
从 examples/ 中最接近的示例开始,并根据用户场景进行调整:
- 仅主对象(无连接)→
examples/AccountsWithIndustry.reportType-meta.xml - 外连接(即使没有子记录,也包含主记录)→
examples/AccountsWithProjects.reportType-meta.xml - 嵌套内连接(每一层都必须有子记录)→
examples/AccountProjectsWithTasks.reportType-meta.xml
将文件命名为 <DeveloperName>.reportType-meta.xml。
步骤 5:验证
- XML 格式正确,且命名空间正确(
xmlns="http://soap.sforce.com/2006/04/metadata") - 文件名(去掉
.reportType-meta.xml)与<fullName>一致(如果包含<fullName>) <baseObject>是有效的 API 名称,且该对象已部署- 每个
<relationship>都使用正确的子关系名称(自定义名称需带__r后缀) <sections>中引用的每个对象都是该 CRT 的组成部分(主对象或已连接对象)- 所有
<field>引用都存在于父<table>中,且使用 API 名称(而非标签) <category>是有效的 Salesforce 类别值- 如果用户需要立即访问 CRT,则
<deployed>应为true
参考文件索引
| 文件 | 何时阅读 |
|---|---|
examples/AccountsWithIndustry.reportType-meta.xml | 步骤 2 / 步骤 4——仅主对象模板 |
examples/AccountsWithProjects.reportType-meta.xml | 步骤 2 / 步骤 4——外连接模板(即使没有子记录也包含主记录) |
examples/AccountProjectsWithTasks.reportType-meta.xml | 步骤 2 / 步骤 4——嵌套内连接模板(每一层都必须有子记录) |
references/category-values.md | 步骤 3——从 ReportTypeCategory 枚举中选择有效的 <category> 值 |
references/errors-and-troubleshooting.md | 字段未显示在报表生成器中,或连接要求发生冲突时 |
验证清单
通用检查
- 文件扩展名为
.reportType-meta.xml - 文件基本名称符合开发者名称规则(以字母开头,仅包含字母、数字和下划线,不含空格,不以下划线结尾,也不含连续下划线)
- 如果包含
<fullName>,其内容与文件基本名称完全一致(字符、大小写和下划线均相同) -
<label>易于理解且少于 40 个字符 -
<description>说明业务用途 -
<baseObject>使用有效的 API 名称,且该对象已部署 -
<category>是有效的ReportTypeCategory枚举值 -
<deployed>设置恰当(允许用户访问时设为true,迭代进行中时设为false) - 不要手动设置
<autogenerated>(仅用于历史趋势 CRT)
关联检查
- 每个
<join>都使用正确的子级关系名称(而非查找字段 API 名称) - 自定义关系使用
__r后缀 - 有意设置
<outerJoin>:true= 子级为可选项,false= 子级为必选项 - 序列中外连接之后不得出现内连接(
<outerJoin>false</outerJoin>) - 对象总数(基对象和关联对象,包括嵌套对象)不超过 4 个
分区检查
- CRT 中的每个对象都有对应的
<sections>块 - 每个分区的
<masterLabel>都具有描述性 - 每个
<columns>都同时包含<field>(API 名称)和<table>(对象 API 名称或点分路径) - 为每列设置
<checkedByDefault> - 基对象的
<table>为对象 API 名称(例如Account) - 关联对象的
<table>使用点分关系路径(例如Account.Projects__r、Account.Projects__r.Tasks__r) - 字段引用使用 API 名称(而非标签);自定义字段使用
__c - 查找遍历字段使用点表示法(例如
Owner.Email),并将<table>设置为起始字段所属对象 - 适用时,历史趋势字段的
<field>和<table>均使用_hst后缀 - 每个分区中不得有重复字段