レポートの期間集計やってみた

はじめに

こんにちは!株式会社オプトプランニングです。
Salesforce(Salesforce.com/セールスフォース・ドットコム、略してSFDC)であれこれやってみたことを書いていきます。

レポートを作成していると「過去の月ごとの商談件数が知りたい」や「月ごと・週ごとの金額の合計がわかればいいな」など、データを期間ごとに集計したい場面は多いと思います。

そんな時に使うのが、「期間集計」です。

これは、データ型が「日付」「日付/時間」項目の場合、簡単な設定で任意の期間で集計をすることができるものです。

今回はLightning Experienceでの期間集計の方法や、やってみて分かったこと、他の方法などを書いていきたいと思います。

※2023/1/30 訂正・追記あり

日付項目を年月(YYYYMM月)で期間集計してみた

早速、期間集計をやってみようと思います!

今回使用するレポートは、以前のブログでも使用したTrailheadのモジュールをダウンロードした時に入っていた図1のレポートです。
(どのモジュールだったかは前回から思い出せておりませんのであしからず)

まずは、右上の「編集」をクリックしてレポートの編集画面を表示させます。

図1 使用レポートの編集
図1 使用レポートの編集

今回は、レポート内にある「完了予定日」を期間集計してみたいと思います。
日付項目を期間集計するには、対象の項目がグループ化された行または列に存在する必要があります。

列にある項目「完了予定日」を期間集計しようとしてみても、以下のように期間集計できる項目が出てきません。

図2 「完了予定日」グループ化前
図2 「完了予定日」グループ化前

そこで、「完了予定日」を行グループに移動して期間集計しようとすると…
「集計期間単位」という項目が出てきました!

期間集計は、この「集計期間単位」で任意の単位を選択することで設定します。

今回は「年月」で集計しようと思うので単位に「年月」を選択します。
(図3のようにデフォルトでは「日付」が選択されていますが「年月」をクリックすると選択できます)

図3 「完了予定日」グループ化後
図3 「完了予定日」グループ化後

すると、日にちまで表示されていた「完了予定日」が年月のみの表示に変わりました!

図4 「完了予定日」を「年月」単位で期間集計
図4 「完了予定日」を「年月」単位で期間集計

編集時は表示されるデータが少ないため、期間集計で何が変化するのかわかりにくいですが、期間集計する前後のレポートを見比べてみると以下のようになります。

左図が「完了予定日」を期間集計する前、右図が「完了予定日」を期間集計した後です。
(わかりやすくするため、基準とグラフ種類を変更しています。)

図5 期間集計前
図5 期間集計前
図6 期間集計後
図6 期間集計後

期間集計前は日ごとに集計されていたのが、「年月」で期間集計したことで月ごとに集計されるようになりました。

オブジェクトの項目を増やしたりすることなくこのような集計が行えるのはとても便利ですね!

実際にやってみてわかったことや気をつけたいこと

期間集計はあくまで集計するための機能

期間集計を行う場合、対象の項目がグループ化されていなければなりません。
期間集計が表示されない場合は、対象の項目をグループ化しているかどうか確認してみましょう。

あくまで「集計」機能なので、データの表示形式を変更するためのものではないということを念頭に入れておきましょう。

また、期間集計を行う項目はグループ化しなければならないため、表形式のレポートでは使用できません

期間集計を行った項目の表示内容

期間集計を行った項目は、期間集計で選択した単位でしか表示されなくなります。

今回やってみた期間集計を例にすると、「完了予定日」を「年月」で期間集計したレポートは、完了予定日の年月だけ表示され、完了予定日の日付は表示されません

集計は「年月」で行いたいけど、日付や時間などの表示もレポートに表示したいのに…という時は気をつけたい部分です。

データ内容は変わらないので、表示されていない情報(例で言えば「完了予定日」の日付)はレコードを参照すればいいのですが、いちいちレコードを参照するのも面倒に感じてしまいます。
期間集計を行う項目は、期間集計後の表示でいいかの判断が必要かもしれません。

エクスポートをやってみてわかったこと

エクスポートをしてみると期間集計を行った項目に関して影響が出る場合があります。

「フォーマット済みレポート」の場合、期間集計を行う前後でエクスポートされるデータ内容が変わります

