salesforce開発お勉強など
https://trailhead.salesforce.com/
https://trailblazer.me/id/yinlei
基礎編
2020/05/01
2020/05/02
2020/05/03
2020/05/04
2020/05/05
2020/05/06
2020/05/9
2020/05/10
2020/05/16
2020/05/17
2020/05/23
2020/05/24
2020/05/30
2020/06/06
2020/06/13
2020/06/14
2020/06/18
2020/06/20
2020/06/27
2020/06/28
2020/07/04
2020/07/11
メモ
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 開発者ガイド
ハンズオン組織
User Interface API Developer Guide
Visualforce では、一度にページ全体を開発します。
Visualforce は、PHP、ASP、JSP、Ruby on Rails など他のページ中心技術と概念的に類似しています。
Step not yet complete in My Trailhead Playground 4
Make sure you add the 'helloWorld' Lightning web component to the default Home page.
解決法
組織> オブジェクト> 項目> レコード
組織の共有設定>ロール階層>共有ルール>共有の直接設定
レコードに対する権限は、常にオブジェクトレベル、項目レベル、レコードレベルの権限の組み合わせによって評価される。
オブジェクトレベルの権限とレコードレベルの権限が一致しない場合は、より制限が厳しい設定が採用される。
組織の共有設定は、最も制限されたユーザがアクセスできる基準レベルを指定するものです。
% 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]
オブジェクト権限は、プロファイルまたは権限セットを使用して設定できます。ユーザには、1 つのプロファイルと複数の権限セットを設定できます。
ユーザのプロファイルによって、ユーザがアクセスできるオブジェクトと、オブジェクトレコードでユーザが実行できる操作 (作成、参照、編集、削除など) が決まります。
権限セットを使用すれば、ユーザに追加の権限を付与したり、アクセスを設定することができます。
プロファイルを使用して、特定の種別のすべてのユーザに必要な最小の権限と設定を付与します。
次に、必要に応じて権限セットを使用して追加権限を付与します。
プロファイルと権限セットを組み合わせることにより、非常に柔軟にオブジェクトレベルのアクセス権を指定できます。
プロファイルは、設定と権限のコレクションです。
プロファイル設定はユーザが参照できるデータを決定し、
権限はそのデータに対してユーザが実行できる操作を決定します。
2 つの一般的な目的で権限セットを使用します。
カスタムオブジェクトまたはアプリケーションへのアクセス権を付与する。
特定の項目に対する権限を付与する。
ユーザが特定の項目に確実にアクセスできないようにするには、対象のオブジェクトの項目レベルセキュリティページを使用して、その項目へのアクセスを制限することが重要です。
項目設定を適用するには、プロファイルまたは権限セットを変更するか、[設定] の [項目アクセス許可/Field Accessibility] メニューから行います。
項目設定を適用するには、プロファイルまたは権限セットを変更します。
-オブジェクトに対するユーザのベースラインの権限は、プロファイルによって決定される。
-ユーザに権限セットが割り当てられている場合は、権限セットにプロファイルを組み合わせてベースラインの権限が設定される。
-ユーザが所有しないレコードに対するアクセス権は、まず組織の共有設定によって設定される。
-組織の共有設定/Organization-Wide Defaultsが [公開/参照・更新可能] より低いものである場合は、ロール階層/Creating the Role Hierarchyを使用して特定のロールにアクセスを許可できる。
-共有ルール/Security->Sharing Settings->Sharing Rulesを使用して、追加のユーザグループ/Groupに対してアクセス権を拡張できる。
-各レコード所有者はレコードの [共有] ボタンを使用して、個別のレコードを直接他のユーザと共有できる。
公開グループPublic Groupsは、全員が共通の機能を持つ個々のユーザ、他のグループ、個々のロールまたはテリトリー、下位ロールを持つロールまたは下位テリトリーを持つテリトリーなどの集まりです。
共有ルールは、レコードの所有者またはレコード内の項目値に基づくことができます。
ロール階層と同様に、共有ルールを組織の共有設定より厳しくすることはできません。
特定のユーザのアクセス権を拡大するのみです。
オブジェクトリレーションによって、レポートタイプに含まれるレコードが決まります。
各オブジェクトリレーションでは、商談などの主オブジェクト、および必要に応じて 1 つ以上の関連オブジェクトを指定します。
主オブジェクトのみを指定した場合、レポートタイプにはそのオブジェクトのレコードのみが含まれます。
項目レイアウトによって、レポートタイプに含まれる項目が決まります。
AppExchange にはすべての Salesforce クラウドおよび製品に対する何かがありますが、通常はソリューションとコンサルタントの 2 種類のリストを参照します。
ソリューションは、Salesforce のプラグインとしてコア機能を拡張するものです。
たとえば、外部調査ツールを Service Cloud と統合するアプリケーションなどがあります。
ソリューションの他の例として、Lightning コンポーネント、Lightning Bolt、Lightning データがあります。
コンサルタントは、特定のクラウドまたは業種向けカスタムソリューションの構築を専門とする Salesforce プロフェッショナルです。
たとえば、コンサルタントは機器メーカーと連携して、組み立て技術者向けのアプリケーションセットを開発できます。
コレクションは AppExchange エキスパートが選定したリストのグループで、特定分野のトップソリューションに焦点を絞ることができる便利な方法です。
Lightning Experience には、ページをカスタマイズする 2 種類の方法があります。ページのレイアウトのカスタマイズと、コンテンツのカスタマイズです。それぞれ異なるツールを使用して作業します。
Lightning ページは、ページ上の領域に割り当てられた Lightning コンポーネントの集まりです。Lightning アプリケーションビルダーを使用して、ページの構造やコンポーネントの位置をカスタマイズできます
ページに表示する項目やボタンなどのページのコンテンツのカスタマイズでは、ページレイアウトエディタと呼ばれる別のツールを使用します。
Lightning Experience でページのコンテンツをカスタマイズするのに、2 種類の UI でページレイアウトエディタを使用するのはなぜでしょうか? それは、Lightning アプリケーションビルダーでは、ページ上のボタン、アクション、および項目をまだカスタマイズできないからです。
アクションを使用すると、ユーザは、レコードの作成、活動の記録、メールの送信など、さまざまな操作をすばやく実行できます。
カスタムアクションを使用してユーザが最も重要な情報にすばやくアクセスできるようにすることで、ユーザの操作やワークフローがスムーズになります。
オブジェクト固有のアクションでは、他のレコードとの自動的な関連付けが行われ、ユーザはレコードの作成または更新、活動の記録、メールの送信などの操作を特定のオブジェクトのコンテキストですばやく行うことができます。
オブジェクト固有のアクションをモバイルアプリケーションに公開する場合、オブジェクトのページレイアウトを編集するという方法でユーザが使用できるようにします。
ユーザは Salesforce ヘッダーの グローバルアクションメニューアイコン をクリックしてグローバルアクションメニューにアクセスできます。
グローバルアクションでは、ユーザはレコードを作成できますが、新規レコードに他のレコードとのリレーションはありません。
そこで、異なるページレイアウトや異なる選択リスト値をさらに使い分けたいときに使用するツールが「レコードタイプ」です。
Salesforce モバイルアプリケーションでレコードを開くと、ページのヘッダーにそのレコードの主要情報が表示されます。
コンパクトレイアウトは、ヘッダーにどの項目を表示するかを制御します。
オブジェクトごとに、その領域に表示する項目を 10 個まで ([名前] 項目を含む) 割り当てることができます。
モバイルユーザが必要な情報をすばやく取得できるように、コンパクトレイアウトを使用して重要な項目をレコードヘッダーに配置することをお勧めします。
スマート検索項目は、ナビゲーションメニューに最近アクセスしたオブジェクトのダイナミックリストを追加します。
1 アプリケーションの定義とアプリケーションのデータモデル(カスタムオブジェクト,タブ, Lightning アプリケーション)を作成します。
2 ページレイアウト、コンパクトレイアウト、グローバルアクションを使用してブラウザおよび Salesforce モバイルアプリケーション上のユーザインターフェースを変更する。
3 数式、入力規則、プロセスビルダーを使用して計算、データ品質、データベースの更新を自動化し、ユーザエクスペリエンスを向上させます。
4 分析するためのレポート、グラフ、ダッシュボードを定義します。
Lightning フローは製品名です。
プロセスビルダーと Flow Builder はツールの名前です。
プロセスを作成する場合はプロセスビルダーを、フローを作成する場合は Flow Builder を使用します。
プロセスは次のタイミングで開始します。
レコードが作成されたとき
レコードが更新されたとき
プラットフォームイベントが発生したとき
Flow Builder は次のような目的に使用します。
ガイド付き視覚的環境を自動化する。
バックグラウンドプロセスにプロセスビルダーで使用可能な機能以外の機能を追加する。Flow Builder を使用してより複雑な機能を作成し、プロセスからそのフローをコールする。
ユーザがボタンなどをクリックしたときに、バックグラウンドのビジネスプロセスを開始する。
public class StringArrayTest {
public static String[] generateStringArray (Integer j){
String[] strs = new List
for(Integer i=0; i
}
return strs;
}
}
insert
update
upsert
delete
undelete
merge
各 DML ステートメントは 1 つの sObject または sObject のリスト (または配列) を受け入れます。レコードを処理する場合は、sObject のリストを操作する方が効率的です。
DML 一括処理中に発生するエラーを、コントロールフローをその場で中断する Apex 例外として処理する場合、DML ステートメントを使用します。ここでは try. . .catch ブロックを使用します。この動作は、ほとんどのデータベース手続き型言語での例外の処理方法に似ています。
DML 一括操作の部分的な完了を可能にする場合は、Database クラスメソッドを使用します。レコードが失敗した場合でも、DML 操作の残りは終了できます。アプリケーションは拒否されたレコードを確認でき、可能であれば操作を再試行します。この形式を使用すると、DML 例外エラーが発生することがないコードを書くことができます。エラーが発生しない代わりに、作成したコードでは、成功または失敗を判断するための適切な結果配列を使用できます。Database クラスメソッドには、DML ステートメントに類似する、発生した例外をサポートする構文も含まれます。
関連レコードの項目は、同じ DML 操作のコールでは更新できないため、別の DML コールが必要になります。
delete 操作では、カスケード削除がサポートされています。親オブジェクトを削除すると、各子レコードが削除可能な場合は自動的に削除されます。
DML 操作はトランザクション内で実行されます。トランザクションの実行には、すべての DML 操作が正常に完了することが求められます。いずれかの操作でエラーが発生した場合はトランザクション全体がロールバックされます。この場合、データは一切データベースにコミットされません。トランザクションの境界は、トリガ、クラスメソッド、匿名のコードブロック、Apex ページ、カスタム Web サービスメソッドのいずれかにすることができます。
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;
}
}
}
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;
}
}
一度に 1 つの標準またはカスタムオブジェクトしか照会できない SOQL とは異なり、1 つの SOSL クエリですべてのオブジェクトを検索できます。
もう 1 つの相違点として、SOSL が単語の一致に基づいて項目を検索するのに対し、SOQL はデフォルトで完全一致検索を実行します (ワイルドカードを使用しない場合)。
1 つのオブジェクトのレコードを取得する場合は、SOQL を使用します。
複数のオブジェクトを対象に項目を検索する場合は、SOSL を使用します。SOSL クエリは、オブジェクトのほとんどのテキスト項目を検索できます。
public static List
- > searchContactsAndLeads (String str){
List
- > searchList = [FIND :str IN NAME FIELDS
RETURNING Lead(Name),Contact(Name)];
return searchList;
}
}
< 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>
ページレイアウトをさらに細かく制御する必要がある場合、項目を個別に追加できます。
< 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>
< 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>
< 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>
< 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;
}
}
for(Account a : Trigger.New) {
if(String.isNotEmpty(a.BillingPostalCode ) && a.Match_Billing_Address__c ) {
a.ShippingPostalCode = a.BillingPostalCode;
}
}
}
Apex ランタイムでは、1 回のトランザクションで最大 150 の DML コールを実行できます。
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;
}
}
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());
}
}
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 static List
List
for(Integer i=0; i
cons.add(c);
}
insert cons;
return cons;
}
}
=== 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
Partner WSDL は、多数の Salesforce 組織で使用するために最適化されています。あまり強い型付けでなく、組織に固有の設定に基づいて変更されません。
通常、単一の Salesforce 組織のインテグレーションを記述する場合は、Enterprise WSDL を使用します。複数組織の場合は、Partner WSDL を使用します。
Enterprise WSDL は組織に固有の設定を反映しています。そのため、組織のメタデータを変更するたびに、WSDL ファイルを再生成します。これにより、WSDL ファイルが組織の設定と同期が取れた状態が保たれます。
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"
...
1 UI
スタックの最上部では、コードは記述せず、ポイント & クリック操作を行います。
Lightning アプリケーションビルダーでは、コードを一切使用せずに、コンポーネントを組み合わせて Salesforce で稼働するアプリケーションを作成できます。Salesforce プラットフォームでホストされるスタンドアロンアプリケーションを作成することもできます。
2 Lightning コンポーネント
スタックを下がると、独自の Lightning コンポーネントを作成できます。
少しのコードで、Lightning データサービスを使用してレコードの作成、参照、更新、削除ができます。
3 Lightning データサービス
Lightning データサービスは (スタックで直下にある) ユーザインターフェース API を使用してデータを Salesforce から取得します。
LDS ではキャッシュを利用できるため、サーバとの往復が最小限になり、同じデータを使用するすべてのレコードを更新できます。
4 ユーザインターフェース 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
Last update: