サーチ…


備考

前書き

カスタム設定では、それらに基づいたレコードを持つカスタムオブジェクトとは異なり、組織全体でカスタムデータセットを使用したり、カスタム条件に基づいて特定のユーザーやプロファイルを区別したりできます。たとえば、管理者が階層カスタム設定を編集して、単一のユーザーまたはプロファイルのワークフロー/検証ルールを無効にすることができます(上記のワークフロー/検証ルールを無効にする階層カスタム設定の使用を参照してください) )。

検証ルールは、一般的に次の場合に一時的に無効にする必要があります。

  • コードは、検証ルールがアクティブ化される前に最後に編集された古いレコードを更新するため、新しいルールの基準を満たしていません。
  • コードは、検証ルールの基準によって必要とされる値のない新しいレコードを挿入しています。

ワークフロールールは、通常、次の場合に一時的に無効にする必要があります。

  • 電子メールアラートまたはフィールド更新をトリガーし、レコードに加えた変更を上書きまたは干渉させます。

カスタム設定を使用すると、管理者はコードに対していくつかの宣言的な制御を許可するので、多くのユースケースの1つは、利用時にトリガーを無効にするためにコードをデプロイする必要がないということです(上記のApexコードを無効にする階層カスタム設定の使用)。

開発者にとっての主な利点は、カスタム設定のデータがアプリケーションキャッシュに公開され、データベースへの繰り返しクエリのコストをかけずに効率的にアクセスできることです。このデータは、数式フィールド、検証ルール、フロー、Apex、およびSOAP APIで使用できます 。詳細はSalesforceのドキュメントを参照してください。

カスタム設定の制限と考慮事項については、 ここで説明します

カスタム設定の一覧表示

List Custom Settingsも作成できます。一般的な使用例には、2文字の州の略語、国際ダイヤルプレフィックス、製品のカタログ番号などが格納されています。ただし、Salesforceでは、カスタム設定の一覧ではなく、カスタムメタデータの種類の使用を促進しています。

新しいカスタム設定を作成すると、次のメッセージが表示されます

ヒント:アプリケーションの設定にカスタムメタデータタイプを使用する
リストのカスタム設定を使用することを考えている場合は、代わりにカスタムメタデータタイプを使用することを検討してください。リストのカスタム設定とは異なり、パッケージまたはメタデータAPIツールを使用してカスタムメタデータタイプのレコードを移行できます。

カスタムメタデータタイプには、この回答で説明されているように、リストのカスタム設定との追加の利点があります 。 CMDの主任開発者によると、 「カスタムメタデータの種類については、ステロイドのカスタム設定よりもはるかに多く計画されている」

カスタム設定の作成と管理

創造

カスタム設定を作成するには、

クラシック
セットアップ>開発>カスタム設定>新規

ライトニング
セットアップ>カスタムコード>カスタム設定>新規

設定を作成します(階層とリストのカスタム設定の違いについては、このドキュメントの後半の「備考」を参照してください)。管理対象パッケージに設定を展開する場合を除いて、Visibilityピックリストは無視できます。

設定フィールドを作成するには、[新規作成]ボタンをクリックし、 通常のカスタムフィールド作成プロセスに従います。

管理

フィールドを作成したら、[管理]ボタンをクリックして設定を開始できます。

新しいビューを作成し、設定の包括的な概要を一目で把握するために作成したフィールドを追加すると、設定を管理する方が簡単です。セットアップオーナーは、設定が適用されるユーザーまたはプロファイルです。

組織レベルで設定を管理するには、Default Organization Level Valueヘッダーの上にある新しいボタン(下の赤いボックス)をクリックします。

ユーザーまたはプロファイルレベルで設定を管理するには、下の青いボックスの[新規]ボタンをクリックします。

カスタム設定の編集

階層のカスタム設定を使用してワークフロー/検証ルールを無効にする

カスタム設定

カスタム設定

カスタム設定フィールド

カスタム設定フィールド

カスタム設定フィールドの値

フィールドがチェックされると、実行中のユーザーまたはこの例では、ユーザーのプロファイルの検証規則が無効になります。

カスタム設定フィールド編集 - プロファイル

