Skip to main content
Build the future with Agentforce at TDX in San Francisco or on Salesforce+ on March 5–6. Register now.

Winter '24 で認定 Platform デベロッパー資格を更新する

学習の目的

この単元を完了すると、次のことができるようになります。

  • ユーザーモードデータベース操作で Apex コードを保護する。
  • レコードトリガーフローでカスタムエラーメッセージを作成する。
  • Lightning Web コンポーネントで改良された条件付きディレクティブを使用する。
  • Iterable を使用して For ループ内の反復処理を簡単に実行する。
  • Comparator インターフェースと Collator クラスを使用して並び替える。

Salesforce 認定資格

認定 Platform デベロッパー資格を保有している場合、その認定資格を維持するためには期日までにこのモジュールを修了する必要があります。資格を維持するためのもう 1 つ重要な点は、Trailhead アカウントと Webassessor アカウントをリンクさせておくことです。

この資格の取得を検討している方は、Salesforce Platform デベロッパーの資格を参照してください。

注意: このバッジは誰でも取得できますが、このモジュールは認定 Platform デベロッパーの有資格者を対象としています。

認定資格の機密を守る

Salesforce は、質の高い認定試験と価値ある資格を提供することを最優先事項としています。業界随一と広く認められている認定資格制度を維持するためには、試験のセキュリティを確保し、その機密を保持することが不可欠です。

Salesforce 認定資格プログラムに参加する場合は、Salesforce Credential and Certification Program Agreement (Salesforce 認定資格プログラム規約) に同意いただく必要があります。詳細は、Salesforce ヘルプ記事「Salesforce 認定資格プログラム同意書および行動規範」に記載の Salesforce 認定資格試験の受験ポリシーを確認してください。

この 1 年間に多数の機能が強化されています。ここでは、特に重要なものについて説明します。

ユーザーモードデータベース操作で Apex コードを保護する

新しい DatabaseSearch メソッドは accessLevel パラメーターをサポートします。このパラメーターを指定すると、デフォルトのシステムモードではなく、ユーザーモードでデータベース操作と検索操作を実行できます。デフォルトで、Apex コードはシステムモードで実行されます。つまり、コードを実行しているユーザーよりも非常に上位の権限で実行されます。Apex のセキュリティコンテキストを強化するために、データベース操作にユーザーモードアクセスを指定できます。ユーザーモードでは、実行ユーザーの項目レベルセキュリティ (FLS) とオブジェクト権限が考慮され、常に共有ルールが適用されます。システムモードでは、クラスの sharing キーワードで共有ルールが管理されます。

対象: この変更は、Enterprise Edition、Performance Edition、Unlimited Edition、および Developer Edition の Lightning Experience および Salesforce Classic に適用されます。

方法: SOQL クエリに WITH USER_MODE または WITH SYSTEM_MODE を使用して、操作のモードを指定できます。次の例は、ユーザーモードを指定しています。

List<Account> acc = [SELECT Id FROM Account WITH USER_MODE];

データベース操作で、ユーザーモードまたはシステムモードを指定できます。この例では、ユーザーモードで新しいアカウントを挿入しています。

Account acc = new Account(Name='test');insert as user acc;

新しい AccessLevel クラスは、Apex がデータベース操作を実行する 2 つのモードを表します。この新しいクラスを使用して、実行モードをユーザーモードまたはシステムモードに定義します。

レコードトリガーフローでカスタムエラーメッセージを作成する

新しいカスタムエラーメッセージ要素を使用して、何が問題であったのか、どのように修正すべきかを説明するエンドユーザーへの的を絞ったエラーメッセージを作成します。このエラーメッセージはレコードページ全体のウィンドウに表示されるか、特定の項目にインラインエラーとして表示されます。関連付けられたレコードの変更はロールバックされます。エラーメッセージは保存前フローと保存後フローに作成できます。この機能は、IdeaExchange のアイデアのおかげで実現しました。

対象: この変更は、Essentials Edition、Professional Edition、Enterprise Edition、Performance Edition、Unlimited Edition、Developer Edition の Lightning Experience と Salesforce Classic に適用されます。

