Mark Hammer's Blog

SalesforceやTrailheadに関する情報を投稿しているブログです。

Trailhead モジュール:認定 Platform アプリケーションビルダー資格の更新 (Winter '21)

※この内容は2020/12時点のものです。

Winter '21 のアプリケーションビルダー向けの新機能の学習

https://trailhead.salesforce.com/ja/content/learn/modules/platform-app-builder-certification-maintenance-winter-21/learn-whats-new-for-app-builders-in-winter-21

  • 説明:日本語
  • Challenge:日本語選択問題

特定のレコード変更時のフローの保存前トリガのハンズオン

https://trailhead.salesforce.com/ja/content/learn/modules/platform-app-builder-certification-maintenance-winter-21/get-handson-with-flow-before-save-trigger-when-certain-record-changes-are-made

  • 説明:日本語
  • Challenge:英語ハンズオン

【Challenge要約】

※このChallengeには、Salesforce公式解説があります。
注意:このChallenge用に新しいTrailhead playgroundを用意することをお勧めします。既存の組織やPlayground組織を利用するとChallenge判定時に問題が発生する恐れがあります。

取引先オブジェクトに以下選択リスト項目を作成してください。

  • 項目の表示ラベル:Onboarding Status
  • 値:以下の通り設定してください。
    • Not Started
    • In Process
    • Complete
  • 項目名:Onboarding_Status

以下の通り、新規フローを作成し、有効化してください。

  • 初期設定
    • フロータイプ:レコードトリガフロー
  • 開始要素
    • フローをトリガする条件:レコードが作成または更新された
    • フローを実行:レコードが保存される前
    • [+ オブジェクトを選択]をクリックし、以下の通り設定してください。
      • オブジェクト:取引先
      • 条件の要件:すべての条件に一致 (AND)
      • 項目:Onboarding_Status__c
      • 演算子:次の文字列と一致する
      • 値:Complete
    • 更新されたレコードでフローを実行するタイミング:条件の要件に一致するようにレコードを更新したときのみ
  • 割り当て要素を画面に配置し、開始要素と繋いでください。
  • 割り当て要素を以下の通り設定してください。
    • 表示ラベル:New Assignment
    • API参照名:New_Assignment
    • 変数値を設定
      • 変数: {!$Record.Active__c}
      • 演算子:次の文字列と一致する
      • 値:Yes
  • 保存をクリックし、以下の通り設定して保存してください。
    • フローの表示ラベル:Onboarding
    • フローのAPI参照名:Onboarding
  • フローを有効化してください。

週末を表す数式を簡潔に書きたい

「Salesforceで、日付が週末か否かを見分ける数式を書きたい。」と言われたとき、どういう数式を書けばよいでしょうか。

WEEKDAY関数とOR関数を使う

一番簡単な方法がこれです。
ヘルプを参考に、date__cが対象の日付項目とすると

OR(
WEEKDAY( date__c ) = 1,
WEEKDAY( date__c ) = 7
)

とすれば出来上がりです。

数式を1行にしたい

しかし、これだと対象の項目が増えるごとにOR関数ごと増えていくため、「なんとか1行にできないか」と考えました。
日曜日(1)~土曜日(7)までをしばらく眺めると…。

曜日 WEEKDAY関数の返り値 返り値÷6の余り
日曜日 1 1
月曜日 2 2
火曜日 3 3
水曜日 4 4
木曜日 5 5
金曜日 6 0
土曜日 7 1

WEEKDAY( date__c ) の返り値を6で割ったときに1余れば土日」であることが分かりました。

Salesforceの数式で表すと、以下の通り1行で書くことができました。

MOD( WEEKDAY( date__c ), 6 ) = 1

コンパイラ後のサイズを比べる

合わせて数式のコンパイラ後のサイズを比べてみます。

WEEKDAY関数とOR関数を使った数式のコンパイラ後のサイズは104文字。

f:id:mark-hammer:20201210004551p:plain
WEEKDAY関数とOR関数を使った数式のコンパイラ後のサイズ

1行にしてOR関数を除いた数式のコンパイラ後のサイズは57文字。

f:id:mark-hammer:20201211225627p:plain
1行にしてOR関数を除いた数式のコンパイラ後のサイズ

コンパイラ後のサイズを見ると、1行にしてOR関数を除いた数式の方が使い勝手がよさそうです。

おわりに

WEEKDAY関数とOR関数を使った数式の方が意図は伝わりやすいですので、数式の分かりやすさを取るか、コンパイラ後のサイズを取るかはケースバイケースとなるでしょう。
せっかく検証したので、簡単ですが投稿してみました。

Salesforceがサポートするクイックテキスト利用ケース

はじまり

Salesforceには、クイックテキストという定義済みメッセージを項目に挿入できる機能があります。

trailhead.salesforce.com

どの項目に挿入できるかは条件があるのですが、会社では行動の「説明」項目にテンプレートを挿入するために使用していました。

ところが、Winter'21がリリースされてからユーザより「クイックテキストを挿入しようとするとエラーが出てしまう。」という問い合わせが入るようになりました。

f:id:mark-hammer:20201209222433p:plain
実際のエラー画面

試したところ、行動の編集画面*1で差し込み項目を含むクイックテキストを挿入するとエラーが再現しましたのでSalesforceサポートに問い合わせることにしました。

Salesforceがサポートするクイックテキスト利用ケースとは

Salesforceサポートに問い合わせた結果、以下の回答を得ました。

5.メッセージを使用可能にするチャネルを選択します。
組織で有効な機能に応じて、次のチャネルを利用できます。
メール — メールアクション用
行動 — 行動アクション用
内部 — 状況の変更アクションなど、内部項目で使用します
ナレッジ — Lightning Experience のナレッジ記事用
チャット — サービスコンソールのチャットで使用します。
メッセージング — サービスコンソールのメッセージングで使用します。
電話 — 活動の記録アクション用
ポータル — コミュニティまたはカスタマーポータルで使用します
ソーシャル — ソーシャル投稿用
ToDo — ToDo アクション用

  • Salesforceがサポート対象とする行動オブジェクトへのクイックテキスト利用は「新規行動」などの行動アクションのみであり、行動の編集画面はサポート対象としない。
  • したがって、今回の事象はサポート対象外の行動の編集画面のみで発生するため、不具合ではない。

確かに「新規行動」などの行動アクションでは差し込み項目を含むクイックテキストが利用できるため、この回答でクローズとしました。

サポートからこの回答を得るまでの経緯

上記回答はヘルプの内容に沿った回答だと思っておりますが、実はこの回答を得るまで約半月掛かっており、しかもサポートからの回答が二転三転しました。
ここではその経緯を書いてみます。

1回目の回答

最初に問い合わせた時の回答は以下でした。

差し込み項目の考慮事項
クイックテキストでは、差し込み項目は、取引先、ケース、取引先責任者、カスタムオブジェクト、リード、商談、組織、ユーザ、作業指示のオブジェクトに挿入できます。

  • 上記に行動オブジェクトは含まれない。
  • よって行動オブジェクトへの差し込み項目を含むクイックテキストはサポート対象外なので本件は不具合ではない。

この回答には「それはクイックテキストの『差し込み項目の挿入』で関連先として選べるオブジェクトですよね。」「その回答が正しいなら組織に対して挿入可能な差し込み項目を含むクイックテキストを作成する方法を教えてください。」と返しましたがサポートからの回答は全く変わらず、結局「これ以上の進展が見込めないのでクローズします。」と返しました。

2回目の回答

こちらは質問が異なり、会社で「選択可能なチャネルに『商談』ってあるけど、商談でクイックテキスト利用してましたか?」という話が発端でした。
そこから、「選択可能なチャネルに『商談』がありますが、商談ではクイックテキスト利用可能でしょうか」というケースを作りました。

その回答は「Salesforce ヘルプ:クイックテキストの挿入と使用に商談のチャネルがないので商談では利用できません。」でしたが、「1回目の回答が正しいなら、商談にも差し込み項目を含むクイックテキストが作れるはずです。この矛盾はどこからきているのでしょうか。」と追加質問。
最終的に、「Salesforce ヘルプ:クイックテキストの挿入と使用に行動のチャネルがあるので、行動にも差し込み項目を含むクイックテキストは使える。」という回答を得ました。

3回目の回答

2回目の回答をもってもう一度行動の編集画面で発生するエラーについてケースを作りました。
するとまた1回目の回答と同じ回答を出してきたので*3、「その回答は2回目の回答と矛盾しています。どちらが正しいかはっきりさせてください。」と返し、別担当者*4に変わった後の回答が冒頭に書いた回答となります。

おわりに

今回のようにSalesforceサポートの回答を変えさせるのは結構難しいと感じました。
今回の場合だと

顧客「私にはこのヘルプの文面はこう読める」
Salesforceサポート「いや、その認識は誤りでこれが正しい」

となってしまうと平行線のまま先に進めなくなってしまいます。
今となっては1回目の回答の際に「その回答が正しいなら組織に対して挿入可能な差し込み項目を含むクイックテキストを作成する方法を教えてください。」で粘ればよかった*5かなぁと思いますが、当時はこのやり取りで疲れてしまったので終わらせた経緯がありました。

Trailblazer Communityでもこの問題は取り上げられていますので、困っている人はそれなりにいそうです。

trailblazers.salesforce.com

この投稿がお役に立てれば幸いです。

*1:インライン編集含む

*2:他のヘルプにもサポート対象の条件が記載されているため、引用部分を満たせばどのような利用方法でもサポートされるわけではありません

*3:ちなみに1回目、2回目、3回目のサポート担当者は全員違う人です

*4:おそらく上位サポートエンジニア

*5:組織に対してクイックテキストが作成できない矛盾を突く意図

システム管理者はヘルプメニューの非表示ができない

はじめに

Lightning Experience画面右上にある「?」マークをクリックすると表示されるヘルプメニュー。
このメニューは 設定|ユーザエンゲージメント|ヘルプメニュー でカスタマイズでき、一番上に独自のコンテンツを掲載することができます。

f:id:mark-hammer:20201130235418p:plain
追加した独自のヘルプメニュー

Salesforce標準のヘルプメニューを非表示にすると…

会社にこの独自のヘルプメニューを導入する際、「一般ユーザにはSalesforce標準のヘルプメニューはいらないな…。」と思い、「Salesforce ヘルプコンテンツ」を全てオフにしました。

f:id:mark-hammer:20201130235648p:plain
標準のヘルプメニューを全てオフに

その後、「?」マークをクリックしましたが…、
Salesforce標準のヘルプメニューが非表示にならない。

f:id:mark-hammer:20201209013146p:plain
全てオフにしても標準のヘルプメニューが消えない

キャッシュかと思い、ブラウザキャッシュを消しても1日置いても標準のヘルプメニューが表示される状況。
不具合かと思い、Salesforceサポートに問い合わせたところ「システム管理者は標準のヘルプメニューを全てオフにしても表示されたままになる」とのこと。

実際にヘルプを確認すると、Salesforceヘルプ:Lightning Experience ヘルプメニューのカスタムヘルプの定義 より、

Salesforce が作成したセクションおよびコンテンツへのリンクをユーザに対して非表示にすることができます。
[Salesforce ヘルプコンテンツ] セクションで、非表示にするセクションとリンクを無効にします。
システム管理者には、リリースノートへのリンクをはじめ、すべてのリソースが常に表示されます。

…確かに書いてありました。

追加検証:標準ヘルプメニューが表示される条件

上記ヘルプには「システム管理者」としか書いてありませんが、権限として「システム管理者」があるわけではありません。
具体的にどの権限を付与すれば「システム管理者」と判定されるか確認したところ、「すべてのデータの編集」か「ユーザの管理」権限をもつユーザはシステム管理者として判定され、標準のヘルプメニューが消えない環境となります。*1

ヘルプメニューをカスタマイズしても標準のヘルプメニューが消えない方は、権限を確認することをお勧めします。

*1:「すべてのデータの参照」のみではシステム管理者として判定されません。

フローの投稿をどうするべきか考えた

はじめに

先日フローに関する投稿に関するアンケートを実施しました。
お答えいただいた皆様、ありがとうございました。

ここでは、このアンケートを取った理由と、意見を反映した結果を書いてみます。

フロー作成以前

私がフローを自分で考えた要件のために作成したのは↓が初めてです。

sfblog.markhammer.net

それまではTrailheadの課題で作成したことはありましたが、実際の要件に合わせて作成する場合にどう作ればいいのか全く分かりませんでした。
特にフローにおける変数の扱いについて、「これどう使ったらいいの…?」というぐらい使い方が分かっていませんでした。
フローで要件を実現した投稿なども当時見たのですが…

「フローでその要件を実現できるのは分かったの。具体的にどうするのか知りたいの。

とずっと思っていました。

フロー作成後にブログを書いてみて

その後仕事でフローを作成するにあたり、情報共有としてブログ投稿をします。
「フローを作る前の自分が見ても役立つような投稿にしよう」と思いながら書いてみたのですが…、実際に出来上がったのはフローの概要しか書けていない投稿でした。

「ダメだこれ…、当時の自分が見て『具体的にどうするの?』と聞くやつだこれ…。」

ただこれには理由があり、先ほどリンクを貼った投稿を見ていただくと分かるのですが、概要の時点で投稿量が多いんです。

これに各要素の設定値を付け加えると、書くのも大変だし長すぎて誰も読まないような投稿になってしまうと思い、フローの概要までで留めたのでした。

アンケートを取ってみて

フローの設定値まで細かく書いた投稿は需要があるのか。
過去の自分はそれを求めていましたが、実際の需要を見るためにTwitterでアンケートを取ってみました。
ちなみに「概要と設定値両方見たい」という意見もありましたが、「アンケートに『両方』と書いたらほぼ全員それ選ぶでしょ」ということで、より重要視するものはどちらか、という意図で2択にしました。

結果は約2/3が「具体的な設定値を見たい」となり、実際に書いてみることに。
ただし概要と同じページに書くのは長くなりすぎるので却下。
投稿を分けるにしても、おそらくはてなブログでは見やすい投稿にならないと思い、zenn.dev で書いてみました。

zenn.dev

今後も改善しながらこのような形式で書いていければと思います。

Sales Cloud, Service Cloud, Community Cloudコンサルタント資格試験の違いを考える

はじめに

今年の9月から10月にかけて、Sales Cloud, Service Cloud, Community Cloudの各コンサルタント資格試験に合格しました。

この試験を通じて、各試験で感じたことを書いてみます。
なお、Salesforceは試験問題を公開することを禁じているため、試験問題を直接記載はしません。

Trailhead Help: Salesforce Certification Program Agreement and Policies

medium.com

各試験の受験ガイドから

合格ライン

各試験の合格ラインと、そこから計算した必要な正解数(小数点以下切り上げ)は以下になります。

試験名 合格ライン 必要な正解数
Sales Cloudコンサルタント 62% 38/60
Service Cloudコンサルタント 67% 41/60
Community Cloudコンサルタント 62% 38/60

なぜService Cloudコンサルタントのみ合格ラインが高いのかはよく分かりませんが、40問前後正解する必要があることが分かります。

試験範囲

受験ガイドから、各試験の出題ジャンルと出題率を抜き出してみました。

  • Sales Cloudコンサルタント
ジャンル 出題率
業界の知識 7%
実装戦略 12%
Sales Cloud ソリューションの設計 21%
マーケティングとリード 8%
取引先と取引先責任者の管理 13%
商談の管理 13%
営業の生産性 9%
Sales Cloud分析 9%
連携とデータ管理 8%
  • Service Cloudコンサルタント
ジャンル 出題率
業界の知識 10%
実装戦略 15%
Sales Cloud ソリューションの設計 16%
ナレッジ管理 9%
双方向チャネル 10%
ケース管理 15%
コンタクトセンター分析 5%
連携とデータ管理 5%
サービスコンソール 15%
  • Community Cloudコンサルタント
ジャンル 出題率
実装 22%
共有とセキュリティ 20%
コミュニティの設定 18%
エクスペリエンスビルダー 12%
コミュニティ管理 11%
コンテンツ 9%
テンプレートとユースケース 8%

受験して思ったのは、Sales Cloud、Service Cloudにある赤字ジャンル(業界の知識、実装戦略)の存在です。
例えば、Service Cloudコンサルタント受験ガイドにある以下のサンプル問題。

コンタクトセンターの事業継続計画に含めるべき作業を、以下から3つ選んでください。
A. 代わりのセンターのエージェントにケースを割り当てる
B. 音声自動応答システムを無効にする
C. 臨時スタッフにケース処理のトレーニングを実施する
D. ケース状況項目の値を更新する
E. サービスレベル契約 (SLA) を監視してお客様に連絡する

他のジャンルが実際に組織の設定変更やレコード・レポート・ダッシュボード作成で実践しながら身に付けられるのに対し、上記例題のような業界の知識、実装戦略については座学の範囲となります。
例えば「プロジェクト上で〇〇の問題が発生した場合、どうするか」という問題に対し、「Salesforceが考える回答はこれ」という内容を覚える必要がありますが、これはSalesforce組織で手を動かすだけでは身に付けることができません。*1
業界の知識、実装戦略の出題割合は合わせて20%~25%となるため、ここで得点を取れないと合格に向けて大きなマイナスポイントとなります。

なお、Community Cloudコンサルタントについては業界の知識、実装戦略に関する問題は見受けられず、実際の操作で身に付けることができる内容でした。
そのため、Community CloudコンサルタントはDeveloper Editionにてできるだけコミュニティを作成し、設定を見る、変更することが他コンサルタント資格よりも重要になります。
特に、Community Cloudでは設定箇所が以下の通り分かれており、設定できる内容も異なります。

  • Salesforceの一般的な設定画面(共有設定、ユーザ作成など)
  • 「コミュニティ設定」(共有セットなど、全コミュニティに関わる設定)
  • エクスペリエンスビルダー
  • エクスペリエンスマネージャー

また、Community Cloudは特にユーザライセンスが多岐に渡るため、関連ヘルプ を事前に読むことも他コンサルタント試験と比べて重要になります。
Community Cloudコンサルタント合格後、以下のようなコメントを残したのは、そういった背景もあります。

試験に合格するには

  • 受験対策のTrailmixは一通りやる。

現在公式とされるTrailmixは以下です。

trailhead.salesforce.com

trailhead.salesforce.com

trailhead.salesforce.com

別件ですが、Community CloudコンサルタントのTrailmixでヘルプが非常に多いのも、ヘルプの重要性を語っていると思います。

  • 受験対策のTrailmixになくても、関連しそうなProjectがあればやる。

例えば、私はCommunity Cloudコンサルタント受験直前に以下のProjectをやりました。

trailhead.salesforce.com

trailhead.salesforce.com

その後、試験当日までヘルプを見ながらエクスペリエンスマネージャー、エクスペリエンスビルダーを触ることで、エクスペリエンスマネージャー、エクスペリエンスビルダーでそれぞれ何ができるのか把握でき、よい結果に繋がったと思っています。

  • 受験ガイドの出題範囲に書かれたジャンルの下にある説明文について、用語を説明できるようになっておく。

例えばSales Cloudコンサルタント受験ガイドから抜粋しますと

マーケティングとリード
・与えられたシナリオに従って、リードスコアリングの適切な方法とリード評価の基準を推奨する
取引先と取引先責任者の管理
・与えられたシナリオに従って、取引先階層があることによる影響を説明する
・与えられたシナリオに従って、個人取引先実装の使用事例と影響を説明する

ここから「リードスコアリング」「取引先階層」「個人取引先」とは何か、注意事項があるならなにか、を分かっておくとアドバンテージになります。

  • ポイントスタディ研修は可能であれば受験する。また研修時の演習問題は全て答えられるようにする。

コンサルタント資格に限らず、ポイントスタディ研修の内容は非常に重要です。もし受講できた場合は有効活用しましょう。

おわりに

今回は実際の問題に触れずに受験ガイドなど公開された情報を基に書いたため、「もっと『こういった問題が出ます』のような直接的な情報が欲しいんだよ」という方にはお役に立てないかと思いますが、この投稿が皆様の合格に向けてお役に立てれば幸いです。

*1:回答だけ見ると、「どれも間違いとは言い切れない」という回答が選択肢として表示されていました

Salesforce数式: エラーを返す数式を含むAND, ORの条件判定

はじめに

本投稿の元ネタは、こちらのブログです。

sf.forum.circlace.com

内容を簡単に書くと「項目から日付を持ってきて、その月に日曜日が何回あるかを算出する」とのことで、以下の数式が紹介されていました。

4
+ IF( AND( DAY(LastDay__c)>=29, WEEKDAY( DATE( YEAR( BaseDay__c ), MONTH( BaseDay__c ), 29) ) = 1), 1, 0)
+ IF( AND( DAY(LastDay__c)>=30, WEEKDAY( DATE( YEAR( BaseDay__c ), MONTH( BaseDay__c ), 30) ) = 1), 1, 0)
+ IF( AND( DAY(LastDay__c)>=31, WEEKDAY( DATE( YEAR( BaseDay__c ), MONTH( BaseDay__c ), 31) ) = 1), 1, 0)

数式の意味についてはリンク先をご覧いただければと思いますが、上記数式のうち、
DATE( YEAR( BaseDay__c ), MONTH( BaseDay__c ), 31)
を見たときにこう思いました。

「この数式、BaseDay__c 次第ではエラーになるのでは?」

(でも、さすがにブログに書く前に動作確認はしているよなぁ…)と思いつつ、「よく考えたら、AND、ORの条件判定文でエラーが入ったときにどういう処理が行われるか知らないわ」と思ったので、調査することにしました。

AND関数にエラー数式を混ぜる

まず、日付を設定する項目 BaseDay__c と、 DATE( YEAR( BaseDay__c ), MONTH( BaseDay__c ), 29)DATE( YEAR( BaseDay__c ), MONTH( BaseDay__c ), 30)DATE( YEAR( BaseDay__c ), MONTH( BaseDay__c ), 31) の数式項目を作成します。 そして、BaseDay__c に様々な日付を設定し、数式項目の結果を確認します。

f:id:mark-hammer:20201113001057p:plain
月末が異なる日付と数式の結果

予想通り、存在しない日付をDATE関数で出力しようとするとエラーになりました。

続いて、ブログを参考に LastDay__c を設定します。
そして、ブログに記載されていた以下数式を少し変更し、月末が異なる日付で出力させてみます。

  • 29日は日曜日?: IF( AND( DAY(LastDay__c)>=29, WEEKDAY( DATE( YEAR( BaseDay__c ), MONTH( BaseDay__c ), 29) ) = 1), TRUE, FALSE)
  • 30日は日曜日?: IF( AND( DAY(LastDay__c)>=30, WEEKDAY( DATE( YEAR( BaseDay__c ), MONTH( BaseDay__c ), 30) ) = 1), TRUE, FALSE)
  • 31日は日曜日?: IF( AND( DAY(LastDay__c)>=31, WEEKDAY( DATE( YEAR( BaseDay__c ), MONTH( BaseDay__c ), 31) ) = 1), TRUE, FALSE)

f:id:mark-hammer:20201113004417p:plain
数式の結果

AND関数の引数にエラーになる数式が入っているはずですが、数式全体としてはエラーになりませんでした。

次に、AND関数の引数の順番を入れ替えます。

  • 29日は日曜日?: IF( AND( WEEKDAY( DATE( YEAR( BaseDay__c ), MONTH( BaseDay__c ), 29) ) = 1, DAY(LastDay__c)>=29), TRUE, FALSE)
  • 30日は日曜日?: IF( AND( WEEKDAY( DATE( YEAR( BaseDay__c ), MONTH( BaseDay__c ), 30) ) = 1, DAY(LastDay__c)>=30), TRUE, FALSE)
  • 31日は日曜日?: IF( AND( WEEKDAY( DATE( YEAR( BaseDay__c ), MONTH( BaseDay__c ), 31) ) = 1, DAY(LastDay__c)>=31), TRUE, FALSE)

論理式であれば X AND YY AND X は同じ結果になるはずですが、どうでしょうか。

f:id:mark-hammer:20201113005238p:plain
数式の結果

今度は存在しない日付の場合はエラーを表示するようになりました。

さらに最初のAND数式を少し変更し、「AND関数の最初の引数は必ずTRUEを返す数式」を設定します。

  • 29日は日曜日?: IF( AND( DAY(LastDay__c)>=28, WEEKDAY( DATE( YEAR( BaseDay__c ), MONTH( BaseDay__c ), 29) ) = 1), TRUE, FALSE)
  • 30日は日曜日?: IF( AND( DAY(LastDay__c)>=28, WEEKDAY( DATE( YEAR( BaseDay__c ), MONTH( BaseDay__c ), 30) ) = 1), TRUE, FALSE)
  • 31日は日曜日?: IF( AND( DAY(LastDay__c)>=28, WEEKDAY( DATE( YEAR( BaseDay__c ), MONTH( BaseDay__c ), 31) ) = 1), TRUE, FALSE)

これは、「LastDay__cの日は28以上である」という、BaseDay__cにどの日付を入れても必ずTRUEになる数式をAND変数の1番目の引数に設定しています。

f:id:mark-hammer:20201113010948p:plain
数式の結果

エラー数式をAND関数の1番目の引数に設定した場合と同じ動作でした。

AND関数の動作推察

このことから、以下の動作になっていると推測できます。

  • AND関数は左の引数からTRUE、FALSEを判定している。
  • 引数の途中でFALSEと判定された場合は、そこで判定を打ち切り、AND関数はFALSEを返す。
    • 最初の日曜日判定で存在しない日付でもエラーにならなかった理由は、 DAY(LastDay__c)>=XX の時点でFALSEと判定されたため、その後のエラー数式が判定されなかったためと推測できます。
  • 引数の途中でエラーと判定された場合は、そこで判定を打ち切り、AND関数はエラーを返す。
  • AND関数の全ての引数がTRUEの場合はTRUEを返す。

OR関数にエラー数式を混ぜる

今度は、OR関数の1番目の引数に必ずTRUEになる数式と必ずFALSEになる数式を設定し、2番目の引数にエラー数式を設定して動作を見てみます。

1番目の引数に必ずTRUEになる数式を設定

  • 29日は日曜日?: IF( OR( DAY(LastDay__c)>=28, WEEKDAY( DATE( YEAR( BaseDay__c ), MONTH( BaseDay__c ), 29) ) = 1), TRUE, FALSE)
  • 30日は日曜日?: IF( OR( DAY(LastDay__c)>=28, WEEKDAY( DATE( YEAR( BaseDay__c ), MONTH( BaseDay__c ), 30) ) = 1), TRUE, FALSE)
  • 31日は日曜日?: IF( OR( DAY(LastDay__c)>=28, WEEKDAY( DATE( YEAR( BaseDay__c ), MONTH( BaseDay__c ), 31) ) = 1), TRUE, FALSE)

動作結果は以下になりました。

f:id:mark-hammer:20201113012128p:plain
数式の結果

OR関数は引数のうち1つでもTRUEがあればTRUEを返すため、期待通りの動作と言えます。

1番目の引数に必ずFALSEになる数式を設定

  • 29日は日曜日?: IF( OR( DAY(LastDay__c)>=32, WEEKDAY( DATE( YEAR( BaseDay__c ), MONTH( BaseDay__c ), 29) ) = 1), TRUE, FALSE)
  • 30日は日曜日?: IF( OR( DAY(LastDay__c)>=32, WEEKDAY( DATE( YEAR( BaseDay__c ), MONTH( BaseDay__c ), 30) ) = 1), TRUE, FALSE)
  • 31日は日曜日?: IF( OR( DAY(LastDay__c)>=32, WEEKDAY( DATE( YEAR( BaseDay__c ), MONTH( BaseDay__c ), 31) ) = 1), TRUE, FALSE)

動作結果は以下になりました。

f:id:mark-hammer:20201113012624p:plain
数式の結果

AND関数にて検証した、「AND数式の最初の引数は必ずTRUEを返す数式」を設定したときと同じ動作でした。

OR関数の動作推察

このことから、以下の動作になっていると推測できます。

  • OR関数は左の引数からTRUE、FALSEを判定している。
  • 引数の途中でTRUEと判定された場合は、そこで判定を打ち切り、OR関数はTRUEを返す。
  • 引数の途中でエラーと判定された場合は、そこで判定を打ち切り、OR関数はエラーを返す。
  • OR関数の全ての引数がFALSEの場合はFALSEを返す。

終わりに

今回の検証にて確認できた、「AND、OR関数にて引数の途中で結果が確定した場合は、最後まで処理を行わずに結果を返す」動作は「短絡評価」といい、Salesforce外のプログラミング言語でも使われています。

ja.wikipedia.org

Salesforce数式を作成するうえではあまり気にしなくてもよい動作かと思いますが*1、「こういう動作なんだ」ということを頭の片隅にでも入れていただければ幸いです。

*1:条件式にエラーになりえる数式を積極的に使う場合は必要ですが…

埋め込みチャットの姓と名を入れ替えたい

はじめに

Salesforce では、主に顧客とチャットでやり取りするための Web チャットチャネルを作成することができます。

trailhead.salesforce.com

例えば、上のTrailheadモジュールに従えば簡単なWeb埋め込みチャットを作ることができるのですが、ここで1つ問題が発生します。
それは、顧客情報を入力する事前チャット画面で姓と名が逆に表示される、という点です。

f:id:mark-hammer:20201108001618p:plain:w250
姓と名が逆の事前チャット画面

おそらく名前の欄は英語圏を前提としているのでしょうが、Salesforce内部設定と異なりチャット設定には地域の設定がありません。
そのため、Salesforce設定レベルでは姓と名を入れ替えることができません。

そこで今回は、CSSを使って強引に姓と名の配置を変えることで入れ替えを実現します。

姓と名の入れ替えを実現する

※注意:以下コードはブログ投稿時点で動作を確認しておりますが、今後のリリースにより動作しない場合があります。
また、チャット画面はデフォルトを前提としています。既にチャット画面をカスタマイズ済みの場合は期待通り動作しない場合があります。

姓と名を入れ替えるには、組み込みサービスのコードスニペットのうち、CSS部分に以下を追記してください。

4項目バージョン

    label[for="FirstName"] {
        position: relative;
        left: 142px
    }
    input[id="FirstName"] {
        position: relative;
        left: 142px
    }
    label[for="LastName"] {
        position: relative;
        right: 142px
    }
    input[id="LastName"] {
        position: relative;
        right: 142px
    }

コードスニペットがデフォルトのままの場合、CSS全体だとこうなります。

<style type='text/css'>
    .embeddedServiceHelpButton .helpButton .uiButton {
        background-color: #005290;
        font-family: "Arial", sans-serif;
    }
    .embeddedServiceHelpButton .helpButton .uiButton:focus {
        outline: 1px solid #005290;
    }
    label[for="FirstName"] {
        position: relative;
        left: 142px
    }
    input[id="FirstName"] {
        position: relative;
        left: 142px
    }
    label[for="LastName"] {
        position: relative;
        right: 142px
    }
    input[id="LastName"] {
        position: relative;
        right: 142px
    }
</style>

2項目バージョン

    .embeddedServiceSidebarFormField.inputSplitName:nth-of-type(1) {
        position: relative;
        left: 142px
    }
    .embeddedServiceSidebarFormField.inputSplitName:nth-of-type(2) {
        position: relative;
        right: 142px
    }

コードスニペットがデフォルトのままの場合、CSS全体だとこうなります。

<style type='text/css'>
    .embeddedServiceHelpButton .helpButton .uiButton {
        background-color: #005290;
        font-family: "Arial", sans-serif;
    }
    .embeddedServiceHelpButton .helpButton .uiButton:focus {
        outline: 1px solid #005290;
    }
    .embeddedServiceSidebarFormField.inputSplitName:nth-of-type(1) {
        position: relative;
        left: 142px
    }
    .embeddedServiceSidebarFormField.inputSplitName:nth-of-type(2) {
        position: relative;
        right: 142px
    }
</style>

表示結果

f:id:mark-hammer:20201108004743p:plain:w250
姓と名を正しい配置にした事前チャット画面

この設定を見つけるまでの経緯は、長くなるため末尾に記載します。

CSS変更時の注意

ヘルプに以下記載がある通り、Salesforceはユーザが作成したCSSが正常に動作することを保証していません。

重要 組み込みコンポーネントへのカスタム CSS の追加はサポートされていません。ブランドオプションの使用がサポートされるのは、設定およびコードスニペットのカスタマイズ可能なパラメータのみです。組み込みコンポーネントでカスタム CSS を使用する場合は、リリースごとにチャットウィンドウをテストし、適切に機能することを確認してください。

今回のCSSも、タグの内容が変わってしまえば無効化されますし、ある日のSalesforceリリースによって見栄えが変わってしまうこともあり得ます。*1
そのため、見栄えが変わってしまった場合にどう対応するかは知っておいた方がいいでしょう。

まぁ一番いいのはチャット設定に地域項目を追加して、それによって姓と名を自動で入れ替える機能が追加されることですけどね…。Salesforceさんお願いします。

*1:ここでいうリリースは、年3回のメジャーリリースだけでなく、バグフィックス等のユーザ通知がないリリースも含みます

続きを読む

Chatterメンション:手打ちとコピペの違い

はじめに

先日、会社でこんな問い合わせを受けました。

Chatterグループがメンションされればメール通知するよう設定をしています。
先日、ユーザから「Chatterグループをメンションしているのに何も連絡がない」と問い合わせを受けました。
確認すると、Chatterグループがメンションされているのにメール通知がなく、Chatterグループページにも表示されていません。
なぜでしょうか。

確認すると、投稿された内容は違いがないのに、確かに片方はChatterグループページに表示されていませんでした。

f:id:mark-hammer:20201022230309p:plain
片方が通知あり、もう片方は通知なしの投稿です

最初は全く違いが分からなかったので、「これSalesforceサポートに投げようかなぁ…」と内心思いながら調査を行ったのでした。

調査

調べたところ、これはChatterグループ名を手打ちし、正しくメンションした投稿と、その投稿をコピペした結果、正しくメンションされていない投稿の差だと判断しました。

手打ちで正しくメンションしたとき

  • Chatter 投稿画面で、 @[<グループ名>] の書式になっている。 f:id:mark-hammer:20201022230817p:plain

  • Chatter 投稿のうち、グループ名にマウスカーソルを当てるとグループ詳細情報が表示される。

  • Chatter 投稿で、グループ名に点線の下線がある。 f:id:mark-hammer:20201022230940p:plain

文面をコピペし、正しくメンションされていないとき

  • Chatter 投稿画面で、 @<グループ名> の書式になっている。 f:id:mark-hammer:20201022231046p:plain

  • Chatter 投稿のうち、グループ名にマウスカーソルを当てるとリンク先URLのみ表示される。

  • Chatter 投稿で、グループ名に点線の下線がない。*1 f:id:mark-hammer:20201022231147p:plain

おわりに

Chatter投稿のコピペ、ダメ、絶対。

*1:下画像はグループ名にマウスカーソルを当てているため下線があるように見えます。「はじめに」節右側の画像を見ていただくと違いが分かると思います。

Salesforce DevTools を使うには「すべてのデータの参照」権限が必要

はじめに

Salesforce DevTools、便利ですよね。
以前便利ツールとして会社で紹介したのですが、このツール、使用するためのSalesforce権限が見つからなかったんですよね。*1
そこで2020/8に自分のDeveloper Edition環境で確認したのですが、「すべてのデータの編集/参照」権限が使えないForce.com - App Subscriptionライセンス用プロファイルでも一応使えたので、「APIアクセス可能であれば一応ログインまではできるのだろう」と思い紹介したのでした。

その後、非システム管理者ユーザから「ログインしようとしてもActiveボタンしか出ず、何度Activeボタンを押してもログインできない」と言われ、GitHub経由で開発者に質問しました。

github.com

開発者の回答

その結果、開発者からは「『すべてのデータの参照』権限を付与して再度確認してもらえないか」とコメントいただきました。
また、動作確認にて「すべてのデータの参照」権限があればActiveボタンから先に進めたため、現状の必須権限は「すべてのデータの参照」権限でよいと思われます。*2

f:id:mark-hammer:20200915234242p:plain
開発者からの返答

おわりに

Salesforce DevTools には当然IssueのSLAというものはなく、放置されているIssueも結構あったので「質問はしてみるけど期待しないでね」と言ってあったのですが、即日返答いただけたので好印象でした。
今後の Salesforce DevTools の機能拡張を楽しみにしております。*3

*1:まぁシステム管理者しか使わないだろ、というのはあるのですが

*2:では「はじめに」に書いた事前チェックは何だったのか、となりますが、「直近アップデートで動きが変わった」「私の記憶違い」のどちらかかと思われます

*3:全ページレイアウトの内容がエクスポートできる機能が欲しいです…。