はじめまして。エンジニアのnishimuです。弊社では業務管理にSalesforceを利用しています。Salesforceはデフォルトのままでも使えるのですが、足りない機能を独自に実装することもできます。ただしSalesforceの開発にあたっては気を付けなければいけない様々なポイントや、引っかかりやすい罠が存在します。今回はSalesforce開発初学者が引っかかりそうなポイントを自分の経験をもとに紹介します。

ではいってみましょう。

リソース制限という罠

SalesforceのプラットフォームであるForce.comの使用にあたっては、リソース上の制限が存在します。しかもその制限がわりと厳しめで多岐に渡っています。(詳しくはこちらのページ中の「Salesforce.comの制限クイックリファレンスガイド」を参照のこと)

・ガバナ制限

特にApex処理に関する制限は『ガバナ制限』と呼ばれています。せっかく組んだ処理が実際に動かしてみると制限にひっかかって動かなかったりすることがあるので、設計段階からこのガバナ制限を意識することが重要です。

引っかかりやすい主なガバナ制限を紹介します。現時点(2014/05/07時点)での制限

  1. 単一トランザクション内で発行されるSOQLクエリの合計数…100 (非同期処理時は200)
  2. 単一トランザクション内でSOQLクエリによって取得されるレコードの合計数…50,000
  3. 単一トランザクション内で発行されるDMLステートメントの合計数…150
  4. 単一トランザクション内でDMLステートメント、Approval.process、またはdatabase.emptyRecycleBin の結果として処理されるレコードの合計数…10,000

SOQLについての詳しい説明はここでは割愛させていただきますが、SalesforceのDBにアクセスするための言語です。Salesforce版SQLみたいに思っておいていただければと思います。「Database.getQuerylocatorによって」と書いてあるのは「SOQLの実行によって」と読み替えて頂いて大丈夫かと思います。ただしSOQLでできるのはデータの参照のみです。データの更新や削除といったデータ操作を行うのがDMLステートメントになります。

つまり、1.~4.に挙げた制限はつまりざっくりと言ってしまうと、

  1. 一連の処理の中でDBからデータを取得する処理は合計100回まで実行可能ですよ
  2. 一連の処理の中で取得できるDBのレコードは合計50,000件までですよ
  3. 一連の処理の中でDBのデータを編集、削除する処理は合計150回まで実行可能ですよ
  4. 一連の処理の中で編集・削除できるDBのレコードは合計10,000件までですよ

ということです。処理の回数制限はかなり厳しいです。出来る限りレコードはまとめて取得・操作するよう意識して処理を組む必要があります。forループの中でSOQLやDMLの処理を実行していたりするとたやすく制限に引っかかってしまうので注意しましょう!!!

・SOQLのOFFSET値制限

SOQLではSQLと同じようにOFFSET値を設定できます。しかし、OFFSETに設定できる値は2000以下に制限されます。

例えば、以下のSOQLクエリはエラーとなります。

これはつまり、1ページに20件までを表示できるページャ付き一覧画面を実装したいとして、101ページ目以降のデータが取得できないことを意味します。かなり困った制限です。レコードを2000件以下に抑えられるように絞り込み検索機能を付けるなどしておきましょう。

・カスタム項目の制限

カスタム項目というのは一般的なDBでいうところのカラムのことです。カスタム項目を定義するときにも制限があります。その中でも「積み上げ集計項目は1つのカスタムオブジェクト(テーブル)につき10個まで」という制限には注意が必要です。積み上げ集計項目というのは、そのレコードの子レコードに関する集計を行った結果を格納する自動計算カラムです。これを使えば、顧客レコードについて、「紐づいている商談の合計金額値」という集計も簡単に行うことができます。実際に自分が開発していた際には積み上げ集計項目を12個ほど作るつもりで設計をしていたのですが、この制限のことが頭になく、設計見直しをすることになりました…。

デバッグにまつわる罠

開発の効率はデバッグのしやすさにかなり左右されるかなと思うのですが、Salesforceは残念ながらかなりデバッグに関しては貧弱です。

・埋もれるSystem.debug()

処理中の変数の中身が知りたいとき、適当なprint文を使ってその変数の中身を出力させてみるというのが基本的な方法だと思います。ApexにおいてはそれはSystem.debug()によって行うことになります。

しかしデバッグログにはSystem.debug()の出力の他にも色々な情報が載っています。例えば次の2行のレコードを実行させてみます。

このコードのデバッグログの出力は以下の通りです。

上記のうち、必要なのは以下の行だけです。

このようにデバッグログには様々な情報が含まれています。上記の例では単純な処理を実行させてだけでしたが、テストメソッドを走らせた際にはおびただしい量のデバッグログが吐き出されることになります。残念ながらSystem.debugの出力だけを表示させる方法はないようです。仕方がないので検索できるように目印を仕込んでおきましょう。

しかし、検索性にも問題があります。
開発の際にはForce.com IDEを使うことが多いかなと思うのですが、残念ながらForce.com IDEで実行したデバッグログは検索することができず(下図)、検索ができる他のテキストエディタにコピー&ペーストをしなければならないという面倒な作業をする必要があります。これが検索できるようになればかなり効率があがると思うのですが、残念ながらForce.com IDEでは対応していないようです…。
※windows+Sublime Text+MavensMateの環境ならばデバッグログをウェブブラウザ上で閲覧する仕組みになっているので検索できたりします。(MavensMateオススメです)
Force.com IDE Debug Window

・参照関係にあるオブジェクトの内容はSystem.debugで同時に表示することができない

例えばこんなクエリで商談ID、商談名、取引先名、取引先電話番号からなる商談リストのデータを取得したとします。

ここでSystem.debug(opps[0])を実行して、取得した商談リストの一つ目を表示させてみます。ここでデバッグログ上で表示されるのは以下の内容です。

そうです。商談の項目しか表示されません。ここで参照関係にある取引先の項目を表示させようとすると以下のようにしなければなりません。

こうすることでデバッグログには以下のように出力されます。

オブジェクトが別なので分からんでもないですが、少し面倒ですね。

データインポート時の罠

・データローダでインポートしたデータの日付カラムが一日ずれる

他のシステムで行っていた業務をSalesforceに移行する際には、Salesforceへのデータのインポート作業を行うことになります。データインポート作業にはデータローダを使用することになるかと思うのですが、このデータローダを使う際に注意しなければならないのが、タイムゾーンの設定です。
このナレッジ記事に書いてあるように、何も考えずにデータをインポートすると日付(Date)型の項目の日付が一日ずれます。
記事にあるようにデータローダのタイムゾーン設定を変更してからインポートしましょう。

まとめ

今回はSalesforce初学者がつまづきやすいポイントとしてリソース制限、デバッグ、データインポートを挙げました。細かいところになるともっと色々とつまづきポイントがあるのですが、記事が長くなってしまうのでこのあたりにしておきます。今回取り上げた項目のうち、リソース制限に関しては特にシビアに気にする必要があります。開発環境では動いていても本番環境で実際にデータを入れて運用したときに動かない…、という悲惨な事態も十分に起こり得ます。

Salesforce開発に関わると様々な罠に出くわします。どんな罠があるかを把握している人が周囲にいない場合は罠を踏みながら覚えていくことになると思いますが、この記事がほんのちょっとでもSalesforce開発を始めた人の助けになればと思います。

ここまで読んでくださり、ありがとうございました。