このルールは、Salesforce組織全体で無効にすることもできます。

カスタム設定フィールド編集 - 組織

検証ルール

AND(
  /* the below is the reference to the Val_Rule_Cntrlr__c custom setting's checkbox field All_Opportunity_Disabled__c
  */
  $Setup.Val_Rule_Cntrlr__c.All_Opportunity_Disabled__c = FALSE,

  /* the below is the remainder of the validation rule's formula
  */
  CloseDate < TODAY()
)

上記のルールでは、ルールがトリガーされるためには、両方の基準がTRUEに評価されなければなりません。

実行中のユーザーのプロファイルがシステム管理者の場合、 All_Opportunity_Disabled__cチェックボックスはTRUEに評価されるため、ルールはFALSEと評価されFALSE

ワークフロールール

ワークフロールールを無効にする場合も同じアプローチを適用できます。

階層カスタム設定を使用してApexコードを無効にする

説明

この例では、挿入または更新しようとしている案件の締め切り日を10日後の日付に変更する簡単なトリガーが作成されています。

Apexコントローラのカスタム設定のチェックボックスフィールドでは、ユーザ/プロファイル/組織レベルでコードを無効にすることができます。

エイペックスクラス

trigger CloseDateUpdate on Opportunity (before insert, before update) {
    
    Id userId;
    Apx_Cntrlr__c userApexController;
    Boolean userSetting;
    
    userId = userinfo.getUserId();
    userApexController = Apx_Cntrlr__c.getInstance(userId);
    userSetting = userApexController.Close_Date_Update_Disabled__c;

    if (userSetting == false) {
        for(Opportunity opp : Trigger.new) {
            opp.CloseDate = date.today().addDays(10);
        }
    }
    
}

単体テスト

@isTest
public class CloseDateUpdateTest {
    
    @testSetup
    static void dataSetup() {
        
        Profile p = [SELECT Id FROM Profile WHERE Name = 'System Administrator' LIMIT 1];
        
        User u = new User(LastName = 'Test',Alias = 't1',Email = '[email protected]',Username = '[email protected]',ProfileId = p.Id,TimeZoneSidKey = 'America/Denver',LocaleSidKey = 'en_US',EmailEncodingKey = 'UTF-8',LanguageLocaleKey = 'en_US');
        insert u;
    }
    
    static testMethod void testCloseDateUpdateEnabled() {
        
        User u = [SELECT Id FROM User WHERE Username = '[email protected]'];
        // set the custom setting field to FALSE so that the trigger is not deactivated
        Apx_Cntrlr__c apexController = new Apx_Cntrlr__c(SetupOwnerId = u.Id,Close_Date_Update_Disabled__c = false);
        upsert apexController;
        
        Opportunity[] opportunities1 = new Opportunity[]{};
        
        test.startTest();
        system.runAs(u){
                
                for(integer i = 0; i < 200; i++) {
                    opportunities1.add(new Opportunity(
                        Name          = 'Test Opp ' + i,
                        OwnerId       = u.Id,
                        StageName     = 'Prospecting',
                        CloseDate     = date.today().addDays(1),
                        Amount        = 100));
                }
            insert opportunities1;
        }
        test.stopTest();
        
        List<Opportunity> opportunities2 = [SELECT CloseDate FROM Opportunity];
        
        for(Opportunity o : opportunities2){
            system.assertEquals(date.today().addDays(10), o.closeDate, 'CloseDateUpdate trigger should have changed the Opportunity close date as it was not disabled by the apexController custom setting');
        }
    }
    
    static testMethod void testCloseDateUpdateDisabled() {
        
        User u = [SELECT Id FROM User WHERE Username = '[email protected]'];
        // set the custom setting field to TRUE to deactivate the trigger
        Apx_Cntrlr__c apexController = new Apx_Cntrlr__c(SetupOwnerId = u.Id,Close_Date_Update_Disabled__c = true);
        upsert apexController;
        
        Opportunity[] opportunities1 = new Opportunity[]{};
            
        test.startTest();
        system.runAs(u){
            
            for(integer i = 0; i < 200; i++) {
                opportunities1.add(new Opportunity(
                    Name          = 'Test Opp ' + i,
                    OwnerId       = u.Id,
                    StageName     = 'Prospecting',
                    CloseDate     = date.today().addDays(1),
                    Amount        = 100));
            }
            insert opportunities1;
        }
        test.stopTest();
        
        List<Opportunity> opportunities2 = [SELECT CloseDate FROM Opportunity];
        
        for(Opportunity o : opportunities2){
            system.assertEquals(date.today().addDays(1), o.closeDate, 'CloseDateUpdate trigger should not have changed the Opportunity close date as it was disabled by the apexController custom setting');
        }
    }
        
}

