platform-custom-field-generate
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSalesforce Custom Field Generator and Validator
Salesforce自定义字段生成器与验证器
Overview
概述
Generates and validates Salesforce CustomField metadata XML, with special handling for the highest-failure-rate types — Roll-Up Summary and Master-Detail. The agent must verify the constraints below before outputting XML to prevent Metadata API deployment errors.
生成并验证Salesforce CustomField元数据XML,针对失败率最高的字段类型——Roll-Up Summary和Master-Detail提供特殊处理。在输出XML前,代理必须验证以下约束条件,以避免Metadata API部署错误。
1. Universal Mandatory Attributes
1. 通用必填属性
Every generated field must include these tags:
| Attribute | Requirement | Notes |
|---|---|---|
| Required | Field name only: derive from |
| Required | The UI name (Title Case) |
| Always include | Explain the business reason why this field exists. |
| Always include | Actionable end-user guidance that adds value beyond the label (e.g., "Enter the value in USD including tax", not "The amount"). |
<description><inlineHelpText>File path (SFDX source format): save each field as , where is the object's API name (, , or a custom ). A correct XML at the wrong path is never seen by the Metadata API.
force-app/main/default/objects/<Object>/fields/<FieldName>__c.field-meta.xml<Object>AccountOpportunityInventory_Item__c每个生成的字段必须包含以下标签:
| 属性 | 要求 | 说明 |
|---|---|---|
| 必填 | 仅为字段名称:从 |
| 必填 | UI显示名称(标题大小写) |
| 必须包含 | 说明此字段存在的业务原因。 |
| 必须包含 | 为终端用户提供可操作的指导,内容需超出标签本身的价值(例如:"输入包含税费的美元金额",而非"金额")。 |
尽管Metadata API不强制要求和,但输出时必须包含这两项——省略它们会生成低质量的元数据。
<description><inlineHelpText>文件路径(SFDX源格式): 将每个字段保存为,其中是对象的API名称(、或自定义对象)。即使XML内容正确,若路径错误,Metadata API也无法识别。
force-app/main/default/objects/<Object>/fields/<FieldName>__c.field-meta.xml<Object>AccountOpportunityInventory_Item__cExternal ID Configuration
外部ID配置
Trigger: If the user mentions "integration," "importing data," "external system ID," or "unique key from [System Name]," set .
<externalId>true</externalId>Applicable Types: Text, Number, Email
触发条件: 当用户提及"集成"、"导入数据"、"外部系统ID"或"[系统名称]的唯一键"时,设置。
<externalId>true</externalId>适用类型: 文本、数字、邮箱
2. Precision, Scale, and Length Rules
2. 精度、小数位数与长度规则
To ensure deployment success, follow these mathematical constraints:
为确保部署成功,请遵循以下数学约束:
Precision vs. Scale Rules
精度与小数位数规则
- is the total digits;
precisionis the decimal digitsscale - Rule: AND
precision ≤ 18scale ≤ precision - Calculation: Digits to the left of decimal =
precision - scale
- 为总位数;
precision为小数部分位数scale - 规则: 且
precision ≤ 18scale ≤ precision - 计算: 小数点左侧位数 =
precision - scale
The "Fixed 255" Rule
"固定255"规则
TextArea: always include exactly — this literal value is required by the Metadata API and omitting it fails deployment, even though the UI exposes no length control. Unlike every other type where is a value you calculate, TextArea's is a fixed constant.
<length>255</length>lengthTextArea:必须精确包含——Metadata API要求此固定值,即使UI未提供长度控制,省略该值也会导致部署失败。与其他需要计算长度的类型不同,TextArea的长度是固定常量。
<length>255</length>Visible Lines
可见行数
Mandatory for Long/Rich text and Multi-select picklists to control UI height.
对于长文本/富文本和多选选择列表,必须设置可见行数以控制UI高度。
3. Field Data Types
3. 字段数据类型
3.1 Simple Attribute Types
3.1 简单属性类型
| Type | | Required Attributes |
|---|---|---|
| Auto Number | | |
| Checkbox | | Default |
| Date | | No precision/length required |
| Date/Time | | No precision/length required |
| Built-in format validation | |
| Lookup Relationship | | |
| Master-Detail Relationship | | |
| Number | | |
| Currency | | Default precision: 18, scale: 2 |
| Percent | | Default precision: 5, scale: 2 |
| Phone | | Standardizes phone number formatting |
| Picklist | | |
| Text | | |
| Text Area | | |
| Text (Long) | | |
| Text (Rich) | | |
| Time | | Stores time only (no date) |
| URL | | Validates for protocol and format |
| 类型 | | 必填属性 |
|---|---|---|
| 自动编号 | | |
| 复选框 | | 默认 |
| 日期 | | 无需精度/长度 |
| 日期/时间 | | 无需精度/长度 |
| 邮箱 | | 内置格式验证 |
| Lookup关系 | | |
| Master-Detail关系 | | |
| 数字 | | |
| 货币 | | 默认精度:18,小数位数:2 |
| 百分比 | | 默认精度:5,小数位数:2 |
| 电话 | | 标准化电话号码格式 |
| 选择列表 | | |
| 文本 | | |
| 文本区域 | | |
| 长文本 | | |
| 富文本 | | |
| 时间 | | 仅存储时间(不含日期) |
| URL | | 验证协议与格式 |
3.2 Computed & Multi-Value Types
3.2 计算与多值类型
| Type | | Required Attributes |
|---|---|---|
| Formula | Result type (e.g., | |
| Roll-Up Summary | | See Section 5 for complete requirements |
| Multi-Select Picklist | | |
| 类型 | | 必填属性 |
|---|---|---|
| 公式 | 结果类型(例如 | |
| Roll-Up汇总 | | 详见第5节完整要求 |
| 多选选择列表 | | |
3.3 Specialized Types
3.3 特殊类型
| Type | | Required Attributes |
|---|---|---|
| Geolocation | | |
| 类型 | | 必填属性 |
|---|---|---|
| 地理位置 | | |
Picklist restricted
default
restricted选择列表restricted
默认值
restrictedAlways set inside unless the user explicitly says the picklist should accept custom values not in the admin-defined list (e.g. "unrestricted"/"open"). Restricted sets are capped at 1,000 total values (active + inactive). Minimal inline shape:
<restricted>true</restricted><valueSet>xml
<valueSet>
<restricted>true</restricted>
<valueSetDefinition>
<sorted>false</sorted>
<value><fullName>Option_A</fullName><default>false</default><label>Option A</label></value>
</valueSetDefinition>
</valueSet>始终在内设置,除非用户明确说明选择列表应接受管理员定义列表之外的自定义值(例如"非限制"/"开放")。限制集的总数值上限为1000(激活+未激活)。最小内联结构:
<valueSet><restricted>true</restricted>xml
<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 Advanced Picklists
3.4 高级选择列表
The inline above is the simple case. Full rules and worked ✅/❌
examples for everything below are in
— load it for any
non-trivial picklist. Section numbers in parentheses below (e.g. "ref §1") point to that
reference file, not to this skill. The hard rules:
<valueSetDefinition>references/advanced-picklists.md- Value-set reference (ref §1). A holds EITHER
<valueSet>(reference) OR<valueSetName>(inline) — never both. Reference by the bare developer name — Standard set<valueSetDefinition>, GlobalValueSetIndustrywith NOPriority_Levelsand no__gvs(the__csuffix is org-storage display only; the Metadata API uses the bare name). A value-set-backed field is__gvs. Creating the value set is the<restricted>true</restricted>skill's job; this one only references it.platform-value-set-generate - Value-name fidelity (ref §3). A picklist value's /
<fullName>keep the user's exact text including spaces (<label>, neverClosed Won). The space→Closed_Won+_rule is for the FIELD name only.__c - Dependent picklists (ref §2). Use the modern API 38.0+ form: + one
<controllingField>(<valueSettings>+<controllingFieldValue>) per pair; never the legacy<valueName>/<picklist>/<picklistValues>tags. Both controlling and dependent fields MUST be<controllingFieldValues>, even if the request doesn't say so.<restricted>true</restricted> - Enhanced value attributes (ref §3). entries also accept
<value>(hex, leading<color>),#(<isActive>retires a value), and a value-levelfalse.<description> - Scoping a picklist to a record type (ref §5). Per-record-type value visibility lives on the
RecordType (), not the field. The RecordType file carries its own
<picklistValues>(bare developer name). First decide if the object needs a BusinessProcess: only Opportunity / Lead / Case / Solution require one — they won't deploy without a<fullName>(<businessProcess>), even when only a custom picklist is filtered. There you emit two coupled files: theRequired field is missing: businessProcessfile AND a matchingbusinessProcesses/<Name>.businessProcess-meta.xmlinside the<businessProcess><Name></businessProcess>(after<RecordType>, before<active>; the<picklistValues>in the BP file is bare, never object-qualified). Custom objects (<fullName>) and all other standard objects (Account, Contact, …) need NO BusinessProcess — emit the RecordType alone; do not invent one. Scope limit: picklist-value visibility per record type only — NOT general record-type authoring (compact layouts, page layouts, branding).*__c
上述内联是简单场景。以下所有规则及已验证的✅/❌示例均在中——处理非简单选择列表时加载该文件。下文括号中的章节编号(例如"参考§1")指向该参考文件,而非本技能。核心规则:
<valueSetDefinition>references/advanced-picklists.md- 值集引用(参考§1):只能包含
<valueSet>(引用)或<valueSetName>(内联)——不可同时包含两者。引用时使用纯开发者名称——标准集<valueSetDefinition>、GlobalValueSetIndustry无需Priority_Levels或__gvs后缀(__c后缀仅在组织存储显示中使用;Metadata API使用纯名称)。基于值集的字段需设置__gvs。创建值集是<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()上,而非字段上。RecordType文件包含自身的
<picklistValues>(纯开发者名称)。首先判断对象是否需要BusinessProcess: 仅Opportunity / Lead / Case / Solution需要——缺少<fullName>会导致部署失败(错误提示:<businessProcess>),即使仅筛选自定义选择列表。此时需生成两个关联文件:Required field is missing: businessProcess文件,以及在businessProcesses/<Name>.businessProcess-meta.xml内匹配的<RecordType>(位于<businessProcess><Name></businessProcess>之后,<active>之前;BP文件中的<picklistValues>为纯名称,切勿添加对象限定符)。自定义对象(<fullName>)及其他所有标准对象(Account、Contact等)无需BusinessProcess——仅生成RecordType即可,无需额外创建。 限定范围: 仅针对记录类型设置选择列表值可见性——不涉及通用记录类型编写(紧凑布局、页面布局、品牌设置)。*__c
4. Master-Detail Relationship Rules CRITICAL
4. Master-Detail关系规则(关键)
Master-Detail fields have strict attribute restrictions that differ from Lookup fields. Violating these rules causes deployment failures.
Master-Detail字段有严格的属性限制,与Lookup字段不同。违反这些规则会导致部署失败。
Forbidden Attributes on Master-Detail Fields
Master-Detail字段禁用属性
NEVER include these attributes on Master-Detail fields:
| Forbidden Attribute | Why | What Happens |
|---|---|---|
| Master-Detail is ALWAYS required by design | Deployment error |
| Master-Detail ALWAYS cascades deletes | Deployment error |
| Only supported on Lookup fields | Deployment error |
切勿在Master-Detail字段中包含以下属性:
| 禁用属性 | 原因 | 后果 |
|---|---|---|
| Master-Detail设计上始终为必填 | 部署错误 |
| Master-Detail始终级联删除 | 部署错误 |
| 仅支持Lookup字段 | 部署错误 |
Master-Detail vs Lookup Comparison
Master-Detail与Lookup对比
| Attribute | Master-Detail | Lookup |
|---|---|---|
| ❌ FORBIDDEN | ✅ Optional |
| ❌ FORBIDDEN (always CASCADE) | ✅ Required ( |
| ❌ FORBIDDEN | ✅ Optional |
| ✅ Required (0 or 1) | ❌ Not applicable |
| ✅ Optional | ❌ Not applicable |
| ✅ Optional | ❌ Not applicable |
| 属性 | Master-Detail | Lookup |
|---|---|---|
| ❌ 禁用 | ✅ 可选 |
| ❌ 禁用(始终为级联删除) | ✅ 必填( |
| ❌ 禁用 | ✅ 可选 |
| ✅ 必填(0或1) | ❌ 不适用 |
| ✅ 可选 | ❌ 不适用 |
| ✅ 可选 | ❌ 不适用 |
INCORRECT — Master-Detail with forbidden attributes:
错误示例——包含禁用属性的Master-Detail字段:
xml
<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> <!-- WRONG: remove -->
<deleteConstraint>Cascade</deleteConstraint> <!-- WRONG: remove -->
<lookupFilter>...</lookupFilter> <!-- WRONG: remove entire block -->
</CustomField>Errors: · ·
Master-Detail Relationship Fields Cannot be Optional or RequiredCan not specify 'deleteConstraint' for a CustomField of type MasterDetailLookup filters are only supported on Lookup Relationship Fieldsxml
<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 RequiredCan not specify 'deleteConstraint' for a CustomField of type MasterDetailLookup filters are only supported on Lookup Relationship FieldsCORRECT — Master-Detail field:
正确示例——Master-Detail字段:
xml
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>Account__c</fullName>
<label>Account</label>
<description>Links this record to its parent Account</description>
<type>MasterDetail</type>
<referenceTo>Account</referenceTo>
<relationshipLabel>Child Records</relationshipLabel>
<relationshipName>ChildRecords</relationshipName>
<relationshipOrder>0</relationshipOrder>
<reparentableMasterDetail>false</reparentableMasterDetail>
<writeRequiresMasterRead>false</writeRequiresMasterRead>
<!-- NO required, deleteConstraint, or lookupFilter -->
</CustomField>xml
<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>子记录</relationshipLabel>
<relationshipName>ChildRecords</relationshipName>
<relationshipOrder>0</relationshipOrder>
<reparentableMasterDetail>false</reparentableMasterDetail>
<writeRequiresMasterRead>false</writeRequiresMasterRead>
<!-- 无required、deleteConstraint或lookupFilter -->
</CustomField>CORRECT — Lookup field (with optional attributes):
正确示例——Lookup字段(含可选属性):
xml
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>Related_Account__c</fullName>
<label>Related Account</label>
<description>Optional link to a related 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>xml
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>Related_Account__c</fullName>
<label>关联Account</label>
<description>可选关联至相关Account</description>
<type>Lookup</type>
<referenceTo>Account</referenceTo>
<relationshipLabel>关联记录</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>Additional Master-Detail Rules
额外Master-Detail规则
- Relationship Order: First Master-Detail on object = , second =
01 - Relationship Name: Must be a plural PascalCase string (e.g., )
Travel_Bookings - Junction Objects: Use two Master-Detail fields for standard many-to-many (enables Roll-ups)
- Limit: Maximum 2 Master-Detail relationships per object. Use Lookup for additional relationships.
- 关系顺序: 对象上第一个Master-Detail字段设为,第二个设为
01 - 关系名称: 必须为复数帕斯卡命名法字符串(例如)
Travel_Bookings - ** junction对象:** 使用两个Master-Detail字段实现标准多对多关系(支持汇总)
- 限制: 每个对象最多支持2个Master-Detail关系。额外关系请使用Lookup。
5. Roll-Up Summary Field Rules CRITICAL
5. Roll-Up Summary字段规则(关键)
Roll-up Summary fields have the highest deployment failure rate. Follow these rules exactly.
Roll-Up Summary字段的部署失败率最高。请严格遵循以下规则。
Required Elements for Roll-Up Summary
Roll-Up Summary必填元素
| Element | Requirement | Format |
|---|---|---|
| Required | Always |
| Required | |
| Required | |
| Conditional | Required for |
| 元素 | 要求 | 格式 |
|---|---|---|
| 必填 | 始终为 |
| 必填 | |
| 必填 | |
| 条件必填 | |
Forbidden Elements on Roll-Up Summary
Roll-Up Summary禁用元素
NEVER include these attributes on Roll-Up Summary fields:
| Forbidden Attribute | Why |
|---|---|
| Summary inherits from summarized field |
| Summary inherits from summarized field |
| Not applicable to Summary fields |
| Not applicable to Summary fields |
切勿在Roll-Up Summary字段中包含以下属性:
| 禁用属性 | 原因 |
|---|---|
| 汇总字段继承自被汇总字段 |
| 汇总字段继承自被汇总字段 |
| 不适用于汇总字段 |
| 不适用于汇总字段 |
Format Rules for summaryForeignKey and summarizedField
summaryForeignKey和summarizedField格式规则
CRITICAL: Both and MUST use the fully qualified format:
summaryForeignKeysummarizedFieldtext
ChildObjectAPIName__c.FieldAPIName__cDecision Logic:
- =
summaryForeignKeyChildObject__c.MasterDetailFieldOnChild__c - =
summarizedFieldChildObject__c.FieldToSummarize__c
关键: 和必须使用完全限定格式:
summaryForeignKeysummarizedFieldtext
ChildObjectAPIName__c.FieldAPIName__c决策逻辑:
- =
summaryForeignKeyChildObject__c.MasterDetailFieldOnChild__c - =
summarizedFieldChildObject__c.FieldToSummarize__c
INCORRECT — Roll-Up Summary with common errors:
错误示例——包含常见错误的Roll-Up Summary字段:
xml
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>Total_Amount__c</fullName>
<label>Total Amount</label>
<type>Summary</type>
<precision>18</precision> <!-- WRONG: Remove - inherited from source -->
<scale>2</scale> <!-- WRONG: Remove - inherited from source -->
<summaryOperation>sum</summaryOperation>
<summaryForeignKey>Order__c</summaryForeignKey> <!-- WRONG: Missing field name -->
<summarizedField>Amount__c</summarizedField> <!-- WRONG: Missing object name -->
</CustomField>Errors:
Can not specify 'precision' for a CustomField of type SummaryMust specify the name in the CustomObject.CustomField format (e.g. Account.MyNewCustomField)
xml
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>Total_Amount__c</fullName>
<label>总金额</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)
CORRECT — Roll-Up Summary (SUM operation):
正确示例——Roll-Up Summary(SUM操作):
xml
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>Total_Amount__c</fullName>
<label>Total Amount</label>
<description>Sum of all line item amounts</description>
<inlineHelpText>Automatically calculated from child line items</inlineHelpText>
<type>Summary</type>
<summaryOperation>sum</summaryOperation>
<summarizedField>Order_Line_Item__c.Amount__c</summarizedField>
<summaryForeignKey>Order_Line_Item__c.Order__c</summaryForeignKey>
<!-- NO precision, scale, required, or length -->
</CustomField>COUNT: identical structure to SUM but omit entirely (and keep ). MIN / MAX: identical to SUM — just or , with pointing at the field to find the minimum/maximum of. The Quick Reference table below covers all four.
<summarizedField><summaryForeignKey><summaryOperation>min</summaryOperation>max<summarizedField>xml
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>Total_Amount__c</fullName>
<label>总金额</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相同,但完全省略(保留)。MIN / MAX操作: 结构与SUM相同——仅将设为或,指向需查找最小值/最大值的字段。下方快速参考表涵盖所有四种操作。
<summarizedField><summaryForeignKey><summaryOperation>minmax<summarizedField>Roll-Up Summary Quick Reference
Roll-Up Summary快速参考
| Operation | summarizedField Required? | Use Case |
|---|---|---|
| NO | Count number of child records |
| YES | Add up numeric values |
| YES | Find smallest value |
| YES | Find largest value |
| 操作 | 是否需要summarizedField? | 使用场景 |
|---|---|---|
| 否 | 统计子记录数量 |
| 是 | 汇总数值 |
| 是 | 查找最小值 |
| 是 | 查找最大值 |
Roll-Up Summary Prerequisites
Roll-Up Summary前置条件
- Roll-Up Summary fields can ONLY be created on the parent object in a Master-Detail relationship
- The child object MUST have a Master-Detail field pointing to this parent
- The summarized field must exist on the child object
- Roll-Up Summary字段只能在Master-Detail关系的父对象上创建
- 子对象必须有指向该父对象的Master-Detail字段
- 被汇总字段必须存在于子对象上
6. Formula Field Rules
6. 公式字段规则
Formula Result Types
公式结果类型
A Formula is not a type itself. The tag is added to a field whose is set to the result data type:
<formula><type>- ,
Checkbox,Currency,Date,DateTime,Number,PercentText
公式本身并非一种类型。标签需添加至设为结果数据类型的字段中:
<formula><type>- 、
Checkbox、Currency、Date、DateTime、Number、PercentText
Formula XML Generation Rules
公式XML生成规则
- The contents of the tag MUST be wrapped in a
<formula>section. This prevents the XML parser from interpreting formula operators (like<![CDATA[ ... ]]>,&,<) as XML markup.> - If the formula text itself contains the literal sequence , escape it by breaking the CDATA block: e.g.,
]]><![CDATA[Text_Field__c & "]]]]><![CDATA[>"]]> - NEVER use an attribute or tag named . This does not exist in the Metadata API. The
returnTypetag defines the return data type of the formula result.<type>
- 标签的内容必须包裹在
<formula>块中。这可避免XML解析器将公式运算符(如<![CDATA[ ... ]]>、&、<)视为XML标记。> - 若公式文本本身包含文字序列,需通过拆分CDATA块进行转义:例如
]]><![CDATA[Text_Field__c & "]]]]><![CDATA[>"]]> - 切勿使用名为的属性或标签。Metadata API中不存在该属性。
returnType标签定义公式结果的返回数据类型。<type>
formulaTreatBlanksAs Rule
formulaTreatBlanksAs规则
Decision Logic:
- IF formula result type = ,
Number, orCurrency→ setPercent<formulaTreatBlanksAs>BlankAsZero</formulaTreatBlanksAs> - IF formula result type = ,
Text, orDate→ setDateTime<formulaTreatBlanksAs>BlankAsBlank</formulaTreatBlanksAs>
决策逻辑:
- 若公式结果类型为、
Number或Currency→ 设置Percent<formulaTreatBlanksAs>BlankAsZero</formulaTreatBlanksAs> - 若公式结果类型为、
Text或Date→ 设置DateTime<formulaTreatBlanksAs>BlankAsBlank</formulaTreatBlanksAs>
INCORRECT — Using Formula as type:
错误示例——将Formula作为类型:
xml
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>Calculated_Value__c</fullName>
<type>Formula</type> <!-- WRONG: Formula is not a valid type -->
<returnType>Number</returnType> <!-- WRONG: returnType does not exist in Metadata API -->
<formula>Field1__c + Field2__c</formula> <!-- WRONG: Missing CDATA wrapper -->
</CustomField>xml
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>Calculated_Value__c</fullName>
<type>Formula</type> <!-- 错误:Formula并非有效类型 -->
<returnType>Number</returnType> <!-- 错误:returnType在Metadata API中不存在 -->
<formula>Field1__c + Field2__c</formula> <!-- 错误:缺少CDATA包裹 -->
</CustomField>CORRECT — Formula field:
正确示例——公式字段:
xml
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>Calculated_Value__c</fullName>
<label>Calculated Value</label>
<description>Sum of Field1 and Field2</description>
<type>Number</type> <!-- Result type, not "Formula" -->
<precision>18</precision>
<scale>2</scale>
<formula><![CDATA[Field1__c + Field2__c]]></formula>
<formulaTreatBlanksAs>BlankAsZero</formulaTreatBlanksAs>
</CustomField>xml
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>Calculated_Value__c</fullName>
<label>计算值</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>Formula Field Dependencies & Functions
公式字段依赖与函数
- Formula fields that reference other fields fail deployment if the referenced field doesn't exist or hasn't deployed yet — deploy referenced fields first.
- Use (not
ISPICKVAL()) for picklist comparisons.== - For the full formula-function reference (TEXT/VALUE/CASE/DAY/MONTH/DATEVALUE/ISCHANGED type rules), defer to the skill, which owns formula-function correctness.
platform-validation-rule-generate
- 引用其他字段的公式字段,若被引用字段不存在或尚未部署,会导致部署失败——需先部署被引用字段。
- 比较选择列表时使用(而非
ISPICKVAL())。== - 如需完整的公式函数参考(TEXT/VALUE/CASE/DAY/MONTH/DATEVALUE/ISCHANGED等类型规则),请参考技能,该技能负责公式函数的正确性。
platform-validation-rule-generate
7. Common Deployment Errors
7. 常见部署错误
| Error Message | Cause | Fix |
|---|---|---|
| XML comments placed before the root | Remove XML comments ( |
| Referenced field does not exist or has not been deployed yet | Verify the referenced field exists and is deployed before this field |
| Field fullName already exists on the object | Use a unique business-driven name |
| More than 2 Master-Detail or 15 Lookup fields on the object | Use Lookup for 3rd+ Master-Detail; review Lookup count |
| Reserved keyword error | Using | Rename to |
| | Keep exactly one (see Section 3.4) |
| Two | Make every picklist value |
| Value | Start with a letter; no hyphens, no leading digit. Spaces ARE allowed — do NOT underscore them (see §3.4 value-name fidelity) |
| Deprecated ≤37.0 dependent-picklist syntax ( | Use the modern |
| 错误提示 | 原因 | 修复方案 |
|---|---|---|
| XML注释放置在根 | 移除 |
| 引用的字段不存在或尚未部署 | 验证引用字段已存在且已部署,再部署此字段 |
| 字段fullName已存在于该对象上 | 使用唯一的业务驱动名称 |
| 对象上的Master-Detail字段超过2个,或Lookup字段超过15个 | 第3个及以上的Master-Detail关系改用Lookup;检查Lookup字段数量 |
| 保留关键字错误 | 使用 | 重命名为 |
| | 仅保留其中一项(见第3.4节) |
| 两个 | 确保每个选择列表值的 |
选择列表值的 | 值的 | 以字母开头;无连字符,无前置数字。允许使用空格——请勿替换为下划线(见§3.4值名称保真规则) |
| 使用了已弃用的≤37.0版本依赖选择列表语法( | 使用现代的 |
8. Verification Checklist
8. 验证检查清单
Before generating CustomField XML, verify:
生成CustomField XML前,请验证以下内容:
Universal Checks
通用检查
- Does use valid format and end in
<fullName>?__c - Are and
<description>both populated and meaningful?<inlineHelpText> - Is in Title Case?
<label> - Are there no XML comments () before the root
<!-- ... -->element? (Comments before the root element break SDR's parser)<CustomField>
- 是否使用有效格式并以
<fullName>结尾?__c - 和
<description>是否均已填充且内容有意义?<inlineHelpText> - 是否为标题大小写?
<label> - 根元素之前是否无XML注释(
<CustomField>)?(根元素前的注释会破坏SDR解析器)<!-- ... -->
Master-Detail Field Checks CRITICAL
Master-Detail字段检查(关键)
- Is attribute ABSENT? (Master-Detail is always required)
<required> - Is attribute ABSENT? (Master-Detail always cascades)
<deleteConstraint> - Is block ABSENT? (Only for Lookup fields)
<lookupFilter> - Is set to
<relationshipOrder>or0?1 - Is parent object's set to
<sharingModel>?ControlledByParent
- 属性是否已移除?(Master-Detail始终为必填)
<required> - 属性是否已移除?(Master-Detail始终级联删除)
<deleteConstraint> - 代码块是否已移除?(仅适用于Lookup字段)
<lookupFilter> - 是否设为
<relationshipOrder>或0?1 - 父对象的是否设为
<sharingModel>?ControlledByParent
Lookup Field Checks
Lookup字段检查
- Is set to
<deleteConstraint>,SetNull, orRestrict?Cascade - Is in plural PascalCase?
<relationshipName>
- 是否设为
<deleteConstraint>、SetNull或Restrict?Cascade - 是否为复数帕斯卡命名法?
<relationshipName>
Picklist Field Checks
选择列表字段检查
- Does each contain EITHER
<valueSet>OR<valueSetName>— never both?<valueSetDefinition> - For a value-set reference: is set?
<restricted>true</restricted> - For a StandardValueSet reference: is the name the bare enum with NO (e.g.
__c)?Industry - For a GlobalValueSet reference: is the name the bare developer name with NO suffix?
__gvs - For dependent picklists: is set, with one
<controllingField>(<valueSettings>+<controllingFieldValue>) per pair?<valueName> - For dependent picklists: is the deprecated /
<picklist>/<picklistValues>form ABSENT?<controllingFieldValues> - Are all picklist value values unique, start with a letter, and free of hyphens? (spaces are allowed — do NOT replace them with underscores, per the §3.4 value-name fidelity rule)
<fullName>
- 每个是否仅包含
<valueSet>或<valueSetName>——不同时包含两者?<valueSetDefinition> - 对于值集引用:是否设置了?
<restricted>true</restricted> - 对于StandardValueSet引用:名称是否为纯枚举值,无后缀(例如
__c)?Industry - 对于GlobalValueSet引用:名称是否为纯开发者名称,无后缀?
__gvs - 对于依赖选择列表:是否设置了,且每个配对对应一个
<controllingField>(<valueSettings>+<controllingFieldValue>)?<valueName> - 对于依赖选择列表:是否已移除已弃用的/
<picklist>/<picklistValues>格式?<controllingFieldValues> - 所有选择列表值的是否唯一、以字母开头且无连字符?(允许使用空格——请勿替换为下划线,遵循§3.4值名称保真规则)
<fullName>
Roll-Up Summary Field Checks CRITICAL
Roll-Up Summary字段检查(关键)
- Is attribute ABSENT?
<precision> - Is attribute ABSENT?
<scale> - Is in format
<summaryForeignKey>?ChildObject__c.MasterDetailField__c - For SUM/MIN/MAX: Is in format
<summarizedField>?ChildObject__c.FieldName__c - For COUNT: Is ABSENT?
<summarizedField> - Does the child object have a Master-Detail field to this parent?
- 属性是否已移除?
<precision> - 属性是否已移除?
<scale> - 是否为
<summaryForeignKey>格式?ChildObject__c.MasterDetailField__c - 对于SUM/MIN/MAX:是否为
<summarizedField>格式?ChildObject__c.FieldName__c - 对于COUNT:是否已移除?
<summarizedField> - 子对象是否有指向该父对象的Master-Detail字段?
Formula Field Checks
公式字段检查
- Is set to result type (NOT "Formula")?
<type> - Is content wrapped in
<formula>?<![CDATA[ ... ]]> - Is attribute ABSENT? (does not exist in Metadata API)
<returnType> - Is set to
<formulaTreatBlanksAs>for numeric results orBlankAsZerofor text/date results?BlankAsBlank - Do all referenced fields exist and deploy before this field?
- 是否设为结果类型(而非"Formula")?
<type> - 内容是否包裹在
<formula>中?<![CDATA[ ... ]]> - 属性是否已移除?(Metadata API中不存在)
<returnType> - 是否针对数值结果设为
<formulaTreatBlanksAs>,或针对文本/日期结果设为BlankAsZero?BlankAsBlank - 所有引用字段是否已存在且先于此字段部署?
Numeric Field Checks
数字字段检查
- Is ?
scale ≤ precision - Is ?
precision ≤ 18
- 是否满足?
scale ≤ precision - 是否满足?
precision ≤ 18
Text Area Checks
文本区域检查
- For TextArea: Is explicitly included?
<length>255</length> - For LongTextArea/Html: Is set?
<visibleLines>
- 对于TextArea:是否明确包含?
<length>255</length> - 对于LongTextArea/Html:是否设置了?
<visibleLines>
Relationship Limit Checks
关系限制检查
- Are there 2 or fewer Master-Detail relationships on the object?
- Are there 15 or fewer Lookup relationships on the object?
- 对象上的Master-Detail关系是否≤2个?
- 对象上的Lookup关系是否≤15个?
Naming Checks
命名检查
- Is the API name free of reserved words (,
Order,Group, etc.)?Select - Is the API name unique on this object?
- API名称是否不含保留字(、
Order、Group等)?Select - API名称在该对象上是否唯一?