本文へ移動
cccskills
無料GitHub で公開

compound-field-patterns

Compound fields (Name, Address, Geolocation): SOQL access rules, DML semantics, component access in Apex/LWC, reporting column behavior, formula field restrictions. NOT for creating a new custom field — use admin/custom-field-creation. NOT for formula syntax and functions — use admin/formula-fields. Trigger keywords: BillingAddress, MailingAddress, ShippingAddress, StateCode, CountryCode, GeocodeAccuracy, Location field type, displayLocationInDecimal, __Latitude__s, __Longitude__s, DISTANCE, GEOLOCATION, Custom Address Fields, AddressSettings, System.Address, System.Location, Person Account name.

インストール方法を見る

含まれるファイル(8)

  • SKILL.md19.1 KB
  • references/examples.md12.9 KB
  • references/gotchas.md23.2 KB
  • references/llm-anti-patterns.md6.1 KB
  • references/metadata-examples.md19.1 KB
  • references/well-architected.md14.8 KB
  • scripts/check_compound_field_patterns.py16.9 KB
  • templates/compound-field-patterns-template.md3.5 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Compound Field Patterns

Activate when working with Salesforce compound fields — Name, Address, and Geolocation — in SOQL, Apex DML, LWC, or reports. Compound fields expose a single logical field (the compound) and N component fields (the parts). SOQL rules, DML behavior, and reporting differ in ways that trip up both humans and LLMs.

Before Starting

  • Know the three compound field types. Name (FirstName/LastName/Salutation), Address (Street/City/State/PostalCode/Country/Latitude/Longitude), Geolocation (Latitude/Longitude).
  • Compound in SELECT works; compound in WHERE does not. You can SELECT MailingAddress FROM Contact but not WHERE MailingAddress = ....
  • DML uses component fields. update new Contact(Id=x, MailingCity='SF') — never assign the compound.
  • The compound value exists on three surfaces only. "Compound fields are accessible only through SOAP API, REST API, and Apex. The compound versions of fields aren't accessible anywhere in the Salesforce user interface" (object_reference.txt L2913–L2914). Reports, Visualforce, formulas, Data Loader export and lookup filters all need components.
  • Confirm three org flags before writing anything: State and Country/Territory Picklists (adds -Code components), Custom Address Fields (CustomAddressFieldSettings.enableCustomAddressField, irreversible once true — api_meta.txt L113903–L113909), and Person Accounts (changes what Account.Name accepts).

Questions to Ask Before Configuring

Ask these before opening Object Manager or writing the first query; each answer changes the field names your code targets, and an assistant that skips them writes code that compiles and saves the wrong column.

AskWhy it mattersWhat a good answer adds
"Are State and Country/Territory Picklists enabled here — and in every sandbox on the deploy path?"Decides whether writes target BillingState or BillingStateCode. Address.getStateCode() "returns the state code of this address if state and country/territory picklists are enabled in your organization. Otherwise, returns null" (apexrefguide.txt L199256–L199258)The exact field list every integration, Flow, and load file must target (gotcha 1)
"Which surfaces read this field — Apex, a report filter, a formula, a Flow, Data Loader export?"Only SOAP API, REST API, and Apex can see the compound value at all; every other surface needs componentsThe compound-vs-component decision per surface, from the matrix in references/well-architected.md (gotcha 7)
"Does the requirement need proximity — now, or plausibly next year?"DISTANCE/GEOLOCATION work only against a Location-type compound. Two independent decimal fields never qualify, and converting later is a data migration plus a field-name breaking changeA Location field type chosen at creation, before any data lands
"Is Person Accounts enabled, and can one transaction touch both record types?"Account.Name accepts a direct write on a business Account; on a Person Account it is "the concatenation of the FirstName, MiddleName, LastName, and Suffix of the associated person contact. You can't modify this value" (object_reference.txt L13262–L13266)An IsPersonAccount partition in the bulk code instead of a mixed-batch failure (gotcha 3)
"Do we need an address on an object that has no standard one?"Custom Address Fields is an org-wide enablement, and "Custom Address Fields can't be disabled. When enableCustomAddressField is set to true, you can't change the value to false" (api_meta.txt L113905–L113909)A deliberate, reviewed, one-way enablement — or a decision to use five text fields instead (gotcha 8)
"How many custom fields are left on this object?""Custom geolocation fields count as three custom fields towards your organization's limits: one for latitude, one for longitude, and one for internal use" (object_reference.txt L2874–L2876)The real field budget — see admin/data-model-documentation gotcha 7 for how to document it
"Is any validation rule or formula supposed to check 'the address is filled in'?""As of API version 20.0, validation rules can't have compound fields" (api_meta.txt L45369–L45370), and only ISBLANK, ISCHANGED, and ISNULL accept a compound at allA component-level rule set instead of one rule that will not compile (gotcha 9)

