LoginSignup
8
6

More than 3 years have passed since last update.

[Apex]レポートの集計値を取得する方法

Last updated at Posted at 2020-12-13

この記事は Lancers(ランサーズ) Advent Calendar 2020 14日目のエントリーです。

はじめに

ランサーズ株式会社でSalesforce管理者兼開発者を担当している久保です。
4月に新卒として入社し、6月ごろからSalesforceチームメンバーとして、ゴリゴリ開発させていただいております。(ランサーズでのSalesforce運用の歴史はコチラ

さて、今日はApexでレポートデータを取得する過程を深ぼろうと思います。
というのも、「公式のApex開発者ガイドに取得方法が載っているが、一体どういうロジックなのか分からない」という人の助けになれたらと思ったためです。

レポートの集計値を取りたいと思ったキッカケは、日次の売上金額推移をSlack通知したいと思ったことからです。レポート作成スナップショットで日次の金額をレコードに保存し、レポートでそれらのレコードの金額集計を弾き出して、Slack通知させるロジックを書くときに必要になりました。

前提

今回の解説では、下記レポートの枠部分の値を取得することを目標とします。
つまり、フェーズ別商談金額レポートのフェーズがClosedWonの時の金額合計値を取得します
(下記はTrailheadのPlayground組織のテストデータです。詳細行はカットしてます)
スクリーンショット 2020-12-13 14.47.20.png

取得手順

①抽出対象のレポートからIdを取得、実行
②レポートの最初のダウングルーピングを取得
③ファクトマップの取得
④取りたいサマリー値の取得

//①抽出対象のレポートからIdを取得、実行
List <Report> reportList = [SELECT Id,DeveloperName FROM Report where DeveloperName = 'new_report_mdR'];
String reportId = (String)reportList.get(0).get('Id');
Reports.reportResults reportResults = Reports.ReportManager.runReport(reportId, true);

//②レポートの最初のダウングルーピングを取得
Reports.Dimension dim = reportResults.getGroupingsDown();
Reports.GroupingValue groupingVal = dim.getGroupings()[8];

//③ファクトマップの取得
String factMapKey = groupingVal.getKey() + '!T';
Reports.ReportFactWithDetails factDetails = (Reports.ReportFactWithDetails)reportResults.getFactMap().get(factMapKey);

//④取りたいサマリー値の取得
 Reports.SummaryValue sumVal = factDetails.getAggregates()[1];

①〜④でそれぞれ何をしているのかを以下で解説します。

①抽出対象のレポートからIdを取得、実行

List <Report> reportList = [SELECT Id,DeveloperName FROM Report where DeveloperName = 'new_report_mdR'];
String reportId = (String)reportList.get(0).get('Id');
Reports.reportResults reportResults = Reports.ReportManager.runReport(reportId, true);

まず、SOQL文で取得対象のレポートの抽出をします。
ここで条件にあるDeveloperName とは「レポートの一意の名前」のことを指します。
下記キャプチャのように、レポート編集画面のプロパティで確認できます
image.png

そして、取得したリストからget(0).get('Id')でレポートのIDを取得します。
取得条件により、リストの中の要素は唯一つですので、get(0)で対象のレポートを選択できます。

次に、ReportManagerクラスのrunReportメソッドにより、レポートを実行します。
ただし、2番目の引数は詳細行を含むか含まないかの選択を意味します。
(※因みにrunAsyncReportメソッドというのもあり、非同期にレポート実行させることもできます)

②レポートの最初のダウングルーピングを取得

Reports.Dimension dim = reportResults.getGroupingsDown();
Reports.GroupingValue groupingVal = dim.getGroupings()[8];

今度は、①のrunRepotメソッドにより実行した結果からグルーピングの情報を抽出します。
具体的にはrepotrResultsクラスのgetGroupingsDownメソッドを用いて、ダウングルーピング(=行グルーピング)の情報を抜き取ります。(※因みに、getGroupingsAcrossメソッドで列グルーピングの情報を取得できます)

実際、System.debug(dim)で中身を見てみると、確かに行グルーピングしたフェーズの情報が順に書いてあります。

DEBUG|Reports.Dimension[groupings=(Reports.GroupingValue[groupings=null, key=0, label=Prospecting, value=Prospecting], Reports.GroupingValue[groupings=null, key=1, label=Qualification, value=Qualification], Reports.GroupingValue[groupings=null, key=2, label=Needs Analysis, value=Needs Analysis],,,,

そして、DimensionクラスのgetGroupingメソッドで、取得したグルーピング情報をリストとして受け取ります。
今は、取得したい値はレポートのグルーピングの上から9番目の項目である、ClosedWonの時の値なのでdim.getGroupings()[8]とすれば、ClosedWonのキーやラベルが手に入ります。

③ファクトマップの取得

String factMapKey = groupingVal.getKey() + '!T';
Reports.ReportFactWithDetails factDetails = (Reports.ReportFactWithDetails)reportResults.getFactMap().get(factMapKey);

さて、GroupingValue クラスのgetKeyメソッドで、行グルーピングのキーを取得し、ファクトマップキーを作成します。
ここでファクトマップキーとは、「どのグルーピング項目か」を表すキーのことを言います

例えば、0!Tなら「第1グルーピングの最初の項目」、1!Tなら「第1グルーピングの2番目の項目」、0_1!Tなら「第1グルーピングの最初の項目と第2グルーピングの2番目の項目」のことを指します。

このファクトマップキーを用いて、reportResults.getFactMapメソッドでファクトマップを取得します。
取得したファクトマップは以下です。確かに、ClosedWonの時の小計値である期待収益や金額が並んでいます

Reports.ReportFactWithDetails[aggregates=(Reports.SummaryValue[label=¥3,645,000, value=3645000.000000000000000000], Reports.SummaryValue[label=¥3,645,000, value=3645000.000000000000000000], Reports.SummaryValue[label=18, value=18]), key=8!T, rows=(Reports.ReportDetailRow[dataCells=(Reports.ReportDataCell[label=Express Logistics and Transport, value=0012r000006VpxRAAS], Reports.ReportDataCell[label=Express Logistics Standby Generator, value=0062r000003ymAnAAI],,,

④取りたいサマリー値の取得

 Reports.SummaryValue sumVal = factDetails.getAggregates()[1];

最後に、ファクトマップから取りたい小計値を取得します。
ReportFactWithDetailsクラスのgetAggregatesメソッドで小計値のリストを取得します。
そして、今回の場合、レポートの左から2番目の行項目である「金額」を取得したいので、リストの2番目を指定すれば、完了となります。

最後に

レポートの集計値取得はフロー等ではできない(と思われる)ため、Apexを駆使することになります。
しかし、取得したい集計値は特定可能な数個になるかと思います。そのため、フローのApexアクションで呼び出すことができるので、取得結果を活用する事に限っては、十分フローが使えます。

以上の事柄がSalesforce開発者の方々の役に立てば本望です。
最後までお読みいただきありがとうございました。

参考

Apex開発者ガイド レポートデータの取得
Apex開発者ガイド ファクトマップの復号化

8
6
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
6