【UiPath】市民開発ロボをリファクタリングした時に気が付いた改善ポイント

# はじめに
市民開発とは、IT開発側に依存することなく、業務側がローコード・ノーコードツールを用いてシステム開発を行うことを指します。
就業先では、UiPath StudioとStudioXを利用して業務担当者自身でロボ開発を行っております。
作成したロボに関して、開発担当者自身でロボ管理を行えるのがベストですが、様々な状況によりロボ管理ができなくなるケースもあります。
市民開発で作成したロボを引き継ぎリファクタリング対応した時に思った改善点を残します。

# この記事の対象者
- UiPath初学者
- UiPath Studioを利用した市民開発者

# 前提条件
- 実業務で安定してロボの処理が行われている
- 管理する部署によって開発ルールに差異がある

# 内容について
今回は市民開発側から開発側にロボ管理変更の依頼がありました。
管理変更に伴いロボの中身をチェックして、開発ルールに沿っていない部分の改修および可読性向上を目的としてリファクタリングを実施しました。
その中で、改善したら可読性向上するであろう点を筆者主観でまとめました。

## サンプルデータ(連絡先取得台帳.xlsx)　処理前
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524399/9add053b-3837-7546-ea23-1ce76fa5c082.png)

## サンプルデータ(連絡先取得台帳.xlsx)　処理後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524399/cd2b8754-140a-52ad-641d-4691a1397194.png)


:::note warn
テストデータに関して、[個人情報テストデータジェネレーター](https://testdata.userlocal.jp/)を利用して作成しています。
:::

## サンプルロボ
市民開発ロボを複数案件分リファクタリング対応をしました。
どのような点を改善すると更によくなるかサンプルロボを用意しました。
- 改善前：市民開発
- 改善後：リファクタリング

:::note warn
サンプルに関して、筆者がロボ確認して共通に感じた部分を再現しました。
他の市民開発者が全て該当するものではございません。
:::

## BeforeSample(改善前)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524399/f75139e2-f2a4-68a2-b1c2-2fca5accd8fa.png)

## AfterSample(改善後)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524399/1aea41af-1d91-53d7-9995-8416e22a761a.png)



# 改善点
## シーケンスで処理をまとめる
市民開発で作られたロボの構成を見たところ、全体的に「フローチャート」が使われており、フローチャート内にアクティビティが無数に配置されていました。
ロボの中身を確認するとき、アクティビティ1個1個見るより、処理としてまとめられる点があったら「シーケンス」を利用してまとめると処理の細分化が行われ、可読性が向上されます。
考え方として、部屋に無数のものをバラバラに配置するより、種類毎に整理して配置するほうが見やすいです。
もしアクティビティを無数に配置していて、修正に迷ったときは一度落ち着いてシーケンスに共通する処理をまとめてみましょう！


## Dictionary型の変数を利用する
市民開発で使用されている変数情報の中で、Dictionary型の変数を見る頻度が少なかったです。
Dictionary型の変数を使わなくてもロボ開発は行えますが、不具合による修正または、機能追加による改修が発生する場合、各xaml内の変数を確認します。
その場合、変数が多過ぎると解析するのに時間がかかるため、まとめられるものをDictionary型の変数でまとめましょう！
考え方として、Excelから取得したデータ、設定値関連はデータとしてまとめやすいです。
もし1xaml内に変数情報が多いと感じた場合、まとめられるものを見つけてみましょう！

### BeforeSample 変数情報
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524399/d23cb1f8-7c6b-299a-beee-d6306913af0a.png)
### AfterSample 変数情報
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524399/778d2985-c43c-aed3-f3d4-61ad3c4ab9d2.png)

「BeforeSample 変数情報」と「AfterSample 変数情報」情報を見比べてみると、「AfterSample 変数情報」の圧倒的に変数が少なくスッキリしました。
本ロボでは以下のようにDictionary型の変数を作成しています。


### 「代入」アクティビティを利用したDictionaryセット (初期設定)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524399/f35932d7-eaeb-e1de-5166-85cebce58898.png)

### 「代入」アクティビティを利用したDictionaryの設定値 (初期設定)
| 左辺の変数 | 値を設定 |
|:--|:--|
| initialSetting | New Dictionary(Of String,String) |
| initialSetting("シート名") | "Sheet1" |
| initialSetting("処理ファイルパス") | "C:\RPA\UiPath\リファクタリング案件データ\基幹システム登録台帳.xlsx" |
| initialSetting("ヘッダー行") | "1" |


### 「コードを呼び出し」アクティビティを利用したDictionaryセット (コードを呼び出し：処理データセット)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524399/05774e9e-c724-d39b-d895-8ea7a5ee4ae5.png)

  ### 「コードを呼び出し」アクティビティを利用したDictionaryの設定値 (コードを呼び出し：処理データセット)
