Automation Anywhere で提供されるLOOPコマンドは、基本的にはネストなしの単純なループ、テーブルでいえば列方向は固定であることを想定した「行」方向のループ、が想定されているように見えます。RPAではそもそもそんなに複雑なロジックを組まない、というのが前提なのでしょう。
ただし、コマンド上はLOOPをネストして配置させることも可能なので、どんなふうに多重ループを組めるかについてExcel操作を例に見てみたいと思います。
対象
- Automation Anywhere Enterprise 11.3.2
- Automation Anywhere Community Edition
LOOPコマンドとは
LOOPコマンドは、指定したアクションリストを繰り返し実行する仕組みです。繰り返してアクションリストの先頭に戻ってくる際には$Counter$
システム変数の値が増えており、扱っているデータの現在位置(テーブルの行、配列の引数、等)が1増えます。そして、データの最後になるまで or 指定された回数分だけ or 特定の条件を満たしている間、繰り返し処理が実行されます。$Counter$
システム変数の値は1から開始されます。
これらをドラッグ&ドロップで追加すると、以下のダイアログボックスが開き、オプションを設定します。
ここで「保存」ボタンをクリックすると、以下のような「Start Loop」「End Loop」アクションがセットで追加されます。
また、自動で追加されたコメント行にも記載されている通り、Excelのループの場合は、$Excel Column$
システム変数を使って値を参照します。ループの中のアクションリストで$Excel Column(<列の番号 or 名前>)$
といった形で列を指定します。
多重ループでやりたいこと
さて、LOOPコマンドの基本を押さえたうえで、Excelテーブルを操作する前提で構造がどうなっているかを整理すると、以下の図のように行単位で$Excel Column(n)$
(nは列の番号 or 名前)を使い、ループを回していくのが、通常のLOOP-Each row in a Excel Sheetの処理になります。
プログラミングをやったことがある人なら、たとえばVBAだと
For Counter=1 To MaxRow
MessageBox ExcelColumn(n)
Next
みたいなイメージです。RPAにおいては通常は列方向のデータ量は固定の表を扱うので、あとはnを必要回数だけ指定すれば事足ります。
Excelテーブルのすべてのデータ要素を順に表示するには以下のように書きます。
For Counter=1 To MaxRow
MessageBox ExcelColumn(1)
MessageBox ExcelColumn(2)
MessageBox ExcelColumn(3)
...
MessageBox ExcelColumn(n)
Next
ただし、せっかくなので
For Counter=1 To MaxRow
For CounterColumn=1 to MaxColumn
MessageBox ExcelColumn(CounterColumn)
Next
Next
のように列方向もループをまわすことができれば、通常のプログラミング言語だと記述がよりシンプルになります。これをやろうとしたときにAutomation Anywhere だとどうなるでしょうか。
Excelテーブルで多重ループを組んでみた
以下のデータを前提に、多重ループを組む方法を考えました。
名前 | 生年月日 |
---|---|
山田太郎 | 1971/3/4 |
石川たか子 | 1986/12/4 |
鈴木一郎 | 1976/3/31 |
佐藤栄作 | 1980/12/31 |
西川正二 | 1966/2/15 |
方法1: 列の最大数がわかっているとして組む場合
今回は、列の最大数は2です。これを踏まえると、MaxColumn=2として、外側はLOOP-Each row in a Excel Sheet、内側はLOOP-Timesで多重ループを組めばOKです。
これを実行すると、「山田太郎」「1971/3/4」「石川たか子」「1986/12/4」「鈴木一郎」「1976/3/31」...と、表の中のヘッダーを除くデータ部分が、1行目から横方向に順番に1セルずつメッセージボックスで表示されていきます。
注意: 多重ループの場合のCounter変数の取り扱い
ここで注意しないといけないのは$Counter$
システム変数がどの場所でどのループの値を持っているかです。ループが2重になっていても、$Counter$
変数はひとつしかありません。$Counter$
変数は、常に一番内側のループの値が入力されています。内側のループを抜けると、その外側のループの値が入力されます。これはデバッグ機能で$Counter$
変数の値をウォッチしながらステップオーバーしていくとわかります。
方法2: 列の最大数を自動で取得する場合
当初、いろいろと調べてみたのですが、どうやら$Excel Column(n)$
のnに指定できる最大値を取得できる簡単な方法がないのです。配列だと利用できる$ArrayColumns($<Array 型変数名>$)$
は$Excel Column(n)$
には適用できません。かといって、$Excel Column$
システム変数はList変数でもないため、LOOPコマンドで提供されているListオプションも使えません。
また、「Excel でデータの入っている一番最後の列/行の情報を取得するには」の方法で列の最後の場所を出すことはできますが、$Excel Cell Column$
の返す値はアルファベットの値 (3なら"C")となるため、これから列の最大数を簡単に出せません。(Excelの列の番号から数字に変換してくれる関数があれば別ですが!ちなみに、この関数はBot Storeで無料配布されている「Perform Various Spreadsheet Operations-Microsoft」にありました!記事「RPAでExcelを操作する際のヒント (Automation Anywhere拡張編) - R1C1形式とA1形式の列番号を変換するには」で使い方を参照してください。)
よって、一番合理的な方法は、「Excel データを配列変数に読み込むには」の方法に従って、いったんExcelテーブルをArray変数に読み込み、多重ループをまわすことです。
Array変数は変数マネージャーでの初期化のところで、Excelファイルからデータを読み込んでおく (Read from excel/csv file) というオプションがあります。ここで「すべてのセル (All Cells)」を指定して読み込みます。
すると、変数マネージャーでArray変数 $arrayTable$
が定義されました。
これを使ってアクションリストを組むと以下のようになります。内側/外側ともにLOOP-Timesで多重ループを組みます。先に説明したように $Counter$
変数はひとつしかないので、外側のループの値を $Row$
変数に代入して内側のループに持ち込みます。
今回は、Array変数に読み込んだデータにはヘッダーかどうかの区別がないため、メッセージボックスに表示される実行結果は「名前」「生年月日」「山田太郎」「1971/3/4」「石川たか子」「1986/12/4」「鈴木一郎」「1976/3/31」...と、ヘッダーも含めて列挙されてしまいます。ここは必要に応じて後で工夫すればよいです。
まとめ
いかがでしたでしょうか。Automation Anywhere ではループを多重に組むことも可能です。ループ内での現在位置を表す$Counter$
システム変数は一つしかないので、外側のループでの値を適宜他の変数に代入して内側に持ち込んでください。
最後までお読みいただきありがとうございました。