Apexコードの階層カスタム設定の更新

検証やワークフローのルールを無効にするために、コードの実行中にカスタム設定を更新することができます。

以下のコードでは、 スケジュール可能なApexクラスを作成しました。このクラスは、終了日が現在の日付から6日以内の任意の案件の終了日を更新し、将来20日に変更します。

私はカスタム設定Val_Rule_Cntrlr__cを使用して、自分の基準を満たす機会を更新できないような検証ルールを無効にします。

global class Scheduled_OppCloseDateUpdate implements Schedulable {

    global void execute(SchedulableContext SC) {
        updOpportunityCloseDates();
    }

    global void updOpportunityCloseDates() {
        
        Id userId;
        Val_Rule_Cntrlr__c setting;
        Boolean validationRulesAlreadyDisabled;
        List<Opportunity> processedOpps = new List<Opportunity>();
        Date d;
        
        // get running user's Id
        userId = userinfo.getUserId();
        // retrieve Custom Setting status, for running user
        setting = Val_Rule_Cntrlr__c.getInstance(userId);
        
        // if the setting field is false, update it to disable validation rules
        if (setting.All_Opportunity_Disabled__c == false) {
            setting.All_Opportunity_Disabled__c = true;
            upsert setting;
        }
        // if the setting field was already true, there's no need to disable it
        // but it shouldn't be switched to false by this class once the process has been completed
        else {
            validationRulesAlreadyDisabled = true;
        }
        
        // execute code to manage business process
   
        d = system.today().addDays(6);
        
        for(Opportunity o : [SELECT Id, CloseDate
                               FROM Opportunity
                              WHERE CloseDate <= :d
                                // class only updates open Opportunities
                                AND Probability > 0 AND Probability < 100])
        {
            o.CloseDate = System.today().addDays(20);
            processedOpps.add(o);
        }
        
        if (processedOpps.size() > 0) {
            update processedOpps;
        }
        
        // reactivate validation rules
        if (validationRulesAlreadyDisabled == false) {
            setting.All_Opportunity_Disabled__c = false;
            upsert setting;
        }
        
    }
    
}

私のクラスの私のカスタム設定の変更によって私のバリデーションルールが無効にされていることを確認するために、 Trigger_Validation_Rule__c (ユーザには見えないか、ページレイアウトに追加されない)チェックボックスフィールドと、

AND(
  $Setup.Val_Rule_Cntrlr__c.All_Opportunity_Disabled__c = FALSE,
  Trigger_Validation_Rule__c = TRUE,

  /* allow the above criteria to be met while inserting the Opportunities, without triggering the rule, in the @testSetup portion of the test */
  NOT(ISNEW())
)

カスタム設定フィールドが自分のコードで編集されていない場合、ルールの基準が満たされるように案件を作成するときに、チェックボックスフィールドをtrueに設定します。

@isTest
private class WE_ScheduledCloseDateUpdateTest {