What a proper configuration adds over just reading and writing the field: every write lands on the column the org's flags actually make authoritative, proximity stays possible without a migration, and the rules and reports that need the address are expressed against components that exist on their surface.

Core Concepts

Name compound

Standard objects: Name is read-only compound; update FirstName, LastName, Salutation. Custom objects: Name is plain text unless defined as Person Name type.

Address compound

On Account (BillingAddress, ShippingAddress), Contact (MailingAddress, OtherAddress), Lead, User. The Address type extends Location. Components, verbatim from the Object Reference field table (object_reference.txt L2684–L2726):

ComponentTypeContact example
StreettextareaMailingStreet
CitystringMailingCity
StatestringMailingState
StateCodepicklistMailingStateCode — standard addresses only when state and country/territory picklists are enabled
CountrystringMailingCountry
CountryCodepicklistMailingCountryCode — always available on Custom Address Fields, picklist-gated on standard ones
PostalCodestringMailingPostalCode
Latitude / LongitudedoubleMailingLatitude / MailingLongitude
AccuracypicklistMailingGeocodeAccuracy — standard address fields on standard objects only, populated only once geocoded

Address compound fields are available in the SOAP and REST APIs in API version 30.0 and later.

Geolocation compound

CustomField of type Location (not "Geolocation" — that spelling is not in the FieldType enum, api_meta.txt L45760). Components are addressed by appending __Latitude__s / __Longitude__s to the field name "instead of the usual '__c'" (object_reference.txt L2915–L2917). Geolocation compound fields are available in the SOAP and REST APIs in API version 26.0 and later; Location is not an available custom field type on external objects (api_meta.txt L43233–L43245).

SOQL rules

-- Works: the compound in SELECT, through SOAP API, REST API, or Apex
SELECT Name, BillingAddress FROM Account

-- Fails: "Address fields can't be used in WHERE statements in SOQL"
SELECT Id FROM Account WHERE BillingAddress = :addr

-- Works: components
SELECT Id FROM Account WHERE BillingCity = 'SF' AND BillingStateCode = 'CA'

-- Works: the address compound used as a *location*, not as a filter value
SELECT Id, Name, BillingAddress FROM Account
WHERE DISTANCE(BillingAddress, GEOLOCATION(37.775,-122.418), 'mi') < 20
ORDER BY DISTANCE(BillingAddress, GEOLOCATION(37.775,-122.418), 'mi')
LIMIT 10

The last query is the guide's own sample (object_reference.txt L2836–L2841) and is the reason "no compound in WHERE" needs the qualifier: the compound is not filterable, but it is usable as a location operand inside DISTANCE. DescribeFieldResult.isFilterable() "erroneously returns true for address fields" (object_reference.txt L2950–L2951), so do not gate code on it.

Apex DML

// Works — components
update new Contact(Id = cid, MailingCity = 'SF');

// Fails — "Compound fields are read-only. To update field values, modify the individual field components."
update new Contact(Id = cid, MailingAddress = new Address(...));

