您位於此處:
在 Salesforce Spiff 計算中使用壓縮
壓縮會將佣金計算的區段隔離成個別的已命名計算欄位。此技術可減少記憶體使用量、簡化除錯、改善可讀性,並在業務規則變更時更容易維護您的組態。
必要版本
| 提供版本:Salesforce Classic (並非所有組織皆適用) 和 Lightning Experience |
| 提供版本:Enterprise、Unlimited 及 Developer Edition |
| 下列版本亦可額外付費使用:已啟用 Web 服務 API 的 Professional Edition |
什麼是壓縮?
當您撰寫佣金計算時,建立一個合併各個條件、關係和算數運算式的大型運算式很有吸引力。壓縮會採用相反的方法:將邏輯拆分為最小的有意義單位、命名每個單位,並從這些具名部分撰寫最終計算。
壓縮會在計算的欄位層級進行。在結構良好的計畫中,每個計算的欄位都會執行單一作業。較低層級計算會摘要至較高層級計算,其會摘要到最終支出值。
請考慮計畫向代表支付在目前期間已結束之分割交易的佣金,其中代表在年度經常性收入 (ARR) 中的佔有率超過某個值。若未壓縮,單一運算式會結合每個條件和每個算數步驟。
Calculated field, without encapsulation:
=if(CloseDate >= BeginningOfPeriod
AND CloseDate <= EndOfPeriod
AND OwnerId == UserId
AND ContractLength_Months__c > 12
AND Split_Percent__c != null
AND (Split_Percent__c * ARR) >= 20000,
Split_Percent__c * ARR * CommissionRate,
0)此運算式難以閱讀、難以在追蹤中除錯,且很脆弱—欄位重新命名需要尋找並編輯每個參照該運算式的計算。
透過壓縮,每個條件和每個計算值都會成為其自己的具名欄位。最終支出運算式會直接從這些具名欄位讀取。
下列範例同時使用篩選運算式與計算欄位。篩選運算式會傳回 true 或 false,且僅使用布林值邏輯—不支援 if() 陳述式。計算的欄位會傳回值,並支援完整運算式語法。兩者皆受益於壓縮,但原因不同:已計算欄位會得到效能優點 (引擎會評估每個欄位的時間並儲存結果),而篩選運算式會得到結構優點 (更容易閱讀、維護和更新)。
With encapsulation:
// Step 1 — Qualify the period (filter expression)
ClosedInPeriod = CloseDate >= BeginningOfPeriod
AND CloseDate <= EndOfPeriod
// Step 2 — Qualify the rep and deal type (filter expression)
ByRepMultiYear = OwnerId == UserId
AND ContractLength_Months__c > 12
// Step 3 — Compute the split amount (calculated field)
SplitARR = Split_Percent__c * ARR
// Step 4 — Qualify the threshold (filter expression)
SplitARREligible = Split_Percent__c != null
AND SplitARR >= 20000
// Step 5 — Final payout (calculated field)
Payout = if(ClosedInPeriod AND ByRepMultiYear AND SplitARREligible,
SplitARR * CommissionRate,
0)針對計算的欄位,佣金引擎會評估每個欄位一次並儲存結果—後續參照會讀取儲存的值,而非重新計算邏輯。篩選運算式不會共用此行為,因為篩選一律以整體的形式執行,無論其結構為何。
Payout 欄位會讀取四個具名值,而非重新計算相同的算數與日期比較。如果您重新命名 Split_Percent__c,僅更新 SplitARR 和 SplitARREligible,則支出運算式不會受到影響。
壓縮的好處
壓縮提供相較於單一運算式的這些優點。
- 記憶體效率。佣金引擎會針對每個陳述式執行壓縮計算一次,並儲存結果。後續計算會參照讀取儲存的結果,而非重新計算邏輯。對於參照大型資料集或周遊關係的計算而言,此方法特別有用。
- 更容易疑難排解。當支出不正確時,請個別追蹤每個已命名計算,以找出邏輯與預期差異的位置。在先前的範例中,請分別追蹤
ClosedInPeriod、SplitARR和SplitARREligible,以找出哪個條件不正確排除或包含記錄。單一運算式難以檢查,因為佣金引擎會將其評估為單一單位。 - 簡化報告。已命名計算欄位可作為 Spiff 報告的離散資料點使用。單一運算式只會產生其最終輸出。壓縮的欄位可讓您看見中間值,例如,無論是否符合支出資格,都能對
SplitARR進行報告。 - 改善的可讀性。讀取
SplitARR * CommissionRate的最終支出計算比同等巢狀運算式更容易理解。具名欄位會將意圖傳達給未來檢閱計畫的任何人。 - 擴充性。當連接器欄位變更或您更新業務規則時,完全壓縮的組態需要在單一位置進行變更。在先前的範例中,從 20,000 到 25,000 來變更資格,表示僅更新
SplitARREligible。內嵌在內內的單一運算式需要尋找並編輯每個其中包含的篩選條件和計算。
將壓縮套用至關係
物件之間的關係是套用壓縮的最高價值位置之一。每當計算周遊關係以取得欄位時,都會耗用記憶體和處理時間。壓縮關係通話表示工作發生一次。
使用相關物件時,請考量下列方法。
- 可用時使用直接路徑。如果您需要「機會產品」和「機會分割」中的資料,請使用直接 OppProduct 到 OppSplit 關係,而非透過「機會」物件進行路由。路徑愈短,表示路途愈少。
- 使用自我參照關係。您可以建立 OppToOpp 關係,其中唯一索引鍵為 AccountId,而不是將 OppToAccount 和 AccountToOpps 建立為兩個個別的關係。此方法透過單一關係定義達成相同的結果。
- 對相關物件執行計算。您可在相關物件上建立產生所需值的計算欄位,而不是從相關物件提取三個欄位並將其合併到目前物件的計算中。接著,透過關係參照該單一欄位。單一關係呼叫可取用一個欄位,比一個關係呼叫可取用多個欄位更便宜。
例如,您在 OppSplit 物件上建立一個計算的 SplitARR 欄位,而不是透過關係分別參照 OppSplit.SplitPercent 和 OppSplit.ARR 並在「機會」計算中將其乘以。接著「機會」計算會進行單一關係呼叫,以讀取一個預先計算值。
Less efficient — two relationship traversals per record:
Payout = OppSplit.SplitPercent * OppSplit.ARR * Rate
More efficient — one relationship traversal per record:
// On OppSplit object:
SplitARR = SplitPercent * ARR
// On Opportunity object:
Payout = OppSplit.SplitARR * Rate將壓縮套用至捕捉追蹤
壓縮與追蹤會一起運作。由於壓縮的計算是個別的具名欄位 (欄位是獨立且明確識別的),因此您可以選擇性地開啟欄位級的追蹤。您可以關閉代表不需要查看且涉及大型資料集的中繼計算追蹤。開啟最終支出值的追蹤,以及代表在其對帳單上檢閱的主要度量。
| 計算類型 | 追蹤建議 | 原因 |
|---|---|---|
| 關係周遊 | 關閉 | 每個周遊都會儲存其他資料。關閉關係欄位的追蹤,以減少每個陳述式的記憶體消耗。 |
| 累積的變數 | 關閉 | 累積變數會在記錄上執行迴圈,並儲存中繼值。追蹤它們會顯示內部邏輯代表不需要,並大幅增加記憶體使用量。 |
| 雙篩選 | 關閉 | 雙重篩選涉及中繼摘要計算和識別碼清單。追蹤這些步驟會在代表檢視中產生雜訊,而不會新增實用的內容。 |
sum()、count()、let() 函數 |
關閉 | 這些彙總函數會在大型記錄集中作業。追蹤會儲存每個已評估記錄的資料,當記錄數量較高時,這相當昂貴。 |
| YTD 和大型資料集計算 | 關閉 | 年度最新或季度最新總數會掃描大量的歷程記錄。儲存該集中每個記錄的追蹤會耗用大量記憶體。在陳述式上顯示輸出值,但防止引擎儲存完整內部歷程記錄。 |
| 比率表格、配額資料或其他敏感值 | 關閉 | 追蹤可讓代表在對帳單檢視與匯出中看見中繼值。關閉參照代表未獲授權查看之資料的任何欄位上的追蹤,例如其不屬於計畫的比率或配額。 |
| 最終支出欄位與代表面向度量 | 開啟 | 代表依賴追蹤以瞭解其佣金的計算方式。開啟對顯示在對帳單度量卡片和義務清單中的值進行追蹤,以及對 Comp 管理員用於報告和匯出的任何欄位進行追蹤。 |
例如,如果您的支出邏輯包含年度到目前的執行總計作為中間步驟,請將該執行總計壓縮為其自己的欄位,且追蹤已關閉。參照該欄位的 Payout 欄位仍可開啟追蹤,為代表提供最後一個數字,而不會顯示內部累積邏輯。
// YTDCommissions — turn off trace (large dataset, internal only)
YTDCommissions = amounts_from(beginning_of_year(BeginningOfPeriod),
days_ago(BeginningOfPeriod, 1),
plan_name)
// CurrentPeriodPayout — turn on trace (rep-facing)
CurrentPeriodPayout = SplitARR * CommissionRate
// YTDTotal — turn on trace (rep-facing summary metric)
YTDTotal = YTDCommissions + CurrentPeriodPayout
