Salesforceを利用している組織において、営業担当者がカスタマイズを担当していることがあるかと思います。Salesforceの豊富な機能の中で『フロー』という機能がありますが、Too many SOQL queries: 101というエラーに遭遇することがあります。色々調べている中で、エラーを回避できるプラクティスを残している記事があまり多くないなと思いましたし、自分なりの解決方法が分かってきましたので、記事にしました。少しでも同じ苦しみを感じている人の助けになればと思います。ちなみにフロービルダーが何かを理解している方向けの記事になります。Too many SOQL queries: 101とは?Salesforce社の公式のヘルプによると、コンテキストで合計 100 個までの SOQL クエリを実行することができるガバナ制限に達した場合に、以下のエラーが表示されます。「System.LimitException: Too many SOQL queries: 101」とのことです。営業担当者がこれを見てすぐに理解はできないと思います。ほとんどの営業担当者が、「ああ、ガバナ制限でクエリがコンテキストでエラーが100個ね(震え声)」となると思います。要するに、「データベースへのアクセスを何度も何度も一度の処理の中でやらないでくれ!」という理解があれば十分です。問題の処理例えば以下のような設定を行ったとします。解説をすると、全商談情報を配列で取得1で取得した配列をループ処理するループ処理中に商談に紐づく取引先責任者の所有者をupdateするとなります。これの何が悪いかというと、ループ中に何度もUpdateを呼んでしまっているので、パフォーマンスがめちゃめちゃ悪くなります。以前GASの記事で書いていたようなことをSalesforceでもやってしまっているということです。【営業向け】マクロの実行速度を100倍ぐらい早くできたので忘備録GAS風に説明すると、SalesforceにもID付きのオブジェクトを配列に格納し、updateをかけてあげると一括で更新をかけてくれるメソッドがありますので、これを使ってあげれば何度もデータベースへアクセスをしなくて済み、制限にもかからなくなります。具体的な回避の方法具体的な回避方法としましては、ループの外で一括で更新をかけ、SOQLの発行数を少なくし、エラーを回避します。上記の設定を解説いたしますと、商談情報を配列(Salesforceではコレクション変数と呼びます)で取得コレクション変数をループ処理新しく用意した変数にループ処理で取り出したidを格納コレクション変数に3のオブジェクトを格納一括で更新の処理をかけるそれぞれの手順を3から説明します。新しく用意した変数にループ処理で取り出したidを格納新しく要素を追加をクリックするとメニューが立ち上がるので『割り当て』を選択。割り当ての編集画面が表示されるので、『新規リソース』を選択。リソース種別を聞かれるので、変数を選択。変数の名前などを聞かれるので、適当に分かりやすい名前を設定し、データ型は『レコード』、オブジェクトは『取引先責任者』を選択。新しく用意した new_contact_valiable という変数に、idと所有者をセット。演算子は『次の文字列と一致する』を選択してください。演算子に『次の文字列と一致する』を選択することに、若干の違和感を感じるかと思いますが、GASで説明すると以下のようなことをしているとイメージしていただければと思います。var getAllOpportunity = getOppRecords();//商談のレコードを取得するメソッドが定義されていえると考えてくださいvar new_contact_valiable = new Contact();//Contactオブジェクトが定義されていると考えてくださいgetAllOpportunity.forEach(function(roopOppList)){ new_contact_valiable.Id = roopOppList.OppRepresentative.id; new_contact_valiable.OwnerId = roopOppList.OwnerId;}コレクション変数に3のオブジェクトを格納手順3と同じように、新しくリソースを用意します。今回用意する変数はコレクション変数になりますので、『複数の値を許可』をチェックします。これにより空のコレクション変数を用意できます。最後に、3で用意した new_contact_valiable をコレクション変数に追加します。コードで表現すると以下のようなイメージです。var getAllOpportunity = getOppRecords();//商談のレコードを取得するメソッドが定義されていえると考えてくださいvar new_contact_valiable = new Contact();//Contactオブジェクトが定義されていると考えてくださいvar collection_valiable_for_update = [];//空のコレクション変数を用意getAllOpportunity.forEach(function(roopOppList)){ new_contact_valiable.Id = roopOppList.OppRepresentative.id; new_contact_valiable.OwnerId = roopOppList.OwnerId; collection_valiable_for_update.push(new_contact_valiable);}一括で更新の処理をかける最後に、ループの外で更新の処理をします。『レコードまたはレコードコレクションからのID及びすべての項目値を使用』をチェックし、新しく用意をした collection_valiable_for_update というコレクション変数を指定します。まとめ手順だけざっと説明しましたが、やっていることは以下のようなイメージになります。少し複雑ですが、慣れてくるとフローを利用して様々な自動化処理を実装することができるようになります。レコードの更新だけでなく、メールの送信や、chatterの投稿なども可能です。時代はノーコードですね。もはやコーディングをすること自体が古い時代になるのかもしれません。あらゆるSaaSでノーコードでカスタマイズする時代が来る気がしています。非エンジニアでもデータ構造とアルゴリズムをきちんと理解していることはとても大事です。