// Reading: assign the parent to a typed variable first. Dot notation
// straight through the parent field does not compile.
Address addr = acct.BillingAddress;   // System.Address
String city  = addr.city;             // == addr.getCity()
Location loc = acct.MyLocation__c;    // System.Location
Double lat   = loc.latitude;

// Writing a geolocation: the __Latitude__s / __Longitude__s components
w.Warehouse_Location__Latitude__s  = 37.775;
w.Warehouse_Location__Longitude__s = -122.418;

Address and Location are also standard object names. In Apex, "always use Schema.Address instead of Address" for the object and System.Address for the compound field type; the same disambiguation applies to System.Location vs Schema.Location (apexrefguide.txt L199187–L199190, L221921–L221924).

LWC UI API

@wire(getRecord) returns compound and components; display via {v.fields.MailingAddress.displayValue} or each component individually.

Common Patterns

Pattern: Address update from form

Collect form fields, assign to component fields on a new SObject, DML. When State and Country/Territory Picklists are on, write the -Code component; see references/metadata-examples.md §5 for the load-file column list and references/examples.md Example 1 for the batch shape.

Pattern: Geolocation proximity search

DISTANCE(location1, location2, 'unit') calculates the distance between two location values; GEOLOCATION(latitude, longitude) builds a location from coordinates and must be paired with DISTANCE. DISTANCE() is supported in SELECT, WHERE, and ORDER BY clauses; GEOLOCATION() is supported in WHERE and ORDER BY only. Neither is supported in GROUP BY. Use for store locators — see gotchas.md (Gotcha 6) for the four non-obvious query constraints and examples.md Example 2 for the working Apex pattern.

Pattern: Compute distance in Apex when SOQL cannot

DISTANCE/GEOLOCATION need a query. When both points are already in memory — a user's browser coordinates against a record you already hold — System.Location exposes the same maths without a second query: Location.newInstance(lat, lon), loc1.getDistance(loc2, 'mi'), and the static Location.getDistance(a, b, unit), all documented as "an approximation of the haversine formula" (apexrefguide.txt L221955–L221962). Use these instead of hand-rolling trigonometry; use SOQL DISTANCE whenever the filtering or sorting can happen in the database.

Pattern: Serialize compound to JSON

JSON.serialize(contact.MailingAddress) returns the compound object. Consuming code should use components, not the serialized blob as a key.

Decision Guidance

TaskApproach
Display full addressSelect compound, render via UI API or concatenate components
Filter by cityUse component field (BillingCity)
Update nameUpdate FirstName/LastName, not Name
Proximity searchDISTANCE on Geolocation compound
Report with address columnsUse component columns — the compound value is not accessible in the UI at all
Export addresses with Data LoaderSelect component fields; compound fields "cause error messages" on export
"Address is required" ruleValidation rule on components; compound fields are not allowed in validation rules
Distance rule in a workflow/approval/validation ruleDISTANCE formulas are supported there — the compound field on its own is not

Recommended Workflow

  1. Fill templates/compound-field-patterns-template.md: the compound fields in scope, the three org flags (State and Country/Territory Picklists, Custom Address Fields, Person Accounts), and every surface that reads or writes the field. Answer the Questions table above into it.
  2. Resolve compound-vs-component per surface against the matrix in references/well-architected.md → Architectural Tradeoffs. Anything outside SOAP API, REST API, and Apex resolves to components.
  3. If a new field is needed, take the XML from references/metadata-examples.md §1 (Location field), §2 (CustomAddressFieldSettings) or §3 (AddressSettings) — not from admin/custom-field-creation, which covers the non-compound CustomField elements.
  4. Write the SOQL, the Apex reads and writes, and the Data Loader column mapping from §4–§6 of the same file. Keep the location field first in every DISTANCE call and the unit a literal.
  5. Run python3 scripts/check_compound_field_patterns.py --manifest-dir force-app/main/default. ERROR findings (compound in WHERE, compound DML assignment, DISTANCE without a unit) block the deploy; WARN and INFO findings need a written reason.
  6. Deploy with sf project deploy start --dry-run first, then verify with the describe call and the SOQL in §8–§9 — confirm MailingStateCode is populated, not just MailingState.
  7. Walk references/gotchas.md against the change before sign-off; each gotcha names the surface it breaks and the org flag that triggers it.

