
【Salesforceフロー】何もわからないの谷を抜ける為のnote【変数って何!?】
Salesforceはノーコード推しです。(個人的にはコード書きたいけど)
つまり、WebのUIを使って色々なことができちゃうという事です。
色々な事とは、自動化とか自動化とか自動化ですね(嘘です)
その他にも、画面を作ってそこから自動処理を始めるみたいなことも出来たりします。
今回はその中でもフローの話しを取り上げます。
このnoteの想定読者層はフローを見たこと、触ったことがあって、既存フローの編集くらいならできるけど、0から自分で新規作成するとなると取っ掛かりがなくなっちゃってわからなくなっちゃう!みたいな人を想定しています。

この図で言うところの「何もわからない」な人たちです。

フローでプログラミングに出会う人は少なくないはず
フローが何かというと、こんな感じの画面です。なんかパーツでちょいちょいやれば実現できそうで、簡単に使えるんじゃ?ってなって良いですよね。そしてその見た目からは見えなかった牙をむくのがフローなんだそうです。プログラミング的なことをしたことがない人がこの毒牙にかかりがちなので、それを回避するためにこのnoteを書いています。

スタート地点となる開始ノードからパス(線)がでて、次のノード(この画像だと右側のフェーズが変更されましたがノード)に繋がっていて、その処理が終わると終了。というシンプルなものなのですが、これの裏で動いているのは紛れもなくApexコードで、その処理をコードを書かずとも実行できる環境を作りましたよというのがフロービルダーで作られるフローです。
ということで、これってシンプルにプログラミングなんですよね。見た目がGUIなのでとっつきやすそうに見えるのですが、中身は完全にプログラミングと同じなんです。そういったこともあり、みたことのないキーワードに拒否感を覚えてしまったり、意味わからんってなって投げ出してしまったりということが起きます。僕自身もApexからプログラミングちゃんとはじめたのですが、その時は結構時間かかりましたね。
シンプルなフローでできることをみてみよう
例を一つ挙げます
フローの中でも、レコードトリガフローというものを使うことを想定しましょう。レコードトリガフローはレコードの作成や更新時に自動的に起動するフローで、どんなオブジェクトでも基本的に発動させられます。
例えば、商談のレコードが保存された場合に、このレコードトリガフローが起動するという使い方になります。
これは先程の図でいうと、最初の点(このパーツのことをノードと表現します) 一つで表現されます。シンプルすぎてびっくり。

このノードをクリックして開くとこんな形になってると思います

オブジェクトの選択、トリガ条件の指定というものが入っていることが分かります。起動条件の設定をするのが最初のノードです。
では次に、商談内にある取引先ID(AccountId)項目を使って、取引先のレコー取引先を取得してみましょう

ノードの追加ボタン(+)を押して、リストの下の方にあるレコードを取得を選択してください。(このリスト、上下に動かせるように見えないので注意)

設定は見ての通りです。
取引先レコードを絞り込みという所で、項目にID(つまり、取引先IDですね)を、レコードの取引先IDと一致する条件で取得します。
保存するレコード数の部分は、そもそも1件しか出てこないので最初のみでOK。レコードデータの保存方法はひとまず全部取得で良いです(項目数が増えるとパフォーマンスに影響が出るのかもしれないが今の所感じたことはない)。
このあとは、レコードの更新ノードを使うことで更新がかけられたりするというのがフローの使い方です。なんとなくフローの使い方が理解できてきたでしょうか。それでは今度は変数を伴うようなフローの例を紹介してきましょう。
いよいよ変数にチャレンジしてみましょう
変数ってなんなの!!意味がわからない!そうあなたは言います。
気持ち、よく分かります。変数の気持ちに寄り添っていきましょう。
情報の格納先のことを変数と言います。
フローで変数を使う例として以下のようなものを考えてみました。
例題
取引先のカスタム項目として、「2022年度累積成約金額」という金額項目を設けます。(環境に応じて適当な例に置き換えて考えてください)
商談が成約フェーズに上がったタイミングで、2022年度の合計の成約金額を先程の取引先項目「2022年度累積成約金額」に入れて取引先レコードの情報を更新したいとします。
このような処理をフローで実現するためにはどうすればよいでしょうか
フローで実現すべき流れ
フローは先程と同様にレコードトリガーフローを使います。
商談の更新時且つ商談フェーズが受注になった時に発動させます
商談には取引先IDがついているので、それを元に2022年度の間で、商談フェーズが受注以上のものを取得します
ループ処理で取得してきた商談の金額を合計金額という名前で作った変数の中に入れていきます
取引先の項目に4を入れてから取引先を更新します
みたいな流れになります。うわー、面倒くさい!!と思いましたよね、僕も書いてて思いました。
この中ではフローとかApexプログラミングでよく使う処理が入っていて、それがループ処理と、変数の使用です。合わせてマスターできるはずなのでやっていきましょう。これさえ理解すれば結構な量の処理タスクを定義できるようになるはずです。
それでは例題に沿ったフローを作っていきます