    @testSetup
    static void dataSetup() {

        Profile p = [SELECT Id FROM Profile WHERE Name = 'System Administrator' LIMIT 1];
        
        User u = new User(LastName = 'Test',Alias = 't1',Email = '[email protected]',Username = '[email protected]',ProfileId = p.Id,TimeZoneSidKey = 'America/Denver',LocaleSidKey = 'en_US',EmailEncodingKey = 'UTF-8',LanguageLocaleKey = 'en_US');
        insert u;

        Val_Rule_Cntrlr__c valRuleCntrlr = new Val_Rule_Cntrlr__c(SetupOwnerId = u.Id,All_Opportunity_Disabled__c = false);
        upsert valRuleCntrlr;
            
        List<Opportunity> testOpps = new List<Opportunity>();
            
        // create the Opportunities that will be updated by the class
        for(integer i = 0; i < 200; i++) {
            testOpps.add(new Opportunity(
                Name          = 'Test Opp Update' + i,
                OwnerId       = u.Id,
                StageName     = 'Prospecting',
                CloseDate     = date.today().addDays(1),
                Amount        = 100,
                // set checkbox field to true, to trigger validation rules if they've not been deactivated by class
                Trigger_Validation_Rule__c = true));
        }
        // create the Opportunities that won't be updated by the class
        for(integer i = 0; i < 200; i++) {
            testOpps.add(new Opportunity(
                Name          = 'Test Opp Skip' + i,
                OwnerId       = u.Id,
                StageName     = 'Prospecting',
                CloseDate     = date.today().addDays(15),
                Amount        = 100,
                Trigger_Validation_Rule__c = true));
        }           
        insert testOpps;

    }
    
    // code required to test a scheduled class, see https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_scheduler.htm for more details
    public static String CRON_EXP = '0 0 0 15 3 ? 2022';

    static testmethod void testCloseDateUpdates() {

        // execute scheduled class
        
        Test.startTest();
        
        String jobId = System.schedule('ScheduleApexClassTest',
                                       CRON_EXP,
                                       new Scheduled_OppCloseDateUpdate());
        
        CronTrigger ct = [SELECT Id, CronExpression, TimesTriggered, NextFireTime
                            FROM CronTrigger
                           WHERE id = :jobId];
        
        System.assertEquals(CRON_EXP, ct.CronExpression);
        System.assertEquals(0, ct.TimesTriggered);
        System.assertEquals('2022-03-15 00:00:00', String.valueOf(ct.NextFireTime));
        
        Test.stopTest();

        // test results
        
        Integer updateCount = 0;
        Integer skipCount   = 0;

        List <Opportunity> opportunitys = [SELECT Id, Name, CloseDate FROM Opportunity];

        for(Opportunity o : opportunitys) {
            if (o.Name.contains('Update') &&
                updateCount == 0)
            {
                System.assertEquals(date.today().addDays(20), o.CloseDate, 'Opportunity\'s Close Date should have been updated as it was less than 7 days away');
                updateCount = 1;
            }
            if (o.Name.contains('Skip') &&
                skipCount == 0)
            {
                System.assertEquals(date.today().addDays(15), o.CloseDate, 'Opportunity should not have been updated as it\'s Close Date is more than 7 days away');
                skipCount = 1;
            }
        }
        // check that both lists of Opportunities have been tested
        System.assertEquals(2, updateCount + skipCount, 'Count should be 2 once all assertions have been executed');
    
    }
    
    // check that the class does not change the custom setting's field to false, if it was true before class was executed
    static testmethod void testSettingUpdates() {
        
        User u = [SELECT Id FROM User WHERE UserName = '[email protected]'];
        
        // switch the custom setting field to true before the scheduled job executes
        Val_Rule_Cntrlr__c setting;
        setting = Val_Rule_Cntrlr__c.getInstance(u.Id);
        setting.All_Opportunity_Disabled__c = true;
        upsert setting;
        
        System.runAs(u) {
            
            Test.startTest();
            
            String jobId = System.schedule('ScheduleApexClassTest',
                                           CRON_EXP,
                                           new Scheduled_OppCloseDateUpdate());
            
            CronTrigger ct = [SELECT Id, CronExpression, TimesTriggered, NextFireTime
                                FROM CronTrigger
                               WHERE id = :jobId];
            
            System.assertEquals(CRON_EXP, ct.CronExpression);
            System.assertEquals(0, ct.TimesTriggered);
            System.assertEquals('2022-03-15 00:00:00', String.valueOf(ct.NextFireTime));
            
            Test.stopTest();
        }
        setting = Val_Rule_Cntrlr__c.getInstance(u.Id);
        
        // check that the class did not change the All_Opportunity_Disabled__c field to false
        System.assertEquals(true, setting.All_Opportunity_Disabled__c);
    }

}


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow