UiPathサンプル - Excelデータからキーワードを含む行を削除するサンプル


公式サイトのKnowledge Baseサンプルを詳しく解説します。
今回は**"Remove Excel Rows That Contain Keywords"**です。
https://www.uipath.com/kb-articles/excel-automation.remove-rows-that-contain-keywords

#シナリオ
Excelシートを読み込み、あらかじめ定義したキーワードが含まれる行を削除します。Excelシート"Cars"には車名、走行距離、価格、セーラータイプ(SellerType)が含まれています。この中から、"SellerType"が"Private Seller"または"Other"のものを削除して、"Cars2"シートに貼り付けます。
<img src="https://qiita-image-store.s3.amazonaws.com/0/202992/8753b99b-4ad9-6e46-3341-73e698e37e32.png" width=100%>



#このサンプルで使用する機能
- UiPath アクティビティ
    - Read range - Excelファイルを読み込みます
    - Write range - Excelファイルを書き込みます
    - Remove data row - DataTableから指定されたRowを削除します  
<br>
- Windows Workflow
    - For Each コントロール
    - Assign コントロール
    - While コントロール  
<br>
- .Net 関連
    - System.data.DataTable - Excelデータを格納するデータモデルです
    - System.linq - LINQ(統合言語クエリ)のデータの要素数をカウントする機能を使います

#準備
1. サンプルZIPファイルをダウンロードします。  
https://drive.google.com/open?id=0BxVAKI3l9Pc5ODM5WHFRdlNsVmM  
<br>
zipファイルには以下のファイルが含まれています。これらのファイルを任意の場所に展開します。  
<img src="https://qiita-image-store.s3.amazonaws.com/0/202992/47be26fe-9ae6-e703-6a22-7a6e89b2ca47.png">

    - "Cars.xlsx" - 処理対象のExcelファイル
    - "Main.xaml" - ワークフローのXAML実装
    - "project.json" - UiPathプロジェクトファイル
    - "test.csv" - 使用しません  
<br>
2. UiPathを起動します。Main.xamlを選択し、UiPathで開きます。
<img src="https://qiita-image-store.s3.amazonaws.com/0/202992/498d3702-94c5-8071-03a0-bc10f8aeb002.png" width=70%>  
<br>
3. Flowchartが表示されます。
<img src="https://qiita-image-store.s3.amazonaws.com/0/202992/916b6805-b21e-34f5-b68a-050fb684d6c0.png" width=70%>  
<br>
4. 変数も定義されています。
<img src="https://qiita-image-store.s3.amazonaws.com/0/202992/10d090e6-bf20-15eb-185f-509bd3427047.png" width=70%>


#実行と結果
1. Runボタン（またはF5キー)で実行します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/202992/a0d784e7-e12a-b4b7-bde3-b320ed61d21b.png">

2. Cars.xlsxの"Cars2"シートにSellerTypeが"Dealer"のもののみ出力されました。
<img src="https://qiita-image-store.s3.amazonaws.com/0/202992/b1457a2b-a4b6-35b7-05da-689330f30530.png" width=80%>

