UiPath Dictionary型変数を使用したワークフロー開発（１）

20200622
[UiPath Dictionary型変数を使用したワークフロー開発（２）](https://qiita.com/masaru9624/items/455bf8c18768a8494ee6)を投稿しました。
#1. はじめに

最も基本的な、
**１件単位に画面を表示して、その画面に表示されたテキスト情報を取得する**
という動作について、Dictionary型の変数を使用した例を解説したいと思います。

画面上の情報を取得するためには、UiPathでは「テキストを取得」というアクティビティを使用するのが最も一般的だと思います。
このアクティビティにより取得したテキストデータについては変数に格納（出力）する必要がありますが、出力先の変数はString型でもかまいません。
が、今後のワークフローの維持管理のしやすさ、保守性、拡張性、他のワークフローへの流用等を踏まえると、個人的には**Dictionary型**に出力にするのがベストプラクティスと考えています。

「画面上のテキスト情報を取得する」といったワークフローについては、様々な業務で使用することが予想されますので、ワークフローの開発工数を減らしたいですよね。
発想として、
**じゃあ、部品化しよう**
となるわけです。

端的にいうと、今回は、
**部品化ということを考えたときに、Dictionary型を使った方がいいよ**
というお話です。

#2. そもそもDictionary型ってなに？
Dictionary型というものを少し解説してみます。
![スライド1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526899/020abe04-a13c-d0e7-d5ca-dfb1088f3e7e.png)
上図のとおり、ペア（Pair）をたくさん格納できるのが「Dictionary」と思ってください。
じゃあ、たくさんの情報を格納するならDataTable型でもいいんじゃない？と思うかもしれませんが、そうではありません。その点については後述します。

#3. なぜDictionary型がよいのか
##3.1 メリット①　データをまとめて引き渡せる
ワークフロー間でデータを引き渡す際には、「この引数はこの変数へ」といった指定が必要となります。
例えば、3つのデータをワークフロー間で引き渡す際には、3つのString型変数にそれぞれデータを格納していた場合は、3つのString型変数を指定する必要があります。
Dictionary型変数にしておけば、1つのDictionary型変数を指定するだけで構いません。
つまり、ワークフロー間で引き渡すデータの個数が増えれば増えるほどDictionary型を使用する恩恵を受けることとなります。
![スライド2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526899/5fa435ae-c472-a516-ced6-7e3440e3a683.png)

では実際にUiPath Studioでそれぞれのケースで作成したワークフローを見てみましょう。

**＜ケース１＞　String型を使用した場合**
下図のとおり、「ワークフロー Stringにデータを格納」というXamlファイルに、3つの出力引数を作成し、それぞれにデータを代入します。
<img width="960" alt="2020-05-24_23h28_43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526899/54ecb85d-80b2-0d8a-46f7-cbe31d4afc12.png">
Main.xamlより「ワークフロー Stringにデータを格納」を呼び出し、「ワークフロー Stringにデータを格納」より引き渡された出力引数をメッセージボックスに表示してみます。

まず、ワークフローを呼び出し、引数の設定等を行います。
<img width="960" alt="2020-05-24_23h38_05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526899/9dcebb0f-2ec1-02ee-a3da-9f9c3b7ea49b.png">
メッセージボックスに表示する内容を設定し、デバッグ。
<img width="960" alt="2020-05-24_23h44_32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526899/471d3c79-f0a2-5df5-c7c5-875174835f87.png">
メッセージボックスが表示されました。
<img width="960" alt="2020-05-24_23h48_23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526899/51363008-59a9-d015-efe3-71aece58589f.png">

**＜ケース２＞　Dictionary型を使用した場合**
下図のとおり、「ワークフロー Dictionaryにデータを格納」というXamlファイルに、出力引数を作成し、データを代入します。
<img width="960" alt="2020-05-24_23h54_44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526899/ab9287fb-0d4d-bd1b-7639-2f68ab9912b7.png">
**Dictionaryを新たに作成する場合は、代入により「New Dictionary(Of "Keyの型" , "Valueの型")」という記述をする必要があります。**
<img width="960" alt="2020-05-25_00h01_31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526899/f7f1d3cb-595e-8545-f9d1-ee384b3f8891.png">
Main.xamlより「ワークフロー Dictionaryにデータを格納」を呼び出し、「ワークフロー Dictionaryにデータを格納」より引き渡された出力引数をメッセージボックスに表示してみます。

まず、ワークフローを呼び出し、引数の設定等を行います。
<img width="960" alt="2020-05-25_00h24_44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526899/37d8517e-5ec7-ea1d-0470-ae75c4f8a310.png">
メッセージボックスに表示する内容を設定し、デバッグ。
Dictionaryの中から特定のデータを使用したい、取り出したいときは、以下のメソッドを使用します。
　　　**Dictionary型変数名(Key)**　←Keyの部分を指定してあげる
<img width="960" alt="2020-05-25_00h32_08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526899/a4323697-98c5-b3d5-6eac-8aa70f7991dc.png">
メッセージボックスが表示されました。
<img width="960" alt="2020-05-25_01h02_47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526899/9e82c603-dd9c-7e01-3af9-dbd15246e1b7.png">

このように、「呼び出されたワークフローの引数」に設定する数について、ケース１の手法では、ワークフロー間で引き渡すデータの個数に応じて増えますが、ケース２のとおり**Dictionary型を引き渡しておけば、引き渡すのはDictionary型変数1つのみ**となります。

##3.2 メリット②　保守性が高い（ワークフロー改修の手間が減る）
前述で、DataTable型でもいいんじゃないか、ということを言いましたが、「**１件単位に**画面を表示して、その画面に表示されたテキスト情報を取得する」というワークフローを部品化したいときにはDictionary型の方が優れています。

ここでDataTable型について少し解説します。
DataTable型については下図のとおりメリット/デメリットがあります。
![スライド3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526899/d8d7e596-2b05-f79e-dee9-d19977f8587d.png)
Dictionary型と比較して、DataTable型ではワークフロー内に設置するアクティビティ数が増える傾向にあると思います。アクティビティ数が増えるということは、開発工数・テスト工数も増えるということです。

「1件単位」ということを考えたときには、DataTable型のように複数レコードを保持することはありませんので、Dictionary型でいいと思いますし、取得するデータが増えたときにも、代入アクティビティで「Dictionary型変数("新規項目")＝●●●」というふうに記述するだけで、Dictionaryに格納するデータを増やすことができます。
（DataTable型ではデータを格納する位置（列）を決める必要があるが、Dictionary型はKeyを決めるだけで格納する位置という概念は不要）

なお、複数のレコードを扱う必要がある場合はDataTable型変数を使用することがありますが、この場合は1件単位にDictionaryを受け取ってから、Dictionaryの中身（データ）を1件ずつ取り出し、DataTableに対して1件ずつレコードを格納することができます。
**（この方法については、結構簡単にワークフローを開発できますので、別の記事で解説します。）**

例えば、複数件を対象に自動化することがほとんどだと思いますが、**システムエラー等が発生する可能性も見込んで、**
①1件単位にDictionaryに格納
②Dictionaryから1件単位のデータを取り出しDataTableを作成
③作成したDataTableをCSVファイルに出力
～①から③を繰り返す～
④複数件のCSVファイルを集約（マージ）
というワークフローにしておくと、①から③の繰り返し処理のどこかでシステムエラーが発生したとしても、それまでに出力されたCSVファイルは残っていますので、**再処理をするときにも途中の対象から処理が再開できます。**

一方、
**1件単位にテキストを取得して、1レコードごとにDataTableへ格納する処理を繰り返し、最後にCSVファイル出力を行う**
というワークフローであった場合、繰り返し処理のどこかでシステムエラーが発生した場合は、**DataTableの中身はすべて消えてしまい、最初から再処理が必要**となってしまいます。

# 4.最後に
部品化の単位にも触れながら、Dictionary型変数を使用したワークフロー開発のメリットを解説しました。
Array型変数やList型変数を使用した方法などもあると思いますが、個人的には開発初心者でもわかりやすく、かつ、部品化しやすいのはDictionary型変数、かなと思い、記事にしてみました。

また[別の記事](https://qiita.com/masaru9624/items/455bf8c18768a8494ee6)で、
**DictionaryからDataTable化する方法**
について、解説したいと思います。