UiPathでよく使う.NETコード集 ※随時更新

UiPathでオートメーションを開発できるようになるには、
1. [Community Edition](https://www.uipath.com/ja/community)をインストールして
2. [UiPath Academy](https://www.uipath.com/ja/rpa-academy)（※1章あたり目安1時間、全15章）でWebトレーニングを受講して
各種アクティビティの使い方を理解すれば十分でしょう。全て無料です。

が、実際に開発する中では.NETのクラスメソッドを利用してコーディングしたほうが
便利なケースが多々あるので、自分の備忘録も兼ねてよく使うコードを少しずつ書き出してみます。

#日付関係
|やりたい事|コード例|備考|
|:--|:--|:--|
|今日の日付を文字列で取得|DateTime.Now.Date.toString("yyyy/MM/dd") <br>→ 2018/05/01|[.NETの日時書式の文法](https://docs.microsoft.com/ja-jp/dotnet/standard/base-types/custom-date-and-time-format-strings)|
|日付の加算（減算）|10日前：DateTime変数.AddDays(-10)|月：AddMonths(n)<br>年：AddYears(n)|

#DataTable関係
####DataTableの行(DataRow)を別のDataTableに追加する→DataTable.ImportRow()
Add data rowアクティビティで追加しようとすると
実行時に[This row already belongs to another table]エラーになる。（ありがち）
Add data rowで追加できるのは、DataTableに属さない野良DataRowだけなのです。
![datarow.png](https://qiita-image-store.s3.amazonaws.com/0/255097/e871c5a1-23c1-d0b5-2afc-43dabf40f7f7.png)

この場合、DataTable変数.ImportRow()をInvoke methodアクティビティで実行する
（Parameterで追加するDataRow変数を指定）のが正解。
![invoke.png](https://qiita-image-store.s3.amazonaws.com/0/255097/66e826ec-bba1-bcb8-89c4-25fc00633996.png) ![param.png](https://qiita-image-store.s3.amazonaws.com/0/255097/b0e32c43-0e6a-f5b9-98bd-2f9c3a64080f.png)
※dtToが追加する先のDataTable、rowが追加したいDataRow

####DataTableのソート→DataTable.Select()
DataTableのSort用Activityは（2018/05時点で）無いので、
DataTable変数.Select(Nothing, ソート条件式)をAssignで使う。
![sort.png](https://qiita-image-store.s3.amazonaws.com/0/255097/67f87685-edf6-2f80-5dcd-86e855b0d207.png)
[ソート／フィルタ式の書式解説](https://msdn.microsoft.com/ja-jp/library/system.data.datacolumn.expression(v=vs.110).aspx)

返り値はDataTableじゃなくて、ソート済のDataRow[]なので、
後はFor eachアクティビティ（For each rowではない）で１件ずつ処理する。
※For eachはどの型の配列なのかを指定(TypeArgument)する必要があるので注意。
![sortedrow.png](https://qiita-image-store.s3.amazonaws.com/0/255097/3bf08705-4617-c98b-0cac-ef8ed693ef6c.png)

####DataTableをフィルタ→DataTable.Select()
ソート同様、DataTableを条件でフィルタするにはDataTable変数.Select(フィルタ条件式)を
Assignで 実行し、フィルタ済のDataRow[]を取得する。
[ソート／フィルタ式の書式解説](https://msdn.microsoft.com/ja-jp/library/system.data.datacolumn.expression(v=vs.110).aspx)
フィルタ式の例＞
- Col1 Like 'RPA%' Or Col2 = 'Automation'
- Col1 > 200 And Col2 In ('AA', 'BB', 'CC') And Col3 is NULL

2018/07/01. クレスコのエンジニアの方がフィルタ速度について有効な情報を載せて下さってます。
[DataTable 操作のパフォーマンスが上がった話](https://www.cresco.co.jp/blog/entry/6016/)

####その他
|やりたい事|コード例|備考|
|:--|:--|:--|
|DataTableの1行目1カラム目の値を取る|DataTable変数.Rows(0).Item(0).ToString()|Item("名前")のようにカラム名でも指定可|
|For each row内で今の行番号を取る(2018.2以前)|DataTable変数.Rows.IndexOf(row)|素直にカウンタ変数使った方が可読性高いかも|
|For each row内で今の行番号を取る(2018.3以降)|Indexパラメータ（↓の絵参照）|2018/11/16追加|
|DataTableの構造をコピーして新規のDataTableを作成|AssignでdtCopy = dtOriginal.Clone()|値までコピーする場合はCopy()|

For eachの新パラメータ"Index"を使った行カウントのとり方
![image.png](https://qiita-image-store.s3.amazonaws.com/0/255097/a3fd91e3-8039-22da-9bd3-810226b25b7a.png)

#ファイル・フォルダ関係
|やりたい事|コード例|備考|
|:--|:--|:--|
|指定したフォルダ中のサブフォルダ一覧を取得|Directory.GetDirectories(folderPath)|各サブフォルダパスの配列（String[]）が返る|
|指定したフォルダ中のファイル一覧を取得|Directory.GetFiles(folderPath)|各ファイルのファイルパスの配列（String[]）が返る|
|ファイル絶対パスからファイル名のみ取り出す|Path.GetFileName(filepath)|filepathはWebのURLでも可|

#文字列関係
MSDNの[Stringメソッド](https://msdn.microsoft.com/ja-jp/library/system.string_methods(v=vs.110).aspx)から、やりたい事に合うメソッドを探す。
ここではよく使うものを抜粋。

|やりたい事|コード例|備考|
|:--|:--|:--|
|半角スペース区切りで文字列を分割|str1.Split(" "}, StringSplitOptions.None)|区切り文字は {"は", "を", "が"} のように複数指定可|
|分割した文字列の３番目を取得|str1.Split(" "}, StringSplitOptions.None)(2)|インデックスは0から始まるので、3番目の指定は2|
|指定した文字列で始まるかどうか|str1.StartsWith("最初は")|返り値はboolなのでIFアクティビティでよく使う|
|Format文字列の指定|String.Format("いちいち{0}を{1}しなくていいよ。", str1, str2) |str1 = "食ったものの写真"<br>str2 = "twitterにアップ"|
|文字列の置換|str1.Replace("置換前", "置換後")||
|Type intoの文中に改行を入れる|Environment.NewLine|"\r\n"ではない|

#型変換（キャスト）関係
|やりたい事|コード例|備考|
|:--|:--|:--|
|Intへの変換|Cint(変数)|変数.ToInt()はありそうで無い|

#条件判断（IF-Condition）関係
![condition.png](https://qiita-image-store.s3.amazonaws.com/0/255097/828296d2-4df9-77a9-b99d-2279bd1b1986.png)

|判断したい事|コード例|備考|
|:--|:--|:--|
|○と×が同じ|input = 10|== じゃない|
|○と×が違う|input <> 10|!= じゃない|
|アレアレ、かつコレコレ|input1 <= 10 AndAlso input2 <= 10|&, &&じゃない<br>あとAndよりAndAlsoの方がベター|
|アレアレ、もしくはコレコレ|input1 <= 10 OrElse input2 <= 10|![Or.png](https://qiita-image-store.s3.amazonaws.com/0/255097/a19a3613-ac17-dce5-9c6e-85eb66271ae8.png)じゃない<br>あとOrよりOrElseの方がベター|
|文字列に特定のキーワードが含まれている|strInput like "\*エラー\*"|[Like演算子](https://docs.microsoft.com/ja-jp/dotnet/visual-basic/language-reference/operators/like-operator)|

### ※ And/Else と AndAlso/OrElseの違い
[ypmy](https://qiita.com/ypmy)さんからのアドバイスで知ったのですが、
UiPath的に[かつ/もしくは]を表現するのは[And/Else]よりも[AndAlso/OrElse]の方が望ましいです。
（C#でいう && や || に厳密に相当するのがAndAlso/OrElse。）

理由はちゃんとあって、例えば
　①アレアレ And コレコレ
　②アレアレ AndAlso コレコレ
とあった時、UiPathは
　①の場合はアレアレもコレコレも両方確かめようとします。
　②の場合はまずアレアレだけ確認して、NGだったらすぐElseに行き、コレコレは確認しません。
なので②は動作が速いです。

あと地味にInput Dialogで役立ちます。
例えば入力された文字列（"UIPATH"と入力される事を期待）をチェックするケースで
![input.png](https://qiita-image-store.s3.amazonaws.com/0/255097/6fc33a22-6405-a28d-8db8-995697f9f387.png)

Condition欄に `strInput.ToString() = "UIPATH"` と書くだけだと、
何も入力せずOKボタン押した場合に NullReferenceExceptionエラーが出ます。
![null.png](https://qiita-image-store.s3.amazonaws.com/0/255097/63f99268-e8fa-92a5-5c8b-0a1c056f5df7.png)

Input Dialogに何も入力が無かった場合、
その結果を受けるstrInput（GenericValue変数）は実体を持たないNull(nothing)になりますが、
実体の無いNullにToString()を実行させようとするのでエラーになるのです。

そんな時は↓のようにIsNot nothing（アレアレ）をAndAlsoで付けてやれば、
`strInput IsNot nothing AndAlso strInput.ToString() = "UIPATH"`
アレアレの時点でNGだとわかると、そこでUiPathは諦めてくれるのでエラーを回避できます。

これがAndだと、アレアレもコレコレも両方確認してしまうので、結局エラーになってしまいます。
AndAlsoって便利～。

ちなみにこうした振る舞いをする演算子は"ショートサーキット"と呼ぶそうです。これ豆な。

---
2018/05/07 今更ですが、内容がakira-fさんの
[UiPathでの自動化ロボット作成時によく使った、 VB.Net まとめ](https://qiita.com/akira-f/items/e136dfd0700b1503e487)
と結構ダブってる事に気付きました。

2018/07/01 条件判断の項を追記しました。

2018/08/05 [ypmy](https://qiita.com/ypmy)さんのアドバイスを受け、条件判断の項(And/Or)を修正しました。