Review Checklist

  • No WHERE-clause filters on compound fields
  • DML uses component fields only
  • LWC rendering via UI API displayValue or explicit components
  • Reports using compound columns where appropriate
  • State & Country Picklists considered (adds -Code components)
  • Person Account name semantics documented if Person Accounts enabled
  • Proximity queries use DISTANCE in SOQL, or System.Location.getDistance when both points are already in memory — never hand-rolled trigonometry
  • Validation rules and formulas reference components, not the compound (only ISBLANK, ISCHANGED, ISNULL accept a compound)
  • Data Loader export mappings list components; no compound field is selected
  • Location field XML carries scale and displayLocationInDecimal, and the object's field budget accounts for three fields per geolocation
  • No Address / Location identifier ambiguity in Apex (System. vs Schema.)
  • DISTANCE uses only > / < operators and a literal 'mi'/'km' unit (location field before GEOLOCATION)

Salesforce-Specific Gotchas

  1. State & Country Picklists change components. Adds BillingStateCode / BillingCountryCode alongside text versions; DML requires the code if picklist is enabled.
  2. Name on standard objects cannot be DML-assigned. Only on custom objects (where it's a plain text field anyway).
  3. Serialized compound in JSON integrations is not round-trippable. Always map to components explicitly.
  4. isFilterable() lies about address fields. The describe result reports true; SOQL rejects the filter. Do not build dynamic query builders on that flag.
  5. A custom geolocation field is three fields against the org limit, one in the UI, and absent from Schema Builder and dashboards.

The full set with reproduction and avoidance steps is in references/gotchas.md.

Output Artifacts

ArtifactDescription
Compound-access cheat sheetContext × field-type matrix
DML update templateComponent-assignment patterns
Geolocation query libraryDISTANCE patterns

Reference Files

FileRead it when
references/metadata-examples.mdYou are writing deployable metadata or queries: the Location CustomField XML with scale and displayLocationInDecimal, CustomAddressFieldSettings, AddressSettings, the SOQL set (compound, components, DISTANCE, GEOLOCATION), the Apex read/write patterns, the Data Loader column mapping, package.xml, retrieve/deploy, and the verification describe
references/gotchas.mdThe field saved and something downstream is wrong — a null -Code, an empty report column, a query the parser refuses, a describe flag that lies, or a formula that will not compile. Eleven behaviours with guide line citations
references/examples.mdYou want the scenarios end to end: a 30,000-record address batch under State and Country Picklists, a store-locator proximity query, and the compound-in-a-filter anti-pattern
references/well-architected.mdYou are justifying the design — the pillar mapping, the surface-by-surface compound-vs-component matrix, the three field-shape tradeoffs, and the sources every claim rests on
references/llm-anti-patterns.mdYou are reviewing AI-generated compound-field code and need the six failure modes with detection hints
templates/compound-field-patterns-template.mdWorkflow step 1 — the org-flag and surface inventory
scripts/check_compound_field_patterns.pyWorkflow step 5, before every deploy that touches an address, name, or geolocation field

Related Skills

  • admin/custom-field-creation — the non-compound CustomField elements, the FieldType enum, and general field design; it owns the CustomField XML this skill only extends
  • admin/data-model-documentation — how to document a compound field that counts as three against the limit (its gotcha 7)
  • admin/validation-rules — why ISBLANK(BillingAddress) will not save, and the component-level rules to write instead (its "Compound Fields Cannot Be Used in a Validation Rule at All")
  • admin/formula-fields — formula syntax and which field types are addressable
  • data/soql-query-optimization — selectivity and index behaviour for the component filters this skill sends you to
  • apex/soql-fundamentals — SOQL query patterns

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Use this skill when writing test-first, behavior-driven acceptance criteria in Given/When/Then format for a Salesforce user story. Covers happy path, edge cases, negative paths, permission boundaries, and data-state preconditions so the AC block can drive UAT scripts and Apex test design downstream. Trigger keywords: given when then, gherkin, behavior driven AC, test first acceptance criteria, scenario outline, BDD acceptance criteria. NOT for the user-story format itself (use admin/user-story-writing-for-salesforce). NOT for UAT script writing (use admin/uat-test-case-design). NOT for Apex test method generation (use agents/test-class-generator). NOT for high-level UAT planning (use admin/uat-and-acceptance-criteria). More triggers: acceptance criteria record, ac_id, req_id on a criterion, artefact under test, negative case for a rule-type requirement, no-match fall-through criterion, oracle for a Then clause, test type apex flow manual, criteria linter, check_ac_format.py, --manifest-dir.

日本語の概要は準備中です。原文の説明を表示しています。

PranavNagrecha/AwesomeSalesforceSkills192026年10月4日 更新

Task and Event objects: polymorphic WhatId/WhoId, Activity object model, ActivityHistory vs OpenActivity, activity timeline customization, bulk task creation, Einstein Activity Capture boundaries. NOT for turning on EAC or calendar sync — use admin/einstein-activity-capture-setup. NOT for Email-to-Case — use admin/case-management-setup. Covers ActivitiesSettings metadata, enableActivities, shared Task/Event custom fields and FLS, TaskStatus value sets, Shared Activities and TaskRelation/EventRelation, recurring and child activities, and partial-success bulk DML on Task.

日本語の概要は準備中です。原文の説明を表示しています。

PranavNagrecha/AwesomeSalesforceSkills192026年10月4日 更新

Design Invocable Apex actions that return deterministic, agent-friendly errors instead of surfacing raw exceptions to the LLM. NOT for authoring the action itself — @InvocableMethod schema, labels, security context — use agentforce/custom-agent-actions-apex. NOT for the Apex tests that force each error branch — use agentforce/agent-action-unit-tests.

日本語の概要は準備中です。原文の説明を表示しています。

PranavNagrecha/AwesomeSalesforceSkills192026年10月4日 更新

Use when designing how an Agentforce agent extracts structured input parameters (slots) from a user's natural-language utterance to invoke an action. Triggers: 'agent extract date from user', 'agent action argument extraction', 'agentforce slot filling', 'agent invocable input mapping', 'agent fails to fill required parameter'. NOT for action authoring (use agentforce/agent-actions) or for prompt-template variable binding (use agentforce/prompt-builder-templates).

日本語の概要は準備中です。原文の説明を表示しています。

PranavNagrecha/AwesomeSalesforceSkills192026年10月4日 更新

Apex test patterns for @InvocableMethod agent actions: per-reason-code branch coverage, bulk safety, callout mocking, deterministic assertions. NOT for testing whether the agent routes to the right topic or answers well — use agentforce/agent-testing-and-evaluation. NOT for designing the error envelope the tests assert on — use agentforce/agent-action-error-handling.

日本語の概要は準備中です。原文の説明を表示しています。

PranavNagrecha/AwesomeSalesforceSkills192026年10月4日 更新

Designing or reviewing Agentforce actions: Flow actions, Apex invocable actions, prompt-template actions, action naming, input and output contracts, confirmation requirements, and safe error behavior. Triggers: 'agent actions', 'build an agent that can look up an order', 'make the agent able to check order status', 'give the agent a capability', 'agent that can retrieve a record', 'flow action for agent', 'agent invocable action', 'action schema design'. NOT for writing the Apex class itself — use agentforce/custom-agent-actions-apex. NOT for the reason_code error envelope that stops an agent retry loop — use agentforce/agent-action-error-handling.

日本語の概要は準備中です。原文の説明を表示しています。

PranavNagrecha/AwesomeSalesforceSkills192026年10月4日 更新

PranavNagrecha のスキルをすべて見る

このスキルの問題を報告する