SVF Cloud for Salesforceで帳票出力

2023-08-15

概要

Salesforceで『SVF Cloud for Salesforce』を使用して複数レコードを複数ページ(ヘッダー・明細)
で出力する際につまづいたあれやこれやをまとめております。

開発する際につまづいたあれやこれや

自由にデータを取得して出力できない!?

私は、今までスクラッチ開発したアプリケーションからSVFを使用しており、今回初めてSVF Cloud for Salesforceを使用しました。
そのため、勝手なイメージで、Apexクラスでデータ取得してListとMapで成形してCSVっぽくして、SVFのコンポーネントに 渡したら帳票が出力できるのかなと最初思っていました。
実態は全然違いました。

SVF Cloud for Salesforceでは「基準オブジェクト」に印刷ボタンを作成しそこから取得できるデータで帳票を出力します。
標準では基準オブジェクト、とその子オブジェクトの内1つを出力できるというものでした。
(複数子オブジェクトがあっても出力できるのは1つ)
https://repo.svfcloud.com/manual/release/ja/restriction/screstriction/ja/893425.html の「オブジェクトの範囲」参照

えっ!?それだけしか出力できないの!?

基準オブジェクトからみた親オブジェクト・親の親オブジェクトが出力できるのはよかったけど・・・

調べたらありました!!
「Virtual Relation」

これを使えば、複数の子オブジェクトも孫オブジェクトも出力できます。

Virtual Relationの設定自体はとても簡単でした。
かなり使える機能なのに設定する場所のボタンはひっそりと配置されています。
SVFボタン設定のSalesforceオブジェクトの横にあるアイコンから作成を行います。

孫オブジェクトを出力するためは、Virtual Relationの設定を2つ行います。
1つ目は基準オブジェクトを[関連先]、その子オブジェクトを[対象オブジェクト]にしたもの。
2つ目は子オブジェクトを[関連先]、孫オブジェクトを[対象オブジェクト]にしたもの。
[結合条件]でオブジェクト間の関連づけをする項目を指定します。

1つ目のVirtual Relationの設定
2つ目のVirtual Relationの設定

Virtual RelationのAPI名は短く

可能な限りVirtual RelationのAPI名は短くすることをお勧めします。
Sandbox環境で出力できた帳票を本番環境にリリースしたらエラーで出力されてないという事象が発生しました。
(事象から考えると何故Sandbox環境で出力できていたかは今だ謎です・・・)
実際に発生したのは以下のような現象です。

プレビュー表示で上図のようなエラー
SVF Cloud エラーログに上記のようなエラー

これはSVF CloudからSOQLが発行されデータを取得する時に、エラー「Bad Message 431 reason: Request Header Fields Too Large」が返されて事象が起こっていました。
取得指示文が長すぎるというものとなります。
取得項目数が多いのでなく指示文が長いということでした。

Virtual RelationのAPI名がオブジェクトの別名となり、SELECT句では「Virtual RelationのAPI名.項目名」で記述されていました。
そのためVirtual RelationのAPI名を短くすることで現象を回避することができました。
Virtual RelationのAPI名は後から変更することはできず、API名の変更=Virtual Relationの再作成となり、印刷ボタンの設定で行うSVFフィールドとSalesforce項目のマッピングのやり直しとなります。

SVFフィールドとSalesforce項目の名前を一致させておけば1つずつマッピングしなおさなくてよい部分はあるのですが、 すべてがそうなっていなかったので、地道にマッピングし再テストを行いました。

後から名前の変更はとても大変ですので、あらかじめ短い名前にしてリスクを避ける方が楽でよいです。

前のページの値が出力される!?

空欄の箇所なのに前のページの値が出力されてる!?
値があるところはきちんとそのレコードの情報なのに、値がない場所は前のページの情報!?
という事象が発生しました。

こんなことあり得るの!?と思いましたがあり得ました。

リストビューから選択した各データについて、データによって値が空になる項目が存在し、その項目を帳票フィールドにマッピングした際、前データの値を引き継いで出力する場合があります。

https://cs.wingarc.com/ja/kb/000021865

Salesforce から出力すると前の明細レコードのデータを引き継いでしまう

https://cs.wingarc.com/ja/kb/000015910

どうやら、明細オブジェクトで取得するデータは、帳票フォーム上の明細レコードのアイテムとして配置されていなければならないというものでした。

今回の仕様は、1ページに子オブジェクトの情報と孫オブジェクトの明細レコードを出力し、子オブジェクトのレコード数分ページを出力するというものです。

この仕様を踏まえて考えると、孫オブジェクトは明細レコードのアイテム項目で大丈夫でしたが、子オブジェクトの項目がダメだったということです・・・。
子オブジェクトの項目も明細レコードのアイテムとして配置すれば正しく出力されますが、出力したい様式の都合上、それはできません。

値が空の場合に前の明細レコードデータを引き継いでしまうならば、値が設定されている状態を作ろう、ということでSalesforce側でどうにかする手段を考えました。

数式項目の作成とレコードトリガーフローの作成を行いました。

数式項目の作成

数式内容は単純で、BLANKVALUE関数で、値がない場合に固定値にするというものです。
固定値は出力しても支障のない値、または使用されていない値を指定します。

データ型数式例
テキストBLANKVALUE( 項目名 , '-')
数値BLANKVALUE( 項目名 , 0)
日付BLANKVALUE( 項目名 , DATE(1900,1,1) )

レコードトリガーフローの作成

基本数式で対応しましたが、ロングテキストエリア等数式項目で使用できないデータ型項目の場合に、
レコードトリガーフローを作成します。
作成するのは高速項目更新のレコードトリガーフローで、項目が空かどうか判定し、空であった場合に、項目に固定値を設定します。

帳票フォームの編集式で値を空に戻す

Salesforceから値がある状態に変換して渡した項目に対して、帳票上で空欄に設定しなおします。
出力して支障のない値が固定値になっていればこの作業は省くことができます。
フィールドの「編集式」でSalesforceで指定した固定値だったら空文字にするという式を設定します。

IF(終了日="1900-01-01","",終了日)

まとめ

  • 出力ボタンを配置するオブジェクトに直接紐づかない孫オブジェクトは「Virtual Relation」を作成することで出力できます。
  • 出力ボタンを配置するオブジェクトの子・孫オブジェクトを明細レコードに配置しない場合は、 Salesforce側では値が空でない状態をつくり、帳票レイアウト側では無理やり設定した値を空の状態に戻す対応が必要となります。