
platform-custom-field-generate
热门当用户需要创建、生成或验证Salesforce自定义字段元数据时,使用此技能。当用户提及自定义字段、字段类型、汇总字段、主从关系、查找关系、公式字段、选项列表、依赖(控制)选项列表、从字段引用值集,或为特定记录类型限定选项列表值时触发。当用户遇到字段部署错误时也使用,尤其是汇总格式、主从约束、公式问题,或没有业务流程就无法部署的记录类型。使用此技能进行自定义字段元数据工作、字段生成和字段故障排除。不要为创建或自定义值集本身触发——定义新的全局值集,或修改标准值集目录(如Industry或Lead Source)——请使用platform-value-set-generate;此技能涵盖引用值集的字段,而非值集定义。
当用户需要创建、生成或验证Salesforce自定义字段元数据时,使用此技能。当用户提及自定义字段、字段类型、汇总字段、主从关系、查找关系、公式字段、选项列表、依赖(控制)选项列表、从字段引用值集,或为特定记录类型限定选项列表值时触发。当用户遇到字段部署错误时也使用,尤其是汇总格式、主从约束、公式问题,或没有业务流程就无法部署的记录类型。使用此技能进行自定义字段元数据工作、字段生成和字段故障排除。不要为创建或自定义值集本身触发——定义新的全局值集,或修改标准值集目录(如Industry或Lead Source)——请使用platform-value-set-generate;此技能涵盖引用值集的字段,而非值集定义。
Salesforce自定义字段生成器和验证器
概述
生成并验证Salesforce CustomField元数据XML,特别处理最高失败率类型——汇总和主从。代理必须在输出XML之前验证以下约束,以防止Metadata API部署错误。
1. 通用必填属性
每个生成的字段必须包含以下标签:
| 属性 | 要求 | 备注 |
|---|---|---|
<fullName> |
必填 | 字段名称:从<label>派生——每个单词首字母大写,空格替换为_,追加__c。必须以字母开头。例如,标签Total Contract Value → Total_Contract_Value__c。此规则适用于字段名称。选项列表值<fullName>不同——保持用户拼写的原样,包括空格,不加__c(例如Closed Won,而不是Closed_Won)。参见references/advanced-picklists.md(参考§3)。 |
<label> |
必填 | UI名称(标题大小写) |
<description> |
始终包含 | 解释此字段存在的业务原因。 |
<inlineHelpText> |
始终包含 | 可操作的用户指导,提供超出标签的价值(例如,“输入含税美元金额”,而不是“金额”)。 |
<description>和<inlineHelpText>是必填输出,即使Metadata API不强制要求——省略它们会产生低质量元数据。
文件路径(SFDX源格式): 将每个字段保存为force-app/main/default/objects/<Object>/fields/<FieldName>__c.field-meta.xml,其中<Object>是对象的API名称(Account、Opportunity或自定义的Inventory_Item__c)。路径错误但XML正确,Metadata API永远不会看到。
外部ID配置
触发条件: 如果用户提到“集成”、“导入数据”、“外部系统ID”或“[系统名称]的唯一键”,设置<externalId>true</externalId>。
适用类型: 文本、数字、电子邮件
2. 精度、小数位和长度规则
为确保部署成功,请遵循以下数学约束:
精度与小数位规则
precision是总位数;scale是小数位数- 规则:
precision ≤ 18且scale ≤ precision - 计算: 小数点左侧位数 =
precision - scale
“固定255”规则
TextArea:不要包含<length> — Metadata API隐式固定长度为255,并拒绝显式的<length>值,错误为“Can not specify 'length' for a CustomField of type TextArea”。完全省略<length>;字段只需要<fullName>、<label>和<type>TextArea</type>。
可见行数
长文本、富文本和多选选项列表必填,以控制UI高度。
3. 字段数据类型
3.1 简单属性类型
| 类型 | <type>值 |
必填属性 |
|---|---|---|
| 自动编号 | AutoNumber |
displayFormat(必须包含{0})、startingNumber |
| 复选框 | Checkbox |
默认defaultValue为false |
| 日期 | Date |
无需精度/长度 |
| 日期/时间 | DateTime |
无需精度/长度 |
| 电子邮件 | Email |
内置格式验证 |
| 查找关系 | Lookup |
referenceTo、relationshipName、deleteConstraint |
| 主从关系 | MasterDetail |
referenceTo、relationshipName、relationshipOrder |
| 数字 | Number |
precision、scale |
| 货币 | Currency |
默认精度:18,小数位:2 |
| 百分比 | Percent |
默认精度:5,小数位:2 |
| 电话 | Phone |
标准化电话号码格式 |
| 选项列表 | Picklist |
valueSet包含valueSetDefinition(内联)或valueSetName(引用)之一;restricted(参见“选项列表restricted默认值”;高级案例见§3.4) |
| 文本 | Text |
length(最大255) |
| 文本区域 | TextArea |
无——不要包含<length>;API隐式固定长度为255 |
| 文本(长) | LongTextArea |
length、visibleLines(默认3) |
| 文本(富) | Html |
length、visibleLines(默认25) |
| 时间 | Time |
仅存储时间(无日期) |
| URL | Url |
验证协议和格式 |
3.2 计算和多值类型
| 类型 | <type>值 |
必填属性 |
|---|---|---|
| 公式 | 结果类型(例如Number) |
formula、formulaTreatBlanksAs |
| 汇总 | Summary |
参见第5节完整要求 |
| 多选选项列表 | MultiselectPicklist |
valueSet、visibleLines(默认4) |
3.3 专用类型
| 类型 | <type>值 |
必填属性 |
|---|---|---|
| 地理位置 | Location |
scale、displayLocationInDecimal |
选项列表restricted默认值
始终在<valueSet>内设置<restricted>true</restricted>,除非用户明确表示选项列表应接受管理员定义列表之外的自定义值(例如“不受限制”/“开放”)。受限集最多1,000个总值(活动+非活动)。最小内联形状:
<valueSet>
<restricted>true</restricted>
<valueSetDefinition>
<sorted>false</sorted>
<value><fullName>Option_A</fullName><default>false</default><label>Option A</label></value>
</valueSetDefinition>
</valueSet>
3.4 高级选项列表
上面的内联<valueSetDefinition>是简单案例。以下所有内容的完整规则和正确/错误示例在references/advanced-picklists.md中——对于任何非平凡的选项列表,请加载它。下面括号中的章节号(例如“参考§1”)指向该参考文件,而非此技能。硬性规则:
- 值集引用(参考§1)。
<valueSet>包含<valueSetName>(引用)或<valueSetDefinition>(内联)之一——绝不能同时包含。按裸开发者名称引用——标准集Industry、全局值集Priority_Levels,**不带__gvs**且不带__c(__gvs后缀仅用于组织存储显示;Metadata API使用裸名称)。值集支持的字段是<restricted>true</restricted>。创建值集是platform-value-set-generate技能的工作;此技能仅引用它。 - 值名称保真度(参考§3)。 选项列表值的
<fullName>/<label>保持用户的确切文本包括空格(Closed Won,绝不是Closed_Won)。空格→_+__c规则仅适用于字段名称。 - 依赖选项列表(参考§2)。 使用**现代API 38.0+**形式:
<controllingField>+ 每个对的一个<valueSettings>(<controllingFieldValue>+<valueName>);绝不使用旧版<picklist>/<picklistValues>/<controllingFieldValues>标签。控制字段和依赖字段都必须是<restricted>true</restricted>,即使请求未说明。 - 增强值属性(参考§3)。
<value>条目还接受<color>(十六进制,前导#)、<isActive>(false停用值)和值级<description>。 - 将选项列表限定到记录类型(参考§5)。 每个记录类型的值可见性位于RecordType(
<picklistValues>)上,而非字段。RecordType文件携带自己的<fullName>(裸开发者名称)。首先决定对象是否需要业务流程: 只有Opportunity / Lead / Case / Solution需要——它们没有<businessProcess>就无法部署(Required field is missing: businessProcess),即使只过滤自定义选项列表。在那里,您需要发出两个耦合文件:businessProcesses/<Name>.businessProcess-meta.xml文件以及<RecordType>内匹配的<businessProcess><Name></businessProcess>(在<active>之后、<picklistValues>之前;BP文件中的<fullName>是裸的,绝不对象限定)。自定义对象(*__c)和所有其他标准对象(Account、Contact等)不需要业务流程——仅发出RecordType;不要发明一个。 范围限制: 仅限每个记录类型的选项列表值可见性——不是一般的记录类型创作(紧凑布局、页面布局、品牌)。
4. 主从关系规则 关键
主从字段有严格的属性限制,与查找字段不同。违反这些规则会导致部署失败。
主从字段上的禁止属性
绝不在主从字段上包含这些属性:
| 禁止属性 | 原因 | 后果 |
|---|---|---|
<required> |
主从始终必填 | 部署错误 |
<deleteConstraint> |
主从始终级联删除 | 部署错误 |
<lookupFilter> |
仅查找字段支持 | 部署错误 |
主从与查找比较
| 属性 | 主从 | 查找 |
|---|---|---|
<required> |
禁止 | 可选 |
<deleteConstraint> |
禁止(始终级联) | 必填(SetNull、Restrict、Cascade) |
<lookupFilter> |
禁止 | 可选 |
<relationshipOrder> |
必填(0或1) | 不适用 |
<reparentableMasterDetail> |
可选 | 不适用 |
<writeRequiresMasterRead> |
可选 | 不适用 |
错误 — 带禁止属性的主从:
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>Account__c</fullName>
<type>MasterDetail</type>
<referenceTo>Account</referenceTo>
<relationshipName>Contacts</relationshipName>
<relationshipOrder>0</relationshipOrder>
<required>true</required> <!-- 错误:删除 -->
<deleteConstraint>Cascade</deleteConstraint> <!-- 错误:删除 -->
<lookupFilter>...</lookupFilter> <!-- 错误:删除整个块 -->
</CustomField>
错误: Master-Detail Relationship Fields Cannot be Optional or Required · Can not specify 'deleteConstraint' for a CustomField of type MasterDetail · Lookup filters are only supported on Lookup Relationship Fields
正确 — 主从字段:
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>Account__c</fullName>
<label>Account</label>
<description>将此记录链接到其父Account</description>
<type>MasterDetail</type>
<referenceTo>Account</referenceTo>
<relationshipLabel>Child Records</relationshipLabel>
<relationshipName>ChildRecords</relationshipName>
<relationshipOrder>0</relationshipOrder>
<reparentableMasterDetail>false</reparentableMasterDetail>
<writeRequiresMasterRead>false</writeRequiresMasterRead>
<!-- 无required、deleteConstraint或lookupFilter -->
</CustomField>
正确 — 查找字段(带可选属性):
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>Related_Account__c</fullName>
<label>Related Account</label>
<description>可选链接到相关Account</description>
<type>Lookup</type>
<referenceTo>Account</referenceTo>
<relationshipLabel>Related Records</relationshipLabel>
<relationshipName>RelatedRecords</relationshipName>
<required>false</required>
<deleteConstraint>SetNull</deleteConstraint>
<lookupFilter>
<active>true</active>
<filterItems>
<field>Account.Type</field>
<operation>equals</operation>
<value>Customer</value>
</filterItems>
<isOptional>false</isOptional>
</lookupFilter>
</CustomField>
其他主从规则
- 关系顺序: 对象上第一个主从 =
0,第二个 =1 - 关系名称: 必须是复数PascalCase字符串(例如
Travel_Bookings) - 连接对象: 使用两个主从字段实现标准多对多(启用汇总)
- 限制: 每个对象最多2个主从关系。其他关系使用查找。
5. 汇总字段规则 关键
汇总字段具有最高的部署失败率。请精确遵循这些规则。
汇总必填元素
| 元素 | 要求 | 格式 |
|---|---|---|
<type> |
必填 | 始终为Summary |
<summaryOperation> |
必填 | count、sum、min或max |
<summaryForeignKey> |
必填 | ChildObject__c.MasterDetailField__c |
<summarizedField> |
条件 | sum、min、max必填。count不需要 |
汇总上的禁止元素
绝不在汇总字段上包含这些属性:
| 禁止属性 | 原因 |
|---|---|
<precision> |
汇总继承自汇总字段 |
<scale> |
汇总继承自汇总字段 |
<required> |
不适用于汇总字段 |
<length> |
不适用于汇总字段 |
summaryForeignKey和summarizedField的格式规则
关键: summaryForeignKey和summarizedField都必须使用完全限定格式:
ChildObjectAPIName__c.FieldAPIName__c
决策逻辑:
summaryForeignKey=ChildObject__c.MasterDetailFieldOnChild__csummarizedField=ChildObject__c.FieldToSummarize__c
错误 — 带常见错误的汇总:
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>Total_Amount__c</fullName>
<label>Total Amount</label>
<type>Summary</type>
<precision>18</precision> <!-- 错误:删除 - 继承自源 -->
<scale>2</scale> <!-- 错误:删除 - 继承自源 -->
<summaryOperation>sum</summaryOperation>
<summaryForeignKey>Order__c</summaryForeignKey> <!-- 错误:缺少字段名 -->
<summarizedField>Amount__c</summarizedField> <!-- 错误:缺少对象名 -->
</CustomField>
错误:
Can not specify 'precision' for a CustomField of type SummaryMust specify the name in the CustomObject.CustomField format (e.g. Account.MyNewCustomField)
正确 — 汇总(SUM操作):
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>Total_Amount__c</fullName>
<label>Total Amount</label>
<description>所有行项目金额的总和</description>
<inlineHelpText>自动从子行项目计算</inlineHelpText>
<type>Summary</type>
<summaryOperation>sum</summaryOperation>
<summarizedField>Order_Line_Item__c.Amount__c</summarizedField>
<summaryForeignKey>Order_Line_Item__c.Order__c</summaryForeignKey>
<!-- 无precision、scale、required或length -->
</CustomField>
COUNT: 结构与SUM相同,但完全省略<summarizedField>(并保留<summaryForeignKey>)。MIN / MAX: 与SUM相同——只需<summaryOperation>min</summaryOperation>或max,<summarizedField>指向要查找最小值/最大值的字段。下面的快速参考表涵盖所有四种。
汇总快速参考
| 操作 | 需要summarizedField? | 用例 |
|---|---|---|
count |
否 | 计算子记录数 |
sum |
是 | 累加数值 |
min |
是 | 查找最小值 |
max |
是 | 查找最大值 |
汇总前提条件
- 汇总字段只能在主从关系中的父对象上创建
- 子对象必须有一个指向此父对象的主从字段
- 汇总字段必须存在于子对象上
6. 公式字段规则
公式结果类型
公式本身不是类型。<formula>标签添加到<type>设置为结果数据类型的字段上:
Checkbox、Currency、Date、DateTime、Number、Percent、Text
公式XML生成规则
<formula>标签的内容必须包裹在<![CDATA[ ... ]]>部分中。这防止XML解析器将公式运算符(如&、<、>)解释为XML标记。- 如果公式文本本身包含字面序列
]]>,通过中断CDATA块来转义:例如<![CDATA[Text_Field__c & "]]]]><![CDATA[>"]]> - 绝不要使用名为
returnType的属性或标签。这在Metadata API中不存在。<type>标签定义公式结果的数据类型。
formulaTreatBlanksAs规则
决策逻辑:
- 如果公式结果类型为
Number、Currency或Percent→ 设置<formulaTreatBlanksAs>BlankAsZero</formulaTreatBlanksAs> - 如果公式结果类型为
Text、Date或DateTime→ 设置<formulaTreatBlanksAs>BlankAsBlank</formulaTreatBlanksAs>
错误 — 使用Formula作为类型:
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>Calculated_Value__c</fullName>
<type>Formula</type> <!-- 错误:Formula不是有效类型 -->
<returnType>Number</returnType> <!-- 错误:Metadata API中不存在returnType -->
<formula>Field1__c + Field2__c</formula> <!-- 错误:缺少CDATA包装 -->
</CustomField>
正确 — 公式字段:
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>Calculated_Value__c</fullName>
<label>Calculated Value</label>
<description>Field1和Field2的总和</description>
<type>Number</type> <!-- 结果类型,而非"Formula" -->
<precision>18</precision>
<scale>2</scale>
<formula><![CDATA[Field1__c + Field2__c]]></formula>
<formulaTreatBlanksAs>BlankAsZero</formulaTreatBlanksAs>
</CustomField>
公式字段依赖和函数
- 引用其他字段的公式字段,如果引用的字段不存在或尚未部署,则部署失败——先部署引用的字段。
- 使用
ISPICKVAL()(而非==)进行选项列表比较。 - 有关完整公式函数参考(TEXT/VALUE/CASE/DAY/MONTH/DATEVALUE/ISCHANGED类型规则),请参考
platform-validation-rule-generate技能,该技能负责公式函数的正确性。
7. 常见部署错误
| 错误消息 | 原因 | 修复 |
|---|---|---|
ConversionError: Invalid XML tags or unable to find matching parent xml file for CustomField |
XML注释放在根<CustomField>元素之前 |
删除.field-meta.xml文件中<CustomField>之前的XML注释(<!-- ... -->) |
Field [FieldName] does not exist. Check spelling. |
引用的字段不存在或尚未部署 | 验证引用的字段存在并在此字段之前部署 |
DUPLICATE_DEVELOPER_NAME |
字段fullName在对象上已存在 | 使用唯一的业务驱动名称 |
MAX_RELATIONSHIPS_EXCEEDED |
对象上超过2个主从或15个查找字段 | 对第3个及更多主从使用查找;检查查找数量 |
| 保留关键字错误 | 使用Order__c、Group__c等 |
重命名为Status_Order__c等 |
Value set must reference a value set name or define a value set, but not both |
<valueSet>同时具有<valueSetName>和<valueSetDefinition> |
只保留一个(参见第3.4节) |
duplicate value found: [X] is defined multiple times |
两个<value>条目共享一个<fullName> |
使每个选项列表值<fullName>唯一 |
选项列表值上的Invalid fullName |
值<fullName>以数字开头或包含连字符 |
以字母开头;无连字符,无前导数字。允许空格——不要加下划线(参见§3.4值名称保真度) |
Element ...picklist is not allowed |
已弃用的≤37.0依赖选项列表语法(<picklist>/<picklistValues>/<controllingFieldValues>) |
使用现代valueSettings/controllingFieldValue/valueName形式(第3.4节) |
8. 验证清单
在生成CustomField XML之前,验证:
通用检查
- [ ]
<fullName>是否使用有效格式并以__c结尾? - [ ]
<description>和<inlineHelpText>是否都已填充且有意义? - [ ]
<label>是否为标题大小写? - [ ] 根
<CustomField>元素之前是否没有XML注释(<!-- ... -->)?(根元素之前的注释会破坏SDR的解析器)
主从字段检查 关键
- [ ]
<required>属性是否不存在?(主从始终必填) - [ ]
<deleteConstraint>属性是否不存在?(主从始终级联) - [ ]
<lookupFilter>块是否不存在?(仅查找字段) - [ ]
<relationshipOrder>是否设置为0或1? - [ ] 父对象的
<sharingModel>是否设置为ControlledByParent?
查找字段检查
- [ ]
<deleteConstraint>是否设置为SetNull、Restrict或Cascade? - [ ]
<relationshipName>是否为复数PascalCase?
选项列表字段检查
- [ ] 每个
<valueSet>是否包含<valueSetName>或<valueSetDefinition>之一——绝不同时包含? - [ ] 对于值集引用:是否设置了
<restricted>true</restricted>? - [ ] 对于StandardValueSet引用:名称是否为裸枚举且不带
__c(例如Industry)? - [ ] 对于GlobalValueSet引用:名称是否为裸开发者名称且不带
__gvs后缀? - [ ] 对于依赖选项列表:是否设置了
<controllingField>,每个对有一个<valueSettings>(<controllingFieldValue>+<valueName>)? - [ ] 对于依赖选项列表:是否不存在已弃用的
<picklist>/<picklistValues>/<controllingFieldValues>形式? - [ ] 所有选项列表值
<fullName>是否唯一、以字母开头且无连字符?(允许空格——不要用下划线替换,根据§3.4值名称保真度规则)
汇总字段检查 关键
- [ ]
<precision>属性是否不存在? - [ ]
<scale>属性是否不存在? - [ ]
<summaryForeignKey>是否为ChildObject__c.MasterDetailField__c格式? - [ ] 对于SUM/MIN/MAX:
<summarizedField>是否为ChildObject__c.FieldName__c格式? - [ ] 对于COUNT:
<summarizedField>是否不存在? - [ ] 子对象是否有指向此父对象的主从字段?
公式字段检查
- [ ]
<type>是否设置为结果类型(而非"Formula")? - [ ]
<formula>内容是否包裹在<![CDATA[ ... ]]>中? - [ ]
<returnType>属性是否不存在?(Metadata API中不存在) - [ ]
<formulaTreatBlanksAs>是否设置为数值结果的BlankAsZero或文本/日期结果的BlankAsBlank? - [ ] 所有引用的字段是否存在并在此字段之前部署?
数字字段检查
- [ ]
scale ≤ precision? - [ ]
precision ≤ 18?
文本区域检查
- [ ] 对于TextArea:是否省略了
<length>?(API拒绝TextArea字段上的显式<length>值。) - [ ] 对于LongTextArea/Html:是否设置了
<visibleLines>?
关系限制检查
- [ ] 对象上是否有2个或更少的主从关系?
- [ ] 对象上是否有15个或更少的查找关系?
命名检查
- [ ] API名称是否无保留字(
Order、Group、Select等)? - [ ] API名称在此对象上是否唯一?