先ほどの期間集計した前後のレポートをエクスポートして比較すると以下のようになります。

図7 期間集計前後のレポートのエクスポート結果(フォーマット済みレポートの場合)
図7 期間集計前後のレポートのエクスポート結果(フォーマット済みレポートの場合)

「フォーマット済みレポート」でエクスポートした時、期間集計した項目はレポートで表示された内容のままエクスポートされます。

期間集計を「年月」で行ったレポートをエクスポートすると、エクスポートしたファイルでは「完了予定日」の日付は分からなくなってしまいます。

「詳細のみ」でエクスポートした場合は、期間集計を行う前後でデータ内容は変わりません

期間集計する前後のレポートをエクスポートした比較は以下です。

図8 期間集計前後のレポートのエクスポート結果(詳細のみの場合)
図8 期間集計前後のレポートのエクスポート結果(詳細のみの場合)

「詳細のみ」でエクスポートした時、期間集計した項目はレコードデータに基づいた内容でエクスポートされます。

期間集計を「年月」で行ったレポートでも、エクスポートしたファイルから「完了予定日」の日付がわかります。

期間集計を行いたいけど、項目の表示形式は変更したくない!!

行レベルの数式を使ってみよう

年月などの期間集計はやりたいけど、対象項目の表示形式はそのままにしておきたいという場合もあると思います。

また、エクスポートの結果からレポートの期間集計は使いにくいということもあるでしょう。

そんな時に私が思いついたのは、期間集計を行いたい項目を利用して「行レベルの数式」を作成し、その数式を集計項目に利用する方法です。

行レベルの数式を作ってみた

行レベルの数式もレポート編集画面から簡単に作成できます。

レポート編集画面を開いたら「列」の右にある「▼」をクリックすると「行レベルの数式を追加」があるのでクリックします。

図9 行レベルの数式を追加
図9 行レベルの数式を追加

「行レベルの数式列を編集」画面が開くので、以下のように設定します。

「列の名前」はレポートに表示される項目名になるので、必要があれば「説明」に数式の内容を書いておくといいと思います。

列の名前完了予定年月
数式出力種別テキスト
数式MID(TEXT(CLOSE_DATE),1,4) & ‘年’ & MID(TEXT(CLOSE_DATE),6,2) & ‘月’

この数式は「完了予定日」の年月部分だけをテキスト形式で表示させるものになります。
※2023/1/30数式訂正。詳細は追記を参照

図10 行レベルの数式列の編集画面

適用をクリックすると行レベルの数式が作成されているので、作成した数式でグルーピングを行います。
同時に、期間集計に使用していた「完了予定日」は列の方に戻してみます。

図11 数式をグルーピング
図11 数式でグルーピング
図12 数式で集計したレポートの表示
図12 数式で集計したレポート

すると、「完了予定日」の「年月」で集計しつつ、「完了予定日」の内容をレポート上に表示できるようになりました!!

ついでにエクスポートもしてみた

行レベルの数式があるレポートを「詳細のみ」でエクスポートしてみるとどうなるか試してみました。

すると…

図13 数式で集計したレポートのエクスポート結果
図13 数式で集計したレポートのエクスポート結果

行レベルの数式も項目としてデータをエクスポートできることが分かりました!!!

これだと、エクスポート後のデータの活用に幅が広がるかもしれませんね~

おわりに

期間集計ですが、実務の方ではLightning Experienceでの期間集計方法がわからず、苦肉の策として編み出したのが行レベルの数式を作成して集計をしてみることでした。

行レベルの数式を作成した後に期間集計の方法が分かったのですが、期間集計した項目の表示だと私が作成したいレポートでは表示内容が不十分なことが多く、そのまま行レベルの数式で集計を行うレポートもありました。

今回書くにあたって、エクスポートについてもいろいろ試してみてより理解が深まったので、この気づきを生かして利用者が使いやすいレポート作成を心掛けていきたいと思います!

それでは、またお会いしましょう!!

追記

2023/1/30、完了月が正しく並び替えできないという問題があるため数式を訂正しました。(初歩的なミスですみません)