商談レコードの更新されたタイミングでフェーズが08になったときにシンプルにしてありますがこんな形です。本当は成約済みフェーズが複数あるので、フェーズでやるよりは売上予測分類で設定したほうが理想的なかたちになります。

一番下の非同期実行を加える場合はチェックを入れましょう。リバネスでやるパターンだと、更新された情報をSlackに送信することがあるのですが、その実装をするためにはチェックを入れる必要があります。
取引先に紐づく商談のリストを取得しましょう
先ほどと似たような形ですが、商談のリストを取得します。

商談の取得条件が、取引先IDが商談の取引先IDと同じであることと、フェーズが08になっている事及び、商談の会計年度が2022年になっているものを取得してくるという形にしました。
このノード設定で取引先に紐付いた商談のリストを取得することができます。(もちろん商談が1件しか該当しない場合は一つだけしか取得されません)
取得した商談をループで回しましょう
複数商談がありますので、この各商談の売上(Amount)を全部見る必要があります。それぞれのレコードを見る処理をループ処理と言ったり、for-loopと言ったりするのですが、繰り返し処理をするためのノードが「ループ」です。

ループノードを選択したら、設定をしていきましょう。

はい出ましたー!コレクション変数!ついに変数の登場です。
先程設定した商談のリスト取得時のAPI参照名にget_acc_opps_2023という名前を付けたのですがこれが入ります。
その時は特に変数を作った感じがしなかったのに勝手に変数が作られていてその中にデータが入っていた!なんだこのコレクション変数ってやつは!!!と、ポルナレフみたいな顔になることが想像されます。
ということで、ついに出てきた変数について以下に説明していきます。
ちょっとループからは離れますが、戻ってきますのでご安心ください。
まずは変数で遊んでみましょう
変数は箱(入れ物/記憶領域)です
変数って文字通り変化する数という意味なのですが、数というと数字に捉えられてしまうのですが数だけを意味しません。変数という概念があるという話だと思ってください。
変数(箱)には種類があって、
・テキストだけが入る箱
・レコードそのものが入る箱
・数値
・通貨
・Boolean(True or False)つまり○か✗か
・日付
・日付/時間
・選択リスト/複数選択リスト
・Apex定義
と色々あるのですが、これはオブジェクトの項目に出てくるものとほぼ同義なのでイメージ沸く人の方が多いのではないでしょうか。

専用の箱を定義するのがデータ型の定義部分になります。何種類も箱があって、箱に名前をつけるのがここの作業になります。
変数には二種類ある(単一か、リストか)
加えてもう一つ考慮することがあります。この変数の箱は一つの箱なのか、連結可能な箱なのかというものです。
複数の値を許可(コレクション)というチェックボックスがあるのですが、これをつけると複数のリストとして取得することができるようになります。
例えば、今回の場合でいうと変数のデータ型をレコードにして、取引先に紐づく商談を全件取得したいという場合は商談レコードが複数返ってくることが予想されるのでコレクションとして取得します。
(コレクションと同義の用語として、リストとか配列といった表現がありますがどれも同じ用途に使われます。)
一方で、最初にやったように取引先IDを指定して取得するような場合は、IDは一意でレコードは一つしか返ってこないのでチェックを入れなくても良いということになります。(ただし、レコードが削除される可能性がある場合は1件取得の変数だとエラーになって止まるので、基本的にコレクションで良いような気がしますが)
それでは早速変数を作ってみます。これは右側のノード設定画面ではなく、左側のツールボックス上で定義していきます。

左上のボタンを押すとツールボックスが開きます。新規リソースボタンを押すと、定義画面が出ます。まずは変数を選択してください。

先程自動的に出来ていたのは商談のリスト(コレクションでした)
これを手動で作ろうとするとこのような設定になります。
データ型をレコードにしてオブジェクトを商談に設定
複数の値を許可するにチェックを入れれば商談リストを入れる変数の出来上がりです。簡単!
(データ型をレコードにしたときだけ、オブジェクトの指定欄が出てきます)
そもそもなぜ変数が必要なのか
フローなり、プログラムなり何でも良いのですが、道具を使って最終的に何かをしたいという目的があります。
それはたいてい、「この値でこのレコードのこの項目を更新したい」とか、「これらのレコードのコレクションのこの項目に入っているテキストを改行区切りで全部連結したものをSlackに投稿したい」とか、既存のデータになにがしかの処理をしたものを使って何かをするという使い方になると思います。
その際に、その処理された情報を保持する場所が必要になります。逆に言うとこれがないと処理ができないのです。
例えばAさんが1をもっていて、Bさんが2を持っています。合わせていくつですか?という例題を人間が解こうとすると、2+1=3だよね!って瞬時にわかるのですが、それはなぜでしょう。
人間は答えとなる「3」を脳内メモリ領域である海馬に短期記憶として記憶として保存し、それを口に出すというようなことをやっていると仮定できると思います。コンピュータでも同様な処理をして上げる必要があります。そのため、あらかじめ変数という形で保存場所を確保(定義)しておいて、その中にいれるという必要があります。人間の場合はあらかじめ定義なんてしなくても適当に保存ができちゃうのでかなり便利ですよね。その分簡単に忘れてしまうということもあるのですが。
ということで変数への理解が深まったところで元のループに戻りましょう
ループ処理を行う

