platform-custom-field-generate について
SalesforceのCustomFieldメタデータXMLを生成・検証するスキルです。フィールドをデプロイする担当者向けに、リレーション、集計項目、選択リストなどで起きやすいエラーの制約を扱います。
主な機能
- 01CustomFieldメタデータXMLの生成
- 02フィールド型ごとの要件検証
- 03Master-Detail制約への対応
- 04Roll-Up Summary規則への対応
- 05高度な選択リスト設定
活用シーン
- 01デプロイ可能なカスタム項目メタデータの作成
- 02Master-Detailリレーションの構築
- 03集計計算項目の定義
- 04インラインまたは参照型選択リストの設定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ forcedotcom/ sf-skills --skill platform-custom-field-generateインストール後、Claude Code で/platform-custom-field-generateを入力して読み込まれたか確認します。
同梱ファイルreferences/advanced-picklists.md
詳細
Salesforce カスタム項目ジェネレーターおよびバリデーター
概要
Salesforce の CustomField メタデータ XML を生成および検証します。特に、失敗率が最も高い種類であるロールアップサマリーと主従関係を特別に処理します。Metadata API のデプロイエラーを防ぐため、エージェントは XML を出力する前に以下の制約を確認する必要があります。
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> | 常に含める | ラベル以上の価値を加える、エンドユーザー向けの具体的なガイダンスです(例:「税を含む金額を USD で入力してください」。 「金額」ではありません)。 |
<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」、または「[System Name] からの一意のキー」に言及した場合、<externalId>true</externalId> を設定します。
適用可能な種類: テキスト、数値、メール
2. 精度、スケール、長さのルール
デプロイを確実に成功させるため、次の数学的な制約に従います。
精度とスケールのルール
precisionは合計桁数、scaleは小数桁数です- ルール:
precision ≤ 18かつscale ≤ precision - 計算: 小数点より左の桁数 =
precision - scale
「255 固定」ルール
TextArea:<length> を含めないでください。 API は暗黙的に 255 に固定しており、明示的な値を指定すると拒否されます(「Can not specify 'length' for a CustomField of type TextArea」)。この項目に必要なのは <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、scale:2 |
| パーセント | Percent | デフォルトの精度:5、scale: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 に記載しています。単純ではない選択リストを扱う場合は、
このファイルを読み込んでください。以下の括弧内のセクション番号(例:「ref §1」)は、このスキルではなく、
参照ファイルを指しています。重要なルールは次のとおりです。
- 値セットの参照(ref §1)。
<valueSet>には、<valueSetName>(参照)または<valueSetDefinition>(インライン)のどちらか一方を指定します。両方を指定してはいけません。 開発者名は そのまま参照します。Standard セットはIndustry、GlobalValueSet はPriority_Levelsです。__gvsを付けず、__cも付けません(__gvs接尾辞は組織のストレージ上の表示にすぎず、Metadata API ではそのままの名前を使います)。 値セットに基づくフィールドには、<restricted>true</restricted>を指定します。値セットの作成はplatform-value-set-generateスキルの役割であり、このスキルはそれを参照するだけです。 - 値の名前の忠実性(ref §3)。 選択リスト値の
<fullName>/<label>には、ユーザーが指定したテキストを スペースも含めてそのまま使います(Closed_Wonではなく、常にClosed Won)。スペースを_に変換して__cを付けるルールは、フィールド名にのみ適用されます。 - 従属選択リスト(ref §2)。 最新の API 38.0 以降の形式を使います。
<controllingField>と、各ペアにつき 1 つの<valueSettings>(<controllingFieldValue>+<valueName>)を指定します。従来の<picklist>/<picklistValues>/<controllingFieldValues>タグは使わないでください。依存項目と制御項目の 両方に、要求に明記されていなくても<restricted>true</restricted>を指定する必要があります。 - 拡張値属性(ref §3)。
<value>エントリでは、<color>(先頭に#を付けた 16 進数値)、<isActive>(falseにすると値を廃止)、および値レベルの<description>も指定できます。 - 選択リストをレコードタイプに限定する(ref §5)。 レコードタイプごとの値の表示設定は、フィールドではなく
RecordType(
<picklistValues>)に記述します。RecordType ファイルには、独自の<fullName>(そのままの開発者名)が 含まれます。まず、オブジェクトに BusinessProcess が必要か判断してください。 必要なのは Opportunity/Lead/Case/Solution だけです。これらは、カスタム選択リストだけをフィルタリングする場合でも<businessProcess>がないとデプロイできません(Required field is missing: businessProcess)。この場合は、businessProcesses/<Name>.businessProcess-meta.xmlファイルと、対応する<businessProcess><Name></businessProcess>を<RecordType>内に配置した 2 つの関連ファイルを出力します (配置位置は<active>の後、<picklistValues>の前です。BP ファイルの<fullName>はオブジェクト名を付けず、 そのままの名前にします)。カスタムオブジェクト(*__c)と、その他すべての標準オブジェクト(Account、Contact など)には BusinessProcess は不要です。RecordType だけを出力し、作成しないでください。 対象範囲: レコードタイプごとの選択リスト値の表示設定のみです。コンパクトレイアウト、ページレイアウト、ブランディングなど、 レコードタイプ全般の作成は対象外です。
4. 主従関係のルール 重要
主従関係フィールドには、参照関係フィールドとは異なる厳格な属性制限があります。これらのルールに違反すると、デプロイに失敗します。
主従関係フィールドで禁止される属性
主従関係フィールドには、以下の属性を絶対に含めないでください。
| 禁止される属性 | 理由 | 結果 |
|---|---|---|
<required> | 主従関係は仕様上、常に必須です | デプロイエラー |
<deleteConstraint> | 主従関係では常に削除がカスケードされます | デプロイエラー |
<lookupFilter> | 参照関係フィールドでのみサポートされています | デプロイエラー |
主従関係と参照関係の比較
| 属性 | 主従関係 | 参照関係 |
|---|---|---|
<required> | 禁止 | 任意 |
<deleteConstraint> | 禁止(常に CASCADE) | 必須(SetNull、Restrict、Cascade) |
<lookupFilter> | 禁止 | 任意 |
<relationshipOrder> | 必須(0 または 1) | 該当なし |
<reparentableMasterDetail> | 任意 | 該当なし |
<writeRequiresMasterRead> | 任意 | 該当なし |
INCORRECT — 禁止属性を含む主従関係:
<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
CORRECT — 主従関係項目:
<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>
</CustomField>
CORRECT — 参照項目(任意の属性を含む):
<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>
主従関係の追加ルール
- 関係の順序: オブジェクトで最初の主従関係は
0、2 番目は1 - 関係名: 複数形のパスカルケース文字列である必要があります(例:
Travel_Bookings) - ジャンクションオブジェクト: 標準の多対多関係には、2 つの主従関係項目を使用します(積み上げ集計が有効になります)
- 上限: オブジェクトあたりの主従関係は最大 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
INCORRECT — よくあるエラーを含む積み上げ集計:
<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)
CORRECT — 積み上げ集計(SUM 演算):
<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>
</CustomField>
COUNT: SUM と同様ですが、<summarizedField> は省略します(<summaryForeignKey> は残します)。MIN / MAX: SUM と同様に、<summaryOperation>min</summaryOperation> または max を指定します。
積み上げ集計のクイックリファレンス
| 演算 | summarizedField は必須か? | 使用例 |
|---|---|---|
count | いいえ | 子レコード数を数える |
sum | はい | 数値を合計する |
min | はい | 最小値を求める |
max | はい | 最大値を求める |
積み上げ集計の前提条件
- 積み上げ集計項目は、主従関係の親オブジェクトにのみ作成できます
- 子オブジェクトには、この親を参照する主従関係項目が必ず必要です
- 集計対象項目は、子オブジェクトに存在している必要があります
6. 数式項目のルール
数式の戻り値の型
数式自体は型ではありません。<type> が結果のデータ型(Checkbox、Currency、Date、DateTime、Number、Percent、Text)である項目に、<formula> タグを追加します。
- 数式項目に
<length>を指定することはありません — Text を返す数式でも同様です。API はこれを拒否します:Can not specify a length for CustomFields that have a formula。
数式 XML の生成ルール
<formula>タグの内容は、パーサーが数式演算子(&、<、>)を XML マークアップとして読み取らないよう、<![CDATA[ ... ]]>で囲む必要があります。- 数式テキスト自体に文字列
]]>が含まれている場合は、CDATA ブロックを分割してエスケープしてください。例:<![CDATA[Text_Field__c & "]]]]><![CDATA[>"]]> returnTypeという属性やタグは絶対に使用しないでください。これは Metadata API には存在しません。<type>タグで数式の結果の戻り値のデータ型を定義します。
formulaTreatBlanksAs のルール
判定ロジック:
- 数式の結果の型が
Number、Currency、またはPercentの場合 →<formulaTreatBlanksAs>BlankAsZero</formulaTreatBlanksAs>を設定します - 数式の結果の型が
Text、Date、またはDateTimeの場合 →<formulaTreatBlanksAs>BlankAsBlank</formulaTreatBlanksAs>を設定します
誤り — type として Formula を使用:
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>Calculated_Value__c</fullName>
<type>Formula</type>
<returnType>Number</returnType>
<formula>Field1__c + Field2__c</formula>
</CustomField>
正しい例 — 数式項目:
<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>
<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 | ルートの <CustomField> 要素より前に XML コメントが配置されている | .field-meta.xml ファイル内で <CustomField> より前にある XML コメント(``)を削除します |
Field [FieldName] does not exist. Check spelling. | 参照先の項目が存在しないか、まだデプロイされていない | この項目より前に、参照先の項目が存在し、デプロイ済みであることを確認します |
DUPLICATE_DEVELOPER_NAME | 項目の fullName がオブジェクト上にすでに存在する | 業務上の用途に基づく一意の名前を使用します |
MAX_RELATIONSHIPS_EXCEEDED | オブジェクト上の Master-Detail 項目が 2 個、または Lookup 項目が 15 個を超えている | 3 個目以降の Master-Detail には Lookup を使用し、Lookup の数を確認します |
| 予約キーワードエラー | 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 | 2 つの <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 のパーサーを破損させます)
Master-Detail 項目のチェック(重要)
-
<required>属性がありませんか?(Master-Detail は常に必須です) -
<deleteConstraint>属性がありませんか?(Master-Detail は常にカスケードします) -
<lookupFilter>ブロックがありませんか?(Lookup 項目にのみ使用します) -
<relationshipOrder>が0または1に設定されていますか? - 親オブジェクトの
<sharingModel>がControlledByParentに設定されていますか?
参照項目の確認
-
<deleteConstraint>はSetNull、Restrict、またはCascadeに設定されていますか? -
<relationshipName>は複数形のパスカルケースですか?
選択リスト項目の確認
- 各
<valueSet>に含まれているのは<valueSetName>または<valueSetDefinition>のどちらか一方ですか?両方を含めてはいけません。 - 選択リスト値セットの参照では、
<restricted>true</restricted>が設定されていますか? - StandardValueSet を参照する場合、名前は
__cのない列挙型名のみですか(例:Industry)? - GlobalValueSet を参照する場合、名前は
__gvsサフィックスのない開発者名のみですか? - 従属選択リストでは、
<controllingField>が設定され、各ペア(<controllingFieldValue>+<valueName>)に対して<valueSettings>が1つありますか? - 従属選択リストでは、非推奨の
<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 には存在しません) -
<length>がありませんか?(数式項目に length は設定されません。結果が Text の数式でも同様です) - 数値結果の場合は
<formulaTreatBlanksAs>がBlankAsZeroに、テキスト/日付結果の場合はBlankAsBlankに設定されていますか? - 参照されるすべての項目が存在し、この項目より先にデプロイされますか?
数値項目の確認
-
scale ≤ precisionですか? -
precision ≤ 18ですか?
テキストエリアの確認
- TextArea の場合、
<length>は省略されていますか?(API は TextArea 項目に明示的な<length>値が指定されると拒否します) - LongTextArea/Html の場合、
<visibleLines>は設定されていますか?
関係の上限の確認
- オブジェクト上の主従関係は2つ以下ですか?
- オブジェクト上の参照関係は15個以下ですか?
命名の確認
- API 名に予約語(
Order、Group、Selectなど)が含まれていませんか? - API 名はこのオブジェクト上で一意ですか?