当初の数式【 TEXT(YEAR(CLOSE_DATE)) & ‘年’ & TEXT(MONTH(CLOSE_DATE)) & ‘月’) 】と訂正後の数式【 MID(TEXT(CLOSE_DATE),1,4) & ‘年’ & MID(TEXT(CLOSE_DATE),6,2) & ‘月’ 】の「完了予定年月」の表示を忘備録として載せておきます。

追記1 当初の数式
追記1 当初の数式
追記2 訂正後の数式
追記2 訂正後の数式

訂正後の「完了予定年月」は正しく並び替えできています。

今回、参考にした数式は公式ヘルプに紹介されていました。

[数式 サンプル] 日付型項目から年・月を抽出する数式

AWS CLIで情報を出力しよう 色々編(Linux版その4)

1. AWS CLIコマンドのヴァージョンアップをしよう

$curl https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o "awscliv2.zip"
$unzip awscliv2.zip
$sudo ./aws/insstall --update
$aws --version
aws-cli/2.9.10 Python/3.9.11 Linux/5.10.157-139.675.amzn2.x86_64 exe/x86_64.amzn.2 prompt/off

2022/12/27 時点で最新バージョンです 詳しくは、以下を参照 AWS CLI 最新バージョンをインストールまたは更新する
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html

2. 前回の復習 InternetGW情報を出力しよう

InternetGWの情報を必要な項目のみ出力してみよう

$aws ec2 describe-internet-gateways \
--query "InternetGateways[].[{VPC_id:Attachments[0].VpcId,Name:Tags[0].Value}]" --out table

             図 A InternetGWの情報

3. AWSが保持しているグルーバルアドレスCIDRを表示しよう

3.1 AWSが保持している東京リージョンのグローバルCIDRの表示

AWSが保持しているグルーバルアドレスのCIDRが公開されています。(json形式)その内容から東京リージョンのIPレンジのみを出力します。

$curl https://ip-ranges.amazonaws.com/ip-ranges.json | \
jq -r '.prefixes[] | select(.region=="ap-northeast-1") | .ip_prefix'

curl コマンドでjsonファイルを取ってきます。 jp コマンドでリストになっているprefix[]からreginがap-northeast-1(東京)のもので、ip_prefix項目のみ出力させます

jq コマンドは以下でインストールしてみてください

$sudo yum install jq

            図B 東京リージョンのIPアドレスレンジ

3.2AWSが保持している東京リージョンでEC2のグルーバルアドレスCIDRを表示

東京リージョンでEC2のIPレンジのみを出力します。

$curl https://ip-ranges.amazonaws.com/ip-ranges.json | \
jq -r '.prefixes[] | select(.service=="EC2" and .region=="ap-northeast-1") | .ip
_prefix'

curlコマンドでjsonファイルを取ってきます。jpコマンドでリストになっているprefix[]からreginがap-northeast-1(東京)かつ serviceがEC2のip_prefixのみを出力させます

           図C 東京リージョンEC2のIPアドレスレンジ

4. AWS Health イベントで使用されるサービス名の一覧を出力

HealthイベントをEventBridge経由で監視するイベントルールの対象を特定のサービスとする場合に、対象のサービス名は、”A2I”、”SSM”と選択可能である、これがなんのサービスかわかりたい

$aws health describe-event-types

             図D Health サービス名一覧

Health イベントで使用されるサービス名の一覧は、aws health describe-event-types コマンドで出力できます。json形式で出力されます。沢山出力されるのである程度絞り込みを行います。

$aws health describe-event-types | \
jq -r '.eventTypes[] | select(.service=="SSM" or .service=="A2I") | .code'

   図E Health A2IとSSMに絞り込み出力

Health イベントで使用されるサービス名の一覧は、aws health describe-event-types コマンドで出力できます。これでは、沢山出力されるので、対象を絞ります。 jqコマンドのselectを利用して SSMとA2Iに絞ります。そして、codeの部分のみを出力します。A2IはAmazon Augmented AI(AmazonA2I)のことだそうです。「A2I aws」で検索するとヒットします。

5. AWS WindowsのAMI一覧を出力しよう

Windows-serverのAMIはどのような物があるか、質問が良くあります。AWS CLIコマンドを使って出力できます。(Windows-server2019の例です)