理由: ユーザーがアクション (フローをトリガーするレコードの削除など) を実行すると、フローでエラーが発生することがあります。以前は、フローが失敗したときに、特定のエラーメッセージをユーザーに表示できませんでした。操作が失敗した正確な原因をユーザーに通知できるようになったため、ユーザーが問題を修正して再試行できます。

方法: [Custom Error Message (カスタムエラーメッセージ)] 要素を追加して (1)、エラーメッセージを表示する場所を選択し (2)、エラーメッセージテキストを入力します (3)。

[Custom Error Message (カスタムエラーメッセージ)] 要素と、この要素を設定するための詳細ペインが表示されているフローキャンバス

Lightning Web コンポーネントで改良された条件付きディレクティブを使用する

従来の if:trueif:else ディレクティブが、lwc:iflwc:elseiflwc:else 条件付きディレクティブに置き換わりました。

対象: この変更は、Lightning Experience、エクスペリエンスビルダーサイト、およびすべてのバージョンの Salesforce モバイルアプリケーションのカスタム Lightning Web コンポーネントに適用されます。この変更は、オープンソースの Lightning Web コンポーネントにも適用されます。

方法: lwc:iflwc:elseiflwc:else 条件付きディレクティブを使用すると、プロパティ getter へのアクセスがディレクティブのインスタンスごとに 1 回のみになります。

<!-- conditionalExample.html -->
<template>
    <template lwc:if={isTemplateOne}>
        This is template one.
    </template>
    <template lwc:else>
        This is template two.
    </template>
</template>

lwc:elseiflwc:else はどちらも、同階層の lwc:if または lwc:elseif のすぐ後ろに続ける必要があります。

式は lwc:iflwc:elseif に渡し、lwc:else には渡しません。

expression1 で truthy が返されると、他のどのプロパティ getter もアクセスされません。

<!-- example.html -->
<template>
    <template lwc:if={expression1}>
        Statement 1
    </template>
    <template lwc:elseif={expression2}>
        Statement 2
    </template>
    <template lwc:else>
        Statement 3
    </template>
</template>

lwc:iflwc:elseiflwc:else 条件付きディレクティブを使用するときは、次のガイドラインに留意してください。

  • 条件付きディレクティブは、ネストされた <template> タグ、<div> タグ、その他の HTML 要素や、<c-custom-cmp> のようなカスタムコンポーネントタグで使用します。
  • lwc:elseif または lwc:else の前にテキストや他の要素を配置することはできません。タグ間の空白文字が条件付きディレクティブと同階層である場合、その空白文字は無視されます。たとえば、lwc:if の後、lwc:else の前に <div> タグを含めることはできません。
  • !conditionobject?.property?.condition など、複雑な式はサポートされていません。複雑な式を評価するには、JavaScript クラスで getter を使用します。

Iterable を使用して for ループ内の反復処理を簡単に実行する

for ループに Iterable 変数を使用して、リストまたはセットを簡単に反復処理できるようになりました。

対象: この変更は、Enterprise Edition、Performance Edition、Unlimited Edition、および Developer Edition の Lightning Experience および Salesforce Classic に適用されます。

方法: この例では、文字列のリストを反復処理します。

Iterable<String> stringIterator = new List<String>{'Hello', 'World!'};
for (String str : stringIterator) {
   System.debug(str);
}

この例では、Iterable インターフェースを実装し、返された文字列のセットの文字列を反復処理します。

public class MyIterable implements Iterable<String> {
   public Iterator<String> iterator() {
      return new Set<String>{'Hello', 'World!'}.iterator();
   }
}




for (String str : new MyIterable()) {
   System.debug(str);
}

Comparator インターフェースと Collator クラスを使用して並び替える

List クラスで新しい Comparator インターフェースがサポートされるようになったため、List.sort()Comparator パラメーターを指定してコードにさまざまな並び替え順を実装できます。ロケールを区別する比較や並び替えを実行するには、新しい Collator クラスに getInstance メソッドを使用します。ロケールを区別する並び替えでは、コードを実行するユーザーによって異なる結果が生成される可能性があるため、トリガーや、特定の並び替え順が想定されるコードでは使用しないでください。

対象: この変更は、Enterprise Edition、Performance Edition、Unlimited Edition、および Developer Edition の Lightning Experience および Salesforce Classic に適用されます。

