tyoshikawa1106のブログ

- Force.com Developer Blog -

SFDC:定期的にApex処理を実行する方法

定期的にApex処理を実行するには「Apexをスケジュール」の機能からスケジュール登録して実行できます。
f:id:tyoshikawa1106:20160109134440p:plain

f:id:tyoshikawa1106:20160109133937p:plain


通常、バッチを実行するための機能として利用すると思うのですが、『implements Schedulable』を宣言していれば、ただのApexクラスも実行することが可能です。


ちょっとした処理ならバッチ処理ではなくただのApex処理で対応できないかなと思い、先月作成されたレコード件数を集計する処理をつくってみました。

RecordCountMonthMonitoringScheduler.cls

implements Schedulableを宣言したクラス
f:id:tyoshikawa1106:20160109135118p:plain

RecordCountMonthMonitoringConnect.cls

ここで通常のApex処理を実行 (Not Apex Batch Version)
f:id:tyoshikawa1106:20160109135129p:plain

RecordCountMonthMonitoringController.cls

集計処理を行うApexクラス
f:id:tyoshikawa1106:20160109135138p:plain


Apexスケジュールのクラス構成についての詳細はこちら

集計処理の概要

処理を実行すると、先月作成されたレコード件数をSELECT COUNTをつかって集計します。
f:id:tyoshikawa1106:20160109135716p:plain


集計期間と一緒にレコード件数を登録していく感じです。
f:id:tyoshikawa1106:20160109135533p:plain


Apexバッチのようにstartメソッドで大量レコードを取得して、forループで集計していくより簡単に取得できるかなと思いました。


コンストラクタ処理を実行するとシステム日付を基準に「先月の年と月」の値を取得して、それを集計範囲として集計処理を行います


このとき「年と月」は引数で渡せるようにもしておくと、何らからの理由で過去分のレコードを集計したいときにも対応できるようになります。
f:id:tyoshikawa1106:20160109140246p:plain


手動実行は開発者コンソールから行います。
f:id:tyoshikawa1106:20160109140755p:plain


これで任意の期間分の集計レコードも作成できます。
f:id:tyoshikawa1106:20160109140549p:plain

やってみて・・・

COUNTクエリで取得することで、Apexバッチに比べて短時間で処理できて良いんじゃないかなと試してみたのですが、COUNTクエリの場合、取得上限に50000件までの制限があります。


ガバナ制限の詳細はこちら


集計件数が大きい場合は、Apexバッチを使う方が良さそうです。(最初は件数が少なくても利用していく内に件数が大きくなる可能性も考えられます。)


今回の試したサンプルのように集計期間が1ヶ月と範囲を指定すれば大丈夫かなと思ったのですが、データ移行などで大量に作成された場合にパンクする可能性がありました。(あと5万人ユーザがいる場合は1人、1レコード作成したら5万件になりますが...)


やっぱり基本はApexバッチで対応するようにしておく方がいいかなと思います。実際に動かしてみていろいろ気づけたので良かったです。

おまけ

クエリを実行する場合は、LIMITの宣言を行っておくと安全です。(WHERE的に件数が絞られる場合は大丈夫)
f:id:tyoshikawa1106:20160109143258p:plain

サンプルコード