~~~vb:コードを呼び出し：処理データセット　
'====================
'処理概要：インプットファイル情報をセット

'IN：
  'InRow：対象行データ
  'InRowsCount：対象行番号
'OUT：
  'OutDicInputItem：入力ファイル_処理データ
    'KEY：名前
    'KEY：性別
    'KEY：生年月日
    'KEY：年齢
    'KEY：都道府県
    'KEY：Email
    'KEY：処理結果
    'KEY：エラー内容
  'OutDicWriteCell：入力ファイル_セル情報
    'KEY：処理結果
    'KEY：エラー内容
  'OutDicWriteResult：入力ファイル_書き込み内容
    'KEY：処理結果
    'KEY：エラー内容
'IO：なし
'====================

OutDicInputItem = New Dictionary(Of String,String)
OutDicWriteCell = New Dictionary(Of String,String)
OutDicWriteResult = New Dictionary(Of String,String)

'dicInputItem
OutDicInputItem("名前") = InRow("名前").ToString
OutDicInputItem("性別") = InRow("性別").ToString
OutDicInputItem("生年月日") = InRow("生年月日").ToString
OutDicInputItem("年齢") = InRow("年齢").ToString
OutDicInputItem("都道府県") = InRow("都道府県").ToString
OutDicInputItem("Email") = InRow("Email").ToString
OutDicInputItem("処理結果") = InRow("処理結果").ToString
OutDicInputItem("エラー内容") = InRow("エラー内容").ToString

'dicWriteCell
OutDicWriteCell("処理結果") = "H" & InRowsCount.ToString
OutDicWriteCell("エラー内容") = "I" & InRowsCount.ToString

'dicWriteResult
OutDicWriteResult("処理結果") = ""
OutDicWriteResult("エラー内容") = ""
~~~

### コードを呼び出し：処理データセット　 「呼び出されたコード引数」
| Name | Direction | Type | Value |
|:--|:--|:--|:--|
| InRow | 入力 | DataRow | row |
| InRowsCount | 入力 | Int32 | rowsCount |
| OutDicInputItem | 出力 | Dictionary<String,String> | dicInputItem |
| OutDicWriteCell | 出力 | Dictionary<String,String>  | dicWriteCell |
| OutDicWriteResult | 出力 | Dictionary<String,String>  | dicWriteResult |

個人的に初心者は「代入」を用いてDictionary型の変数を作成、ある程度ロボを作ったことがある方は、「コードを呼び出し」で変数を作成してみるとよいです！

:::note warn
「コードを呼び出し」はVBを用いて大量にデータセット可能ですが、エラーが発生した場合はVBを読み解く必要があります。
「コードを呼び出し」は非常に便利ではありますが、知識も要求されるため扱う際は注意が必要です。
:::

## 共通部品を作成する
処理内容が似ているものは共通部品化することをオススメします。
BeforeSample(改善前)、AfterSample(改善後)では「セルに書き込み」アクティビティが多く使用されていたため、共通部品を作成しました。
共通部品の中身は[【UiPath】Excelデータ書き込み　複数行](https://qiita.com/OKiNA_RPA/items/bdbef091b0f6e48f94bd)を利用して作成しました。
共通部品作成のメリットして、不具合が発生した場合、共通部品を修正することにより一括で不具合改修が可能になります。アクティビティが個々に配置されている場合、1個1個修正しなければならなくなるので大変です。
ロボを作っているときに同じような処理を見つけたら、共通部品作成できるようにするとよいと思います！


## Configを有効利用する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524399/c6b5cfbe-3467-7977-1227-7180ab3acb76.png)
ロボ開発ではConfigファイルを利用するケースが非常に多いです。本投稿では画像情報としてハードコーディングされていますが、変動する可能性があるデータはConfigにまとめるのが良いです。
ロボ内部でハードコーディングされている場合、ロボの中身を修正しなければならないのですが、Configからデータ取得している場合、Config内のデータ修正するだけで可変データの修正が可能です。
注意点として、Config内には説明(Description)は必ず記載しましょう。
ロボを作成した時は仕様を覚えていますが、ある程度の日数が経過した場合、設定情報が分からなくなります。
ロボ改修は必ずしも作成担当者が行うとは限らないため、自分自身または改修する他者のためにも情報は残しましょう！

# おわりに
今回は市民開発で作られたロボ引継ぎを行ったときに気が付いた内容をまとめました。
前提として、通常業務の合間に勉強しながら開発を行って作られているため、すごく頑張っていると思いました！
本投稿は必ずしも市民開発者の開発として正解に繋がるとは限りませんが、参考の1つとして取り入れてもらえたら嬉しいです！






# 参考サイト
[個人情報テストデータジェネレーター](https://testdata.userlocal.jp/)