方法: System.Comparator インターフェースの compare() メソッドを実装し、Comparator を List.sort() のパラメーターとして指定します。null ポインター例外を回避するために、実装で compare() メソッドの null 入力を明示的に処理する必要があります。この例では、従業員の 2 種類の並び替え方法を実装します。

public class Employee {
    private Long id;
    private String name;
    private Integer yearJoined;
    // Constructor
    public Employee(Long i, String n, Integer y) {
        id = i;
        name = n;
        yearJoined = y;
    }
    public String getName() { return name; }
    public Integer getYear() { return yearJoined; }
}




// Class to compare Employees by name
    public class NameCompare implements Comparator<Employee> {
        public Integer compare(Employee e1, Employee e2) {
            if(e1?.getName() == null && e2?.getName() == null) {
                return 0;
            } else if(e1?.getName() == null) {
                return -1;
            } else if(e2?.getName() == null) {
                return 1;
            }
            return e1.getName().compareTo(e2.getName());
        }
    }
    // Class to compare Employees by year joined
    public class YearCompare implements Comparator<Employee> {
        public Integer compare(Employee e1, Employee e2) {
            // Guard against null operands for ‘<’ or ‘>’ operators because
            // they will always return false and produce inconsistent sorting
            Integer result;
            if(e1?.getYear() == null && e2?.getYear() == null) {
                result = 0;
            } else if(e1?.getYear() == null) {
                  result = -1;
            } else if(e2?.getYear() == null) {
                  result = 1;
            } else if (e1.getYear() < e2.getYear()) {
                  result = -1;
            } else if (e1.getYear() > e2.getYear()) {
                  result = 1;
            } else {
                  result = 0;
            }
            return result;
        }
    }




@isTest
private class EmployeeSortingTest {
    @isTest
    static void sortWithComparators() {
        List<Employee> empList = new List<Employee>();
        empList.add(new Employee(101,'Joe Smith', 2020));
        empList.add(new Employee(102,'J. Smith', 2020));
        empList.add(new Employee(25,'Caragh Smith', 2021));
        empList.add(new Employee(105,'Mario Ruiz', 2019));
        // Sort by name
        NameCompare nameCompare = new NameCompare();
        empList.sort(nameCompare);
        // Expected order: Caragh Smith, J. Smith, Joe Smith, Mario Ruiz
        Assert.areEqual('Caragh Smith', empList.get(0).getName());
        // Sort by year joined
        YearCompare yearCompare = new YearCompare();
        empList.sort(yearCompare);
        // Expected order: Mario Ruiz, J. Smith, Joe Smith, Caragh Smith
        Assert.areEqual('Mario Ruiz', empList.get(0).getName());
    }
}

この例では、デフォルトのリストの並び替えを実行してから、Collator を使用してユーザーロケールに基づいて並び替えます。

@IsTest
    static void userLocaleSort() {
        string userLocale = 'fr_FR';
        User u = new User(Alias = 'standt', Email='standarduser@testorg.com',
        EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US',
        LocaleSidKey=userLocale, TimeZoneSidKey='America/Los_Angeles',
        ProfileId = [SELECT Id FROM Profile WHERE Name='Standard User'].Id,
        UserName='standarduser' + DateTime.now().getTime() + '@testorg.com');
        System.runAs(u) {
            List<String> shoppingList = new List<String> {
                'épaule désosé Agneau',
                'Juice',
                'à la mélasse Galette 5 kg',
                'Bread',
                'Grocery'
            };
            // Default sort
            shoppingList.sort();
            Assert.areEqual('Bread', shoppingList[0]);
            // Sort based on user Locale
            Collator myCollator = Collator.getInstance();
            shoppingList.sort(myCollator);
            Assert.areEqual('à la mélasse Galette 5 kg', shoppingList[0]);
            Assert.areEqual('Bread', shoppingList[1]);
            Assert.areEqual('épaule désosé Agneau', shoppingList[2]);
            Assert.areEqual('Grocery', shoppingList[3]);
            Assert.areEqual('Juice', shoppingList[4]);
        }
    }

リソース

Salesforce ヘルプで Trailhead のフィードバックを共有してください。

Trailhead についての感想をお聞かせください。[Salesforce ヘルプ] サイトから新しいフィードバックフォームにいつでもアクセスできるようになりました。

詳細はこちら フィードバックの共有に進む