salesforce開発お勉強など

https://trailhead.salesforce.com/
https://trailblazer.me/id/yinlei

基礎編

2020/05/01

  • Trailhead の基本
  • Trailhead Playground の管理
  • 2020/05/02

  • Salesforce Platform の基礎
  • データモデリング
  • Salesforce のアジャイルの基礎
  • Lightning Design System の基本
  • 2020/05/03

  • Salesforce でのスクラムと Kanban
  • アプリケーションライフサイクルと開発モデル
  • プラットフォーム開発の基礎
  • Lightning Experience の開発
  • Lightning Experience の基本
  • 2020/05/04

  • Visualforce と Lightning Experience
  • 2020/05/05

  • クイックスタート: Lightning Web コンポーネント
  • 2020/05/06

  • Lightning Web コンポーネントの基本
  • Lightning Web コンポーネント開発者ツールの設定
  • 2020/05/9

  • TeamSpirit 社員登録ガイド
  • TeamSpirit 利用者編
  • TeamSpirit 管理者編
  • 2020/05/10

  • Salesforce ユーザの基本
  • ユーザ管理
  • クイックスタート: Salesforce 開発のための Visual Studio Code
  • Salesforce DX を使用したアプリケーション開発
  • Salesforce モバイルアプリケーションの基礎
  • 数式と入力規則
  • 2020/05/16

  • データセキュリティ
  • 2020/05/17

  • データの管理
  • Salesforce Classic ユーザのための Lightning Experience
  • Lightning Experience のレポートおよびダッシュボード
  • AppExchange の基礎
  • 2020/05/23

  • API の基礎
  • Lightning Experience のカスタマイズ
  • 2020/05/24

  • Salesforce モバイルアプリケーションのカスタマイズ
  • Suggestion Box (提案箱) アプリケーションを構築する
  • 在宅勤務のベストプラクティス
  • 2020/05/30

  • 個人の生産性
  • セルフモチベーション
  • Atlassian アジャイルの基礎
  • 2020/06/06

  • Lightning フロー
  • 2020/06/13

  • Apex の基礎とデータベース
  • 2020/06/14

  • Visualforce の基礎
  • 開発者コンソールの基礎
  • ts-sd-onboarding-wspfe done
  • 2020/06/18

  • 選択リスト管理
  • Apex トリガ
  • 2020/06/20

  • Apex テスト
  • 検索ソリューションの基礎
  • ts-sd-onboarding-wspbe done
  • ユーザエンゲージメント
  • システム管理者初級 done
  • Effective Emails: Quick Look
  • 1 対 1 ミーティング
  • 平等の支持戦略
  • 平等であることのビジネス価値
  • 2020/06/27

  • Salesforce Classic のレポートおよびダッシュボード
  • TS_SSS_Onbording done
  • クイックスタート: Apexクイックスタート: Apex
  • ts-sd-onboarding-tsfdev done
  • Salesforce Classic の CRM
  • Salesforce Classic の取引先と取引先責任者
  • 2020/06/28

  • Salesforce Classic のリードと商談
  • データ品質
  • Salesforce Classic の Chatter の管理
  • Salesforce CPQ の基礎
  • Salesforce CPQ の機能
  • 2020/07/04

  • 外部サービス
  • Salesforce モバイルアプリケーションロールアウト
  • Battle Station (戦闘基地) アプリケーションを構築する
  • ts-sd-onboarding-pm done
  • クイックスタート: Salesforce DX
  • Lightning プラットフォーム API の基礎
  • ts-sd-onbording-qa done
  • 2020/07/11

  • ユーザインターフェース API

  • メモ


  • 英語の設定

  • Setting->Company Settings->Language Settings
    Setting->Company Settings->Company Information
    Administration->Users
  • 和訳

  • 法人取引先 -> Account
    取引先責任者 -> Contact
    行動 -> Event
    活動 -> Activity
    参照可能 -> Visible
    リードとは、潜在的な顧客として認識された人や会社です。
    指定ログイン情報 -> Named Credentials

    Salesforce Fields Reference
    Salesforce および Lightning プラットフォームのオブジェクトリファレンス
    Visualforce 開発者ガイド
    ハンズオン組織

    platform_basics_arch

    Scrum VS Kanban

    ALM

    API

    User Interface API Developer Guide

  • Salesforce では、データベーステーブルはオブジェクト、列は項目、行はレコードとみなされます。

  • Lightning コンポーネントフレームワーク: AngularJS や React と似た UI 開発フレームワーク。 Lightning コンポーネントでは、つなぎ合わせてページを作成できるコンポーネントを開発します。

  • Apex: Java のような構文を持つ Salesforce 独自のプログラミング言語。

  • Visualforce: HTML によく似たコードを使用してカスタムの Salesforce ページを作成できるマークアップ言語で、Apex と JavaScript の強力な組み合わせも利用できます。
    Visualforce では、一度にページ全体を開発します。
    Visualforce は、PHP、ASP、JSP、Ruby on Rails など他のページ中心技術と概念的に類似しています。

  • SOQL (Salesforce Object Query Language) 例: Property__c property = [SELECT Name, Price__c from Property__c WHERE Id=:propId];

  • Apex 開発者ガイド

  • SLDS (Salesforce Lightning Design System)

  • Salesforce Classic はページ中心モデルを使用しますが、Lightning Experience はアプリケーション中心モデル(コンポーネントで構成されています)を使用します。

  • Lightning Experience コンテナは「単一ページアプリケーション」(SPA) で、/lightning URL からアクセスします。/lightning ページが読み込まれ、そのコードが開始され、アプリケーションコードが環境を取り仕切ります。

  • Step not yet complete in My Trailhead Playground 4
    Make sure you add the 'helloWorld' Lightning web component to the default Home page.

    解決法
    Home_Page_Default
    API name

  • Lightning Web Components Reference

  • Lightning Web Components Recipes

  • データACL:
    組織> オブジェクト> 項目> レコード

  • レコードACL:
    組織の共有設定>ロール階層>共有ルール>共有の直接設定

    レコードに対する権限は、常にオブジェクトレベル、項目レベル、レコードレベルの権限の組み合わせによって評価される。
    オブジェクトレベルの権限とレコードレベルの権限が一致しない場合は、より制限が厳しい設定が採用される。

  • 組織の共有設定
    組織の共有設定は、最も制限されたユーザがアクセスできる基準レベルを指定するものです。

  • sharing model
  • スクラッチ組織は、専用の設定可能な短期間の Salesforce 環境です。

  • sfdx-project.json

  • % sfdx force:org:create -s -f config/project-scratch-def.json -a GeoAppScratch
    ERROR running force:org:create: You do not have access to the [ScratchOrgInfo] object


    % sfdx force:org:list
    === Orgs
    ALIAS USERNAME ORG ID CONNECTED STATUS
    ─── ────── ──────────────────────────────── ────────────────── ────────────────
    (D) DevHub [email protected] 00D2w000004ugdYEAQ Connected

    No active scratch orgs found. Specify --all to see all scratch orgs

    % sfdx force:auth:web:login -d -a DevHub
    Successfully authorized [email protected] with org ID 00D2w000004es1GEAQ
    You may now close the browser

    % sfdx force:org:list --all
    === Orgs
    ALIAS USERNAME ORG ID CONNECTED STATUS
    ─── ────── ──────────────────────────────── ────────────────── ────────────────
    (U) [email protected] 00D2w000004ugdYEAQ Connected
    (D) DevHub [email protected] 00D2w000004es1GEAQ Connected

    No active scratch orgs found. Specify --all to see all scratch orgs

    % sfdx force:org:create -s -f config/project-scratch-def.json -a GeoAppScratch
    Successfully created scratch org: 00D5D0000001T0nUAE, username: [email protected]


  • Salesforce DX を使用したアプリケーション開発
    スクリーンショット 2020-05-10 14.45.21.png
    スクリーンショット 2020-05-10 15.27.20.png
  • security_sharing_concepts.jpg
    record.png


  • オブジェクト権限は、プロファイルまたは権限セットを使用して設定できます。ユーザには、1 つのプロファイルと複数の権限セットを設定できます。

    ユーザのプロファイルによって、ユーザがアクセスできるオブジェクトと、オブジェクトレコードでユーザが実行できる操作 (作成、参照、編集、削除など) が決まります。
    権限セットを使用すれば、ユーザに追加の権限を付与したり、アクセスを設定することができます。

    プロファイルを使用して、特定の種別のすべてのユーザに必要な最小の権限と設定を付与します。
    次に、必要に応じて権限セットを使用して追加権限を付与します。
    プロファイルと権限セットを組み合わせることにより、非常に柔軟にオブジェクトレベルのアクセス権を指定できます。

    プロファイルは、設定と権限のコレクションです。
    プロファイル設定はユーザが参照できるデータを決定し、
    権限はそのデータに対してユーザが実行できる操作を決定します。

    2 つの一般的な目的で権限セットを使用します。
    カスタムオブジェクトまたはアプリケーションへのアクセス権を付与する。
    特定の項目に対する権限を付与する。



  • ユーザが特定の項目に確実にアクセスできないようにするには、対象のオブジェクトの項目レベルセキュリティページを使用して、その項目へのアクセスを制限することが重要です。
    項目設定を適用するには、プロファイルまたは権限セットを変更するか、[設定] の [項目アクセス許可/Field Accessibility] メニューから行います。
    項目設定を適用するには、プロファイルまたは権限セットを変更します。

  • record_access_triangle.png
  • 各種データの表示およびアクセスは、次の基本原則に従って、上記のセキュリティコントロール間の連携により決定されます。

    -オブジェクトに対するユーザのベースラインの権限は、プロファイルによって決定される。
    -ユーザに権限セットが割り当てられている場合は、権限セットにプロファイルを組み合わせてベースラインの権限が設定される。
    -ユーザが所有しないレコードに対するアクセス権は、まず組織の共有設定によって設定される。
    -組織の共有設定/Organization-Wide Defaultsが [公開/参照・更新可能] より低いものである場合は、ロール階層/Creating the Role Hierarchyを使用して特定のロールにアクセスを許可できる。
    -共有ルール/Security->Sharing Settings->Sharing Rulesを使用して、追加のユーザグループ/Groupに対してアクセス権を拡張できる。
    -各レコード所有者はレコードの [共有] ボタンを使用して、個別のレコードを直接他のユーザと共有できる。

  • 共有ルールを作成する前に、適切な公開グループを設定することが重要です。
    公開グループPublic Groupsは、全員が共通の機能を持つ個々のユーザ、他のグループ、個々のロールまたはテリトリー、下位ロールを持つロールまたは下位テリトリーを持つテリトリーなどの集まりです。

    共有ルールは、レコードの所有者またはレコード内の項目値に基づくことができます。
    ロール階層と同様に、共有ルールを組織の共有設定より厳しくすることはできません。
    特定のユーザのアクセス権を拡大するのみです。


  • Sharing Settings
    data import

    analytics_overview.jpeg

  • レポートタイプには、主オブジェクトリレーションと項目レイアウトがあります。
    オブジェクトリレーションによって、レポートタイプに含まれるレコードが決まります。

    各オブジェクトリレーションでは、商談などの主オブジェクト、および必要に応じて 1 つ以上の関連オブジェクトを指定します。
    主オブジェクトのみを指定した場合、レポートタイプにはそのオブジェクトのレコードのみが含まれます。

    項目レイアウトによって、レポートタイプに含まれる項目が決まります。

  • new report


  • AppExchange にはすべての Salesforce クラウドおよび製品に対する何かがありますが、通常はソリューションとコンサルタントの 2 種類のリストを参照します。

    ソリューションは、Salesforce のプラグインとしてコア機能を拡張するものです。
    たとえば、外部調査ツールを Service Cloud と統合するアプリケーションなどがあります。
    ソリューションの他の例として、Lightning コンポーネント、Lightning Bolt、Lightning データがあります。

    コンサルタントは、特定のクラウドまたは業種向けカスタムソリューションの構築を専門とする Salesforce プロフェッショナルです。
    たとえば、コンサルタントは機器メーカーと連携して、組み立て技術者向けのアプリケーションセットを開発できます。

    コレクションは AppExchange エキスパートが選定したリストのグループで、特定分野のトップソリューションに焦点を絞ることができる便利な方法です。


  • App Manager
    App Manager

    appmanager


  • Lightning Experience には、ページをカスタマイズする 2 種類の方法があります。ページのレイアウトのカスタマイズと、コンテンツのカスタマイズです。それぞれ異なるツールを使用して作業します。

    Lightning ページは、ページ上の領域に割り当てられた Lightning コンポーネントの集まりです。Lightning アプリケーションビルダーを使用して、ページの構造やコンポーネントの位置をカスタマイズできます

    ページに表示する項目やボタンなどのページのコンテンツのカスタマイズでは、ページレイアウトエディタと呼ばれる別のツールを使用します。

    Lightning Experience でページのコンテンツをカスタマイズするのに、2 種類の UI でページレイアウトエディタを使用するのはなぜでしょうか? それは、Lightning アプリケーションビルダーでは、ページ上のボタン、アクション、および項目をまだカスタマイズできないからです。


  • アクションを使用すると、ユーザは、レコードの作成、活動の記録、メールの送信など、さまざまな操作をすばやく実行できます。

    カスタムアクションを使用してユーザが最も重要な情報にすばやくアクセスできるようにすることで、ユーザの操作やワークフローがスムーズになります。

    オブジェクト固有のアクションでは、他のレコードとの自動的な関連付けが行われ、ユーザはレコードの作成または更新、活動の記録、メールの送信などの操作を特定のオブジェクトのコンテキストですばやく行うことができます。
    オブジェクト固有のアクションをモバイルアプリケーションに公開する場合、オブジェクトのページレイアウトを編集するという方法でユーザが使用できるようにします。

    ユーザは Salesforce ヘッダーの グローバルアクションメニューアイコン をクリックしてグローバルアクションメニューにアクセスできます。
    グローバルアクションでは、ユーザはレコードを作成できますが、新規レコードに他のレコードとのリレーションはありません。


  • global action

    Predefined Field Values

  • ページレイアウトは「プロファイルごとにひとつ」しか設定することができません。
    そこで、異なるページレイアウトや異なる選択リスト値をさらに使い分けたいときに使用するツールが「レコードタイプ」です。
  • コンパクトレイアウト

    Salesforce モバイルアプリケーションでレコードを開くと、ページのヘッダーにそのレコードの主要情報が表示されます。
    コンパクトレイアウトは、ヘッダーにどの項目を表示するかを制御します。
    オブジェクトごとに、その領域に表示する項目を 10 個まで ([名前] 項目を含む) 割り当てることができます。

    モバイルユーザが必要な情報をすばやく取得できるように、コンパクトレイアウトを使用して重要な項目をレコードヘッダーに配置することをお勧めします。


  • スマート検索項目は、ナビゲーションメニューに最近アクセスしたオブジェクトのダイナミックリストを追加します。
  • アプリケーションの作成プロセス(Suggestion Box (提案箱) アプリケーションを構築する )
    1 アプリケーションの定義とアプリケーションのデータモデル(カスタムオブジェクト,タブ, Lightning アプリケーション)を作成します。
    2 ページレイアウト、コンパクトレイアウト、グローバルアクションを使用してブラウザおよび Salesforce モバイルアプリケーション上のユーザインターフェースを変更する。
    3 数式、入力規則、プロセスビルダーを使用して計算、データ品質、データベースの更新を自動化し、ユーザエクスペリエンスを向上させます。
    4 分析するためのレポート、グラフ、ダッシュボードを定義します。

  • Lightning フローは製品名です。
    プロセスビルダーと Flow Builder はツールの名前です。
    プロセスを作成する場合はプロセスビルダーを、フローを作成する場合は Flow Builder を使用します。


  • プロセスは次のタイミングで開始します。

    レコードが作成されたとき
    レコードが更新されたとき
    プラットフォームイベントが発生したとき



  • Flow Builder は次のような目的に使用します。

    ガイド付き視覚的環境を自動化する。
    バックグラウンドプロセスにプロセスビルダーで使用可能な機能以外の機能を追加する。Flow Builder を使用してより複雑な機能を作成し、プロセスからそのフローをコールする。
    ユーザがボタンなどをクリックしたときに、バックグラウンドのビジネスプロセスを開始する。

  • apex_database_architecture.png


  • public class StringArrayTest {
    public static String[] generateStringArray (Integer j){
    String[] strs = new List();
    for(Integer i=0; i strs.add('Test '+i);
    }
    return strs;
    }
    }

  • 次の DML ステートメントを使用できます。

    insert
    update
    upsert
    delete
    undelete
    merge
    各 DML ステートメントは 1 つの sObject または sObject のリスト (または配列) を受け入れます。レコードを処理する場合は、sObject のリストを操作する方が効率的です。

  • DML ステートメントとは異なり、データベースメソッドには省略可能な allOrNone パラメータがあり、操作を部分的に完了させる必要があるかどうかを指定できます。このパラメータを false に設定すると、一部のレコードでエラーが発生した場合、成功したレコードはコミットされ、失敗したレコードについてはエラーが返されます。また、部分的な完了オプションでは、例外を発生させません。
  • DML ステートメントとデータベースメソッドの使い分け
    DML 一括処理中に発生するエラーを、コントロールフローをその場で中断する Apex 例外として処理する場合、DML ステートメントを使用します。ここでは try. . .catch ブロックを使用します。この動作は、ほとんどのデータベース手続き型言語での例外の処理方法に似ています。
    DML 一括操作の部分的な完了を可能にする場合は、Database クラスメソッドを使用します。レコードが失敗した場合でも、DML 操作の残りは終了できます。アプリケーションは拒否されたレコードを確認でき、可能であれば操作を再試行します。この形式を使用すると、DML 例外エラーが発生することがないコードを書くことができます。エラーが発生しない代わりに、作成したコードでは、成功または失敗を判断するための適切な結果配列を使用できます。Database クラスメソッドには、DML ステートメントに類似する、発生した例外をサポートする構文も含まれます。
  • 関連レコードの更新
    関連レコードの項目は、同じ DML 操作のコールでは更新できないため、別の DML コールが必要になります。
  • 関連レコードの削除
    delete 操作では、カスケード削除がサポートされています。親オブジェクトを削除すると、各子レコードが削除可能な場合は自動的に削除されます。
  • トランザクションについて
    DML 操作はトランザクション内で実行されます。トランザクションの実行には、すべての DML 操作が正常に完了することが求められます。いずれかの操作でエラーが発生した場合はトランザクション全体がロールバックされます。この場合、データは一切データベースにコミットされません。トランザクションの境界は、トリガ、クラスメソッド、匿名のコードブロック、Apex ページ、カスタム Web サービスメソッドのいずれかにすることができます。
  • public class AccountHandler {
    public static Account insertNewAccount (String name){
    try {
    Account acct = new Account(Name=name);
    insert acct;
    return acct;
    } catch (DmlException e) {
    System.debug('A DML exception has occurred: ' + e.getMessage());
    return null;
    }
    }
    }
  • SOQL および SOSL の概要
  • public class ContactSearch {
    public static Contact[] searchForContacts (String lastName, String postalCode){
    Contact[] cts = [SELECT ID, Account.Name FROM Contact WHERE ( LastName LIKE :lastName OR MailingPostalCode LIKE :postalCode)];
    return cts;
    }
    }
  • Salesforce Object Search Language (SOSL) は、レコード内のテキスト検索実行に使用される Salesforce の検索言語です。SOSL を使用して、Salesforce の複数の標準およびカスタムオブジェクトレコードを対象に項目を検索できます。SOSL は、Apache Lucene と似ています。

    一度に 1 つの標準またはカスタムオブジェクトしか照会できない SOQL とは異なり、1 つの SOSL クエリですべてのオブジェクトを検索できます。

    もう 1 つの相違点として、SOSL が単語の一致に基づいて項目を検索するのに対し、SOQL はデフォルトで完全一致検索を実行します (ワイルドカードを使用しない場合)。

    1 つのオブジェクトのレコードを取得する場合は、SOQL を使用します。
    複数のオブジェクトを対象に項目を検索する場合は、SOSL を使用します。SOSL クエリは、オブジェクトのほとんどのテキスト項目を検索できます。

  • public class ContactAndLeadSearch {
    public static List> searchContactsAndLeads (String str){
    List> searchList = [FIND :str IN NAME FIELDS
    RETURNING Lead(Name),Contact(Name)];
    return searchList;
    }
    }
  • visualforce_request_processing.png

  • Visualforce は、Lightning Platform でホストできるモバイルおよびデスクトップアプリケーション用の高度なカスタムユーザインターフェースを、開発者が作成できるようにする Web 開発フレームワークです。
  • < apex:page showHeader="false">
    < apex:image url="https://developer.salesforce.com/files/salesforce-developer-network-logo.png">
    < /apex:page>
  • < apex:page >
    < apex:pageBlock title="User Status">
    < apex:pageBlockSection columns="1">
    {! $User.FirstName }
    < /apex:pageBlockSection>
    < /apex:pageBlock>
    < /apex:page>
  • < apex:page standardController="Contact">
    < apex:pageBlock title="Contact View">
    < apex:pageBlockSection>
    First Name: {! Contact.FirstName }

    Last Name: {! Contact.LastName }

    Owner Email: {! Contact.Owner.Email }

    < /apex:pageBlockSection>
    < /apex:pageBlock>
    < /apex:page>

  • は、たった 1 行のマークアップで多数の項目、セクション、ボタン、その他のユーザインターフェース要素をページに追加する、大まかな出力コンポーネントです。また、ページに追加されるすべての要素には、Salesforce Classic のスタイル設定が使用されます。
    を使用して、現在のレコードに関連するレコードのリストを表示します。
    ページレイアウトをさらに細かく制御する必要がある場合、項目を個別に追加できます。 コンポーネントは、これを実行するために設計されています。
    および コンポーネントは、プラットフォームのデザインを適用するために必要です。 内で を使用すると、2 列のレイアウトが適用され、項目の表示ラベルが追加されて、項目と表示ラベルが適切に整列およびスタイル設定されます。
    を使用して、ページにデータのテーブルを追加します。
  • OppView
    < apex:page  standardController="Opportunity ">
    < apex:pageBlock title="Opp View">
    < apex:pageBlockSection>
    < apex:outputField value="{! Opportunity.Name }"/>
    < apex:outputField value="{! Opportunity.Amount }"/>
    < apex:outputField value="{! Opportunity.CloseDate }"/>
    < apex:outputField value="{! Opportunity.Account.Name }"/>
    < /apex:pageBlockSection>
    < /apex:pageBlock>
    < /apex:page>
  • AccountEdit
    < apex:page  standardController="Contact">
    < apex:form>
    < apex:pageBlock title="Edit Contact">
    < apex:pageBlockSection columns="1">
    < apex:inputField value="{! Contact.FirstName }"/>
    < apex:inputField value="{! Contact.LastName }"/>
    < apex:inputField value="{! Contact.Email }"/>
    < /apex:pageBlockSection>

    < apex:pageBlockButtons>
    < apex:commandButton action="{! save }" value="Save" />
    < /apex:pageBlockButtons>
    < /apex:pageBlock>
    < /apex:form>
    < /apex:page>
  • AccountList
    < apex:page standardController="Account" recordSetVar="accounts">
    < apex:pageBlock title="Accounts List" id="accounts_list">
    < apex:repeat value="{! accounts }" var="a">
    < li>
    < apex:outputLink value="/{! a.ID }">
    {! a.Name }
    < /apex:outputLink>
    < /li>
    < /apex:repeat>
    < /apex:pageBlock>
    < /apex:page>

  • ShowImage
    < apex:page showHeader="false" sidebar="false" standardStylesheets="false">
    < apex:image alt="kitten1.jpg" title="kitten" url="{! URLFOR($Resource.vfimagetest , 'cats/kitten1.jpg') }"/>
    < /apex:page>

  • NewCaseList.vfp

    < apex:page controller="NewCaseListController">
    < apex:pageBlock title="NewCases List" id="newcases_list">
    < apex:repeat value="{! newcases }" var="case">
    < li>< apex:outputLink value="{! URLFOR( $Action.Case.View, case.ID ) }">
    {! case.CaseNumber }
    < /apex:outputLink>

  • < /apex:repeat>
    < /apex:pageBlock>
    < /apex:page>

    NewCaseListController.apxc

    public class NewCaseListController {
    public List getNewCases() {
    List results = Database.query(
    'SELECT ID, CaseNumber ' +
    'FROM Case ' +
    'Where Status = \'New\' ' +
    'LIMIT 10'
    );
    return results;
    }
    }

  • trigger AccountAddressTrigger on Account (before insert, before update) {
    for(Account a : Trigger.New) {
    if(String.isNotEmpty(a.BillingPostalCode ) && a.Match_Billing_Address__c ) {
    a.ShippingPostalCode = a.BillingPostalCode;
    }
    }
    }
  • トリガは、一度に 200 レコードのバッチに対して実行されます。つまり、400 レコードでトリガが実行された場合、1 回につき 200 レコードずつ、トリガが 2 回実行されます。
    Apex ランタイムでは、1 回のトランザクションで最大 150 の DML コールを実行できます。

  • trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {

    List taskList = new List();

    for(Opportunity opp : Trigger.new) {

    //Only create Follow Up Task only once when Opp StageName is to 'Closed Won' on Create
    if(Trigger.isInsert) {
    if(Opp.StageName == 'Closed Won') {
    taskList.add(new Task(Subject = 'Follow Up Test Task', WhatId = opp.Id));
    }
    }

    //Only create Follow Up Task only once when Opp StageName changed to 'Closed Won' on Update
    if(Trigger.isUpdate) {
    if(Opp.StageName == 'Closed Won'
    && Opp.StageName != Trigger.oldMap.get(opp.Id).StageName) {
    taskList.add(new Task(Subject = 'Follow Up Test Task', WhatId = opp.Id));
    }
    }
    }

    if(taskList.size()>0) {
    insert taskList;
    }
    }

  • @isTest
    public class TestVerifyDate {
    @isTest static void testCheckDates(){
    Date d = VerifyDate.CheckDates(date.parse('9/1/2020'), date.parse('9/19/2020'));
    System.assertEquals('9/19/2020', d.format());

    d = VerifyDate.CheckDates(date.parse('9/1/2020'), date.parse('10/1/2020'));
    System.assertEquals('9/30/2020', d.format());
    }
    }
  • @isTest
    public class TestRestrictContactByName {
    @isTest static void TestRestrictContactByName(){
    Contact[] cons = new List {
    new Contact(LastName = 'INVALIDNAME', FirstName='abc'),
    new Contact()
    };
    Test.startTest();
    Database.SaveResult[] srList = Database.insert(cons,false);
    Test.stopTest();

    System.assert(!srList[0].isSuccess());
    System.assert(srList[0].getErrors().size() > 0);
    System.assertEquals('The Last Name "INVALIDNAME" is not allowed for DML',
    srList[0].getErrors()[0].getMessage());
    }
    }

  • public class RandomContactFactory {
    public static List generateRandomContacts (Integer num, String lastName){
    List cons = new List();
    for(Integer i=0; i Contact c = new Contact(LastName=lastName, FirstName = 'Test' + i);
    cons.add(c);
    }
    insert cons;
    return cons;
    }
    }
  • update records.png


  • % sfdx force:org:list --all
    === Orgs
    ALIAS USERNAME ORG ID CONNECTED STATUS
    ─── ────── ──────────────────────────────── ────────────────── ─────────────────────
    (D) DevHub [email protected] 00D2w000004ugdYEAQ Connected

    ALIAS USERNAME ORG ID STATUS EXPIRATION DATE
    ─── ────────────── ───────────────────────────── ────────────────── ─────── ───────────────
    (U) dreamhouse-org [email protected] 00D0l0000001Lm5EAE Active 2020-07-08
    GeoAppScratch [email protected] 00D5D0000001T0nUAE Expired 2020-05-17
    [email protected] 00D5D0000001T1MUAU Expired 2020-05-17
    GeoTestOrg [email protected] 00D5D0000001T0YUAU Expired 2020-05-17

  • Enterprise WSDL は、単一の Salesforce 組織向けに最適化されています。強く型付けされていて、組織に固有の設定を反映しています。つまり、2 つの異なる組織から生成された Enterprise WSDL ファイルには異なる情報が含まれています。

    Partner WSDL は、多数の Salesforce 組織で使用するために最適化されています。あまり強い型付けでなく、組織に固有の設定に基づいて変更されません。

    通常、単一の Salesforce 組織のインテグレーションを記述する場合は、Enterprise WSDL を使用します。複数組織の場合は、Partner WSDL を使用します。

    Enterprise WSDL は組織に固有の設定を反映しています。そのため、組織のメタデータを変更するたびに、WSDL ファイルを再生成します。これにより、WSDL ファイルが組織の設定と同期が取れた状態が保たれます。

  • soapui.png


  • GET /services/data/v48.0/jobs/ingest/7502w000002qqEhAAI/successfulResults
    Content-Type: application/json

    Raw Response
    HTTP/1.1 200 OK
    Date: Thu, 02 Jul 2020 13:02:40 GMT
    Strict-Transport-Security: max-age=31536002; includeSubDomains
    Public-Key-Pins-Report-Only: pin-sha256="9n0izTnSRF+W4W4JTq51avSXkWhQB8duS2bxVLfzXsY="; pin-sha256="5kJvNEMw0KjrCAu7eXY5HZdvyCS13BbA0VJG1RSP91w="; pin-sha256="njN4rRG+22dNXAi+yb8e3UMypgzPUPHlv4+foULwl1g="; max-age=86400; includeSubDomains; report-uri="https://a.forcesslreports.com/hpkp-report/00D2w000004ugdYm";
    Expect-CT: max-age=86400, report-uri="https://a.forcesslreports.com/Expect-CT-report/00D2w000004ugdYm"
    X-Content-Type-Options: nosniff
    X-XSS-Protection: 1; mode=block
    X-Robots-Tag: none
    Cache-Control: no-cache,must-revalidate,max-age=0,no-store,private
    Set-Cookie: BrowserId=T10wP7xkEeq_EtU8MsOlhg; domain=.salesforce.com; path=/; expires=Fri, 02-Jul-2021 13:02:40 GMT; Max-Age=31536000
    Sforce-Limit-Info: api-usage=71/15000
    Content-Type: text/csv
    Vary: Accept-Encoding
    Content-Encoding: gzip
    Transfer-Encoding: chunked


    "sf__Id","sf__Created","Name"
    "0012w00000DvLjCAAV","true","Insuron Bulk Company"
    "0012w00000DvLjDAAV","true","Orboid Bulk Company"
    "0012w00000DvLjEAAV","true","Bovis Bulk Company"
    ...

  • lightning_platform_layers.jpeg

  • Lightning テクノロジスタックの各レイヤ

    1 UI
    スタックの最上部では、コードは記述せず、ポイント & クリック操作を行います。
    Lightning アプリケーションビルダーでは、コードを一切使用せずに、コンポーネントを組み合わせて Salesforce で稼働するアプリケーションを作成できます。Salesforce プラットフォームでホストされるスタンドアロンアプリケーションを作成することもできます。

    2 Lightning コンポーネント
    スタックを下がると、独自の Lightning コンポーネントを作成できます。
    少しのコードで、Lightning データサービスを使用してレコードの作成、参照、更新、削除ができます。

    3 Lightning データサービス
    Lightning データサービスは (スタックで直下にある) ユーザインターフェース API を使用してデータを Salesforce から取得します。
    LDS ではキャッシュを利用できるため、サーバとの往復が最小限になり、同じデータを使用するすべてのレコードを更新できます。

    4 ユーザインターフェース API
    UI 構築用に構造化された Salesforce データおよびメタデータのペイロードが提供されます。

  • UI API では、UI が実行時にメタデータの変更に反応するため、Salesforce 組織内のルールと権限に従うカスタムユーザインターフェースを構築するのが簡単になりました。
    システム管理者が権限、レイアウト、項目レベルセキュリティ、共有ルールを変更しても、アプリケーションを変更する必要はありません。

    ユーザインターフェース API をシステムインテグレーションに使用しないでください。
    データのアップロードまたは抽出のための自動インテグレーションの作成にも、データの一括アップロードまたは抽出にも使用しないでください。
    こうしたタスクには Enterprise API または Bulk API を使用してください。

    Lightning コンポーネントを作成する場合は、UI API を直接使用せずに、Lightning データサービス (LDS) を使用してください。


  • cd RecordViewer
    docker-compose build && docker-compose up -d
    https://localhost:8443/l

  • recordview.png

    Last update: