LoginSignup
5
2

More than 1 year has passed since last update.

@InvocableMethod をフローで呼び出す場合

Posted at

フローで乱数を扱いたい!!(唐突)
という状況があるとします。(実際にあるかあ別として)

Summer'21現在、フローではRAND()に相当する関数がありませんので、これを実現するためにはApexを呼び出す必要性があります。
この際にInvocableアノテーションを使用して、Apexを記述していくことになるのですが…

見事、落とし穴にはまってしまいました。

間違ったコード

最初の画面で入力した数を引数として、その数の分だけ乱数を生成して、そのリストを返す…
こういうコードを記述したくて、最初に書き上げたのがこちら↓

global class CreateRandomNumber {
    @InvocableMethod
    global static List<Integer> getRandomNumber(List<Integer> sizeInput){
        List<Integer> randomNumbers = new List<Integer>();
        for(Integer size : sizeInput){
            for(Integer counter = 1; counter <= size; counter++){
            Integer rand = Math.round(Math.random() * 1000);
            randomNumbers.add(rand);    
          }
        }
        return randomNumbers;
    }
}

一応テストもして、コードカバレッジも100%にしました。
そして、画面フロー組んで早速デバッグしたら…

エラーが発生しました。
Apexをコールした直後の話です。

(|)おやおやおやおやおやおやおや

何がいけなかったのか

少しHelpの方から記述を引用します。

戻り値の型が Null 以外の場合は、メソッドによって返されるデータ型が次のいずれかである必要があります。

  • プリミティブデータ型のリスト、またはプリミティブデータ型のリストのリスト – 汎用 Object 型はサポートされていません。
  • sObject 型のリスト、または sObject 型のリストのリスト。
  • 汎用 sObject 型のリスト (List)、または汎用 sObject 型のリストのリスト (List>)。
  • 前述のサポートされている型の変数、またはユーザ定義の Apex 型を含み、InvocableVariable アノテーションが付加されているユーザ定義型のリスト。各自のデータ型を実装するカスタムのグローバルまたは公開 Apex クラスを作成し、そのクラスに呼び出し可能な変数アノテーションが付加されているメンバー変数が少なくとも 1 つ含まれていることを確認します。

先ほどのコードはこれを守っています。はてさて、何がいけなかったのか…

結論から言うと、メソッドの戻り型が間違っていたです。

引数の部分はList<Integer>型となっていますが、実際にフロー側では数値のコレクション変数を引数に渡すことができません数値の単一変数のみ渡せました。

戻り値についても同じことが言えます。
先ほどのコードのように戻り型をList<Integer>としていると、実際にフロー側に返されるのは数値の単一変数です。リストが1段階はがされているのですね。

ですがApexコード上では、戻り値の例としては、
[53, 169, 39, 765, 346](引数として5が渡された場合)
ここからリストが1段階はがされるので、5つの数値がコレクションではない形でフロー側に渡されるわけです。
…そりゃ、エラーになるわな。

エラーの出ないコード

以上を受けて直したコードはこちらです。

global class CreateRandomNumber {
    @InvocableMethod
    global static List<List<Integer>> getRandomNumber(List<Integer> sizeInput){
        List<Integer> randomNumbers = new List<Integer>();
        List<List<Integer>> output = new List<List<Integer>>();
        for(Integer size : sizeInput){
            for(Integer counter = 1; counter <= size; counter++){
            Integer rand = Math.round(Math.random() * 1000);
            randomNumbers.add(rand);    
            }
        }
        output.add(randomNumbers);
        return output;
    }
}

最適なコードかと言われればそうではないのですが、思い通りに動いたのでヨシ!です。
これで望むだけの個数の乱数をフローで扱えるようになりました。
(|)素晴らしい…素晴らしい…!

5
2
0

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
5
2