#ワークフロー作成ビデオ
1から自分でworkflowを作るとこのようになります。
[![Video](http://img.youtube.com/vi/LIjDjiEXouM/0.jpg)](http://www.youtube.com/watch?v=LIjDjiEXouM)


#解説
1. "Read Excel file"アクティビティ
    - Read range アクティビティ
    "Read Excel file"はDisplayNameで、元々の名前は"Read range"アクティビティです。
<img src="https://qiita-image-store.s3.amazonaws.com/0/202992/a51ec44b-d435-5d7e-37e9-176ebda901a7.png">  

        ダブルクリックすると以下のようになっています。
<img src="https://qiita-image-store.s3.amazonaws.com/0/202992/db59241f-9455-0d95-f238-67c7c366fe08.png">

        ①処理対象のファイルCars.xlsxが選択されています。
        ②読み取るシート名は"Cars"です。
        ③*Range*は何も指定しません。何も指定しないとシート全領域を読み込みます。  

        画面右側のPropertiesは以下のようになっています。
<img src="https://qiita-image-store.s3.amazonaws.com/0/202992/b6a41649-d380-f096-5315-d40cc85ee2f0.png">

        - "Private" - チェックを入れるとLogデータを出力しません。
        - "AddHeaders" - Excelシートの1行目がヘッダー行の場合はチェックを入れます。
        - "DataTable"- Excelデータの出力先のDataTable変数（ここではdtInput）を指定します。dtInputは変数として定義しています。
        <img src="https://qiita-image-store.s3.amazonaws.com/0/202992/59c60151-2eaf-8899-bf0e-16f7a9792512.png">  
<br>

2. "For each word from List"アクティビティ
    - "For Each"アクティビティ
    "For Each word from List"はDisplayNameで、元々は"For Each"アクティビティです。
    <img src="https://qiita-image-store.s3.amazonaws.com/0/202992/56d2bb6e-c61e-011a-0405-a6db2054984c.png">  

        ダブルクリックすると以下のようになっています。
        <img src="https://qiita-image-store.s3.amazonaws.com/0/202992/34837e72-bfa0-f312-2028-7baec0b1bb9f.png" width=70%>

        ①配列"List"に対してFor Eachでループさせます。
        "List"変数には文字型配列として"Private Seller"と"Other"をVisual Basic（VB）表記で定義します。
        <img src="https://qiita-image-store.s3.amazonaws.com/0/202992/9f514569-133b-1bb7-9aa1-db0220d8b457.png">

        >参考までにVBのコードで実際に記述すると以下のようになります。
        <img src="https://qiita-image-store.s3.amazonaws.com/0/202992/2a5c3eeb-0e8a-d61d-1919-7ea7ac80bcc9.png">

        "word"は任意の変数名を指定します。変数といっても"Variables"として定義する必要ははありません。これは、変数のスコープは自動的にFor Each内にとどまり、また、変数の型もList変数の型（ここではString型）に依存するためです。

        ②AssignでString変数"query"にVB表記
        ```String.Format("SellerType='{0}'", word)```
        の実行結果を代入します。

        String.Formatは、'{引数の番号}'部分に引数で渡された文字列を組み込む関数です。最初のFor Eachループの実行ではqueryには
        ```SellerType='Private Seller'```
        という文字列が代入されます。

        >参考までに引数が２つある場合は以下のようになります。
        ```String.Format("SellerType='{0}' or SellerType='{1}'", "Private Seller", "Other")```
        この戻り値は、
        ```SellerType='Private Seller' or SellerType='Other'```
となります。

        ③AssignでDataRow変数"RowsToDelete"にVB表記
        ```dtInput.Select(query)```
        の実行結果を代入します。

        Selectは.NetのSystem.data.DataTableのメソッドで、引数で与えられた条件に合致するデータをDataRow型配列で返します。この例ではExcelの"Cars"シートに"Private Seller"が3行、"Other"が2行あるので最初のFor Eachループで3個の要素をもったDataRow配列が、2回目のループで２個の要素をもったDataRow配列がRowsToDelete変数に格納されます。

        ④Assignでint変数"i"にVB表記
        ```RowsToDelete.Count-1```
        の実行結果を代入します。

        1回目のFor Eachループでは3-1で**2**が、2回目のループでは2-1で**1**が初期値として変数iに入ります。

        この結果、次の⑤Whileループにおいて１回目のFor Eachループではi=2, 1, 0の3回、2回目のFor Each ループではi=1, 0の2回"Remove data row"アクティビティが実行されます。

        なお、CountはLINQ(統合クエリ演算子)の演算子です。配列の長さを表す通常のLength演算子を使って
        ```RowsToDelete.Length-1```
        としても同じ結果が得られます。

        ⑤Whileループで変数iがゼロになるまで"Remove data row"アクティビティが実行されます。
        <img src="https://qiita-image-store.s3.amazonaws.com/0/202992/20a8188a-feb1-59f9-1b61-91779afc0c85.png">

        ⑥ "Remove data row"アクティビティを実行します。
        <img src="https://qiita-image-store.s3.amazonaws.com/0/202992/1b9a78cf-9a3f-7ffe-c1a4-1103e4d257bd.png">

        プロパティは以下のようになっています。
        <img src="https://qiita-image-store.s3.amazonaws.com/0/202992/de60aedd-48b7-dc11-9f1d-22f5bdc92d24.png">

        "DataTable" - データ削除対象のDataTableであるdtInputを指定します。
        "Row" - 削除対象のDataRowを指定します。

        1回目のFor EachループではRowsToDelete配列は3つの要素をもっており、いずれもSellerTypeは"Private Seller"です。RowsToDelete(0)、RowsToDelete(1)、RowsToDelete(2)が順に"Row"として渡されます。2回目の2つの配列要素のSellerTypeは"Other"です。

        ⑦ Assignで変数iを1デクリメントします。  
<br>

3. "Write Excel file"アクティビティ
    - "Write range"アクティビティ
    "Write Excel file"はDisplayNameで、元々は"Write range"アクティビティです。  
    <img src="https://qiita-image-store.s3.amazonaws.com/0/202992/fde232bc-71bc-d51f-fc07-a084d5f4f933.png">

    ダブルクリックすると以下のようになっています。
    <img src="https://qiita-image-store.s3.amazonaws.com/0/202992/1401e436-beb1-7cb3-e307-257019d415eb.png">

    プロパティは以下のようになります。
    <img src="https://qiita-image-store.s3.amazonaws.com/0/202992/0c52027f-ed06-2a7f-0833-573997d91bd1.png">  
    ①"WorkbookPath" - ファイル選択ダイアログで出力Excelファイルへのパスを指定します。
    ②"SheetName" - データを出力するExcelシートとして"Cars2"を指定します。
    ③"StartingCell" - データを出力するシート上の起点となるセルを指定します。
    ④"DataTable" - 出力データが入ったDataTable変数を指定します。