$aws ec2 describe-images \
--owners amazon \
--filters "Name=name,Values=Windows_Server-2019-*" \
--query "sort_by(Images,&Name)[].[Name,ImageId]" \
--out table

           図F  windows-server-2019 AMI情報

imageは、aws ec2 describe-imageコマンドで出力します。filterオプションで windows_Server-2019-*のみを対象にします。更に、queryで ImagesNameとImageIdをsortして出力します。

6. routeテーブルを見て、publicサブネットかどうか判断しよう

publicサブネットかどうかは、routeテーブルを見ないとわかりません。ルートテーブルの(0.0.0.0/0)があるかどうかで判断できます。

$aws ec2 describe-route-tables \
--query "RouteTables[].{Sub:Associations[].SubnetId,Id:RouteTableId,rou:join('<->',Routes[].DestinationCidrBlock),INgw:Routes[].GatewayId}"\
--out text

            図G ルートテーブルと0.0.0.0/の関係

routeテーブルを出力します。queryで出力項目を絞り込みます。Associations[].SubnetIdとRouteTableId,join(‘<->’)で文字列を加え、Routes[].DestinationCidrBlock,Routes[].GatewayIdを出力します。<->0.0.0.0/0があるサブネットがpublicサブネットです。

Linux版その1 EC2の情報出力 https://opt-p.co.jp/blog/aws/post-1633/

Linux版その2 RDSの情報出力 https://opt-p.co.jp/blog/aws/post-1718/

Linux版その3 VPCの情報出力 https://opt-p.co.jp/blog/aws/post-2080/

Apexを使った1日に複数回動作させるバッチ処理

セールスフォース

 Salesforceでバッチ処理を作成する方法としてはフロー処理の中の「スケジュールトリガーフロー」を使ってフロー処理として記述することが可能ですが、フローを動作させる頻度が「1回のみ、毎日、毎週」しかなく、1時間ごとに動作させるような設定ができません。

 今回は、10分ごとに処理を行うための実装をApexを使って行います。

1.バッチクラスとスケジュールクラス

 スケジュールの開始はスケジュールクラスを継承したクラスで実施し、この中からバッチクラスを呼び出し、バッチを実行します。