このループの中では商談の金額(Amount)を、通貨型変数の中に積算していきます。そのためにはまず最初に格納用の変数を作る必要があります。

こんな感じですね。日本円の場合は小数点以下は無いので0、デフォルト値も0でOKです。今回は積算するためコレクションでもつ必要はありません。
変数に金額を割り当てていく
ノードのロジックの中に「割り当て」というものがありますのでそれを使いましょう。

割り当てノードというのは、何かをなにかに追加したり減算したりする為のノードです。演算子部分でどちらかを選べます。今回の設定はこんな形。

amount_2022という先程作った通貨型の変数に、ループ中のAmountを追加するという設定になっています。
これをループすればすべての商談の金額を積算することができるという訳ですね。
ここまでで肝心だったループと変数の使い方が完了です。
あとはamount_2022に入った数値を、取引先に入れればOKです。
取引先の取得と取引先の更新
このnoteを書いた当初は、取引先レコードの取得をする必要があるだろうと思っていたのですが、実は取得なんてする必要が無くて、レコードトリガフローの関連レコードとして既に取得されていました。(びっくりだよ)
取得済みなので、想定していた取得作業は飛ばして、「レコードを更新」ノードを置きましょう


My2022ContactAmountというのが2022年度の累積金額を入れる項目なのですが、カスタム項目で作っておいたもの且つ通貨項目であればなんでもOKです。
ではフローを保存して有効化しましょう。
と思ったらエラーがでました。非同期処理を入れる場合はこうして(条件の要件に一致するようにレコードを更新したときのみ)ないとだめみたいです。

あとは、商談のフェーズを8にした時にきちんと積算されているかを確認すれば完璧ですね。(動作確認もしたので問題なくいけそうです)
番外編として非同期側についてはSlackへの投稿について書こうと思ってたのですが、どこかに既に書いたような気がするのでひとまずここまでとします。(フローの本流ではないため)
その他にどんなことができるか
今回は、レコードのリストを取得してきて、その中の数値を一つのまとめるということをやりましたが逆に、一つのデータを複数のレコードに上書きするといった処理を書くこともできます。
これも同様にループでおこなうのですが、ループ内で更新してしまうとSalesforceのガバナ制限(処理時間はx秒まで、みたいな機能的な制限が設定されています)に達してしまうし単純に計算リソース食いすぎるのでやめましょうねみたいなお作法があったりします。
この場合は、ループ内でデータだけ入れておいて、ループを抜け出したあとにリストを更新するというやり方になります。
その他には、今回は親レコードである取引先としましたが、カスタムオブジェクトでオブジェクトAーオブジェクトBーオブジェクトCのような階層になっていて、Cが更新されたときにB更新して、更にAを更新するみたいなことを考える未来が来る可能性もあります。
段々と上級者になり、様々な処理を組み込ませることができるようになるときっとガバナ制限憎しみたいな所に到達するはずです。この例で言うと、処理するレコード数が多すぎてタイムアウトしてしまったり、更新ノードが増えすぎてDML回数制限に達してしまったりみたいなことが起こり得ます。
こうなってくると、レコードトリガフローのようにリアルタイム処理する必要がありますか?バッチ処理でやればよくないですか?みたいな判断が必要になったり、その他の方法で処理を考える必要性が出てきたりもします。
そこまで行くと、SalesCloudに支払ってる分くらいはコンピュータリソース使えてるんじゃないかな?みたいになれるのではいでしょうか。
上級編についてはこのnoteの範疇外だと思いますので別の機会に書ければと思っています。
まとめ
ということでフローは便利だけどプログラミングと思考が一緒なのでわからないとつまづいてしまうよねというお話でした!
こんな場合はどうすれば良いの?みたいな質問があればコメントするか、Twitterで @geeorgey までお知らせください!やってみます
最後に
Slackを利用するイメージは湧きましたでしょうか。
リバネスナレッジでは、SalesforceのAdmin/エンジニア、Heroku周りをやりたいエンジニアの採用を行っています。いつでもご連絡ください!カジュアル面談からまずはお話しましょう。