1.1 バッチクラスの作成

 バッチクラスを実装するためにはバッチクラスをインプリメントする必要があります。

 public class xxxxBatch implements Database.Batchable<sObject>,Database.Stateful { ....

 また以下のメソッドを実装する必要があります。

  
/* バッチ処理開始時に最初に呼び出される。バッチ処理対象となるレコードを返却するQueryLocatorを返す。*/ 
public Database.QueryLocator start(Database.BatchableContext bc) {
       処理
       return Database.getQueryLocator(xxxxx);
}
/* バッチサイズで指定されたレコード数の単位で、呼び出される。*/
public void execute(Database.BatchableContext bc,List<sObject> executeRecords) {                   
       処理
}
/* バッチ処理の終了時に呼び出される。終了処理があれば実装する */
public void finish(Database.BatchableContext bc) {
       処理
}

 それぞれのメソッドの記述内容は以下の様になります。

 startメソッドでは、DBの情報を取得するためのQueryを作成しそれを返却します。

public Database.QueryLocator start(Database.BachableContext bc) {
           string query = 'select XXXX from YYYY';           return Database.getQuery(query);
}

 startメソッドの終了後、executeメソッドが呼び出されます。その際startの返却値であるQueryが実行され、その結果がexecuteメソッドの第二引数に渡され、executeメソッドが呼び出されます。
 executeメソッドでは主たる処理を記述します。

public void execute(Database.BatchableContext bc,List(sObject> executeRecords) {
       ......
       for(hoge xx : executeRecords) {
          .........
       }
       .......
}

 executeメソッドに引き渡されたQeryの実行結果を順に取り出して処理を実施します。
 executeメソッドでExceptionが発生した場合、このトランザクションで実行されたものがロールバックされてしまいます。そのため、この処理の中でメール送信などを行っている場合にはメールを送信する処理もトランザクションの一部となるためメールが送信されないことになります。
 そのためtry~catch()を使用してExceptionを捕まえて処理することが必要となります。
 最後にfinishメソッドが実行されます。今回はこのfinishメソッド中で次のスケジュールを設定します。

public void finish(Database.BatchableContext bc) {
       DateTime nextSchedTime = DateTime.now().addMinutes(10);
       xxxxBatchSchedule cls = new xxxxBactchSchedule();
       String nextJobName = 'xxxBatchSchedule_'+nextSchedTime.format('yyyyNNddHHmm');
       String schd = nextSchedTime.format('0 m H d M ? yyyy');
       System.schedule(nextJobName,schd,cls);
}

 スケジュール設定について簡単な説明を以下に記載します。

DateTime nextSchedTime = DateTime.now().addMinutes(10);

 次にバッチを起動する時間を設定しています。10分毎にバッチ処理を実施するため、現在時間にaddMinutes()メソッドをつかって10分を加算し、次にバッチ処理を起動する時間を算出しています。

  xxxxBatchSchedule cls = new xxxxBactchSchedule();

 次節で説明するスケジューラクラスをインスタンス化しています。

  String nextJobName = 'xxxBatchSchedule_'+nextSchedTime.format('yyyyNNddHHmm');
  String schd = nextSchedTime.format('0 m H d M ? yyyy');

System.scheduleメソッドに渡すための、スケジュール名と、スケジュール設定する時間を作成しています。スケジュール名は一意でないといけないので、スケジュール時間を付加しています。

System.schedule(nextJobName,schd,cls);

スケジュール設定を行っています。

1.2 スケジュールクラスの作成

 スケジュールクラスでは、Schedulableをimprementします。またスケジュール済のパスが同時に処理できるレコードの数を指定します。デフォルトおよび最大値は200となっています。

 バッチサイズについては分単位、バッチ処理、および制限の強化によるスケジュール済みパスのパワーアップを参照してください。

public class xxxxBactchSchedule imprements Schedulable{
       private final Intefer BATCH_SIZE = 100;
       public xxxxBatchSchedule() {
 
       }
       public void execute(SchedulableContext sc) {
              xxxxBatch bt = new xxxxBatch();
              Database.executeBatch(bt,BATCH_SIZE);
       }
}

 Schedulableクラスのinprementsではexecuteメソッドを実装する必要があります。このexecuteメソッドはglobalまたはpublicで宣言する必要があります。
 executeメソッドの中でインスタンス化されているのは前節で定義したバッチクラスです。

2.Apexスケジューラの設定

 作成したスケジューラを起動するために、Apexスケジューラを設定します。

(1)Apexをスケジュール

 1.ホームタブをクリックし、検索窓からApexを検索します。
2.検索結果のカスタムコードのApexクラスをクリックします。
 3.「Apexをスケジュール」をクリックする

Apexをスケジュールを選択
図1 Apexをスケジュールを選択

(2)スケジュールを設定

スケジュール設定
図2 スケジュール設定

 1.ジョブ名:スケジュールジョブ名を設定
 2.Apexクラス:上記で作成したスケジュールクラス(xxxxBatchSchedule)を指定
 3.頻度、開始日時、終了日時、希望開始時刻を設定する

 注意事項
 1.頻度は、「毎週」または「毎月」しか選択できません。終了日までは指定した頻度でスケジュールが実行されます。上記のスケジュールクラスで設定した時刻とは異なるタイミングでバッチが起動される場合があります。そのため、スケジュールが重複設定されないように、頻度、終了日の設定を行う必要があります。
 2.ジョブキューの状況によっては、指定した日時時刻でのジョブ起動がされない場合があります。

3.スケジュール済のジョブの確認

 バッチクラス(xxxxBatch)で設定したスケジュールは、「設定」→「スケジュール済みジョブ」で確認することができます。

スケジュール済みジョブを確認する方法
図3. スケジュール済みジョブの確認

 アクションに「Manage」と表示されている場合、これをクリックすると起点となったスケジュールの詳細を見ることができます。

スケジュールの詳細表示
図4. スケジュールの詳細表示

 スケジュールを停止する場合には最新のスケジュールの削除アクションをクリックしてスケジュールを削除する必要があります。あわせて、起点となったスケジュールが定期的に実行されるように設定されているためこれも削除する必要があります。

 SFDCのスケジュールに関してはApex スケジューラを参照してください。