【UiPath】データテーブルの操作（1）基礎知識編

# はじめに

この投稿は、RPAツール「UiPath」の データテーブル について「個人的に」まとめたものです。
量が多いので、数回に分けて書きます。

# データテーブルの操作 シリーズ

DataTableの操作方法について記載した記事が、他にもあります。参考まで。

https://qiita.com/miya_gis/items/edc3557f3dc7cf6b3cfd

https://qiita.com/miya_gis/items/171b3d12775c95f722c4

https://qiita.com/miya_gis/items/cde6c1eb3c33378d9718

https://qiita.com/miya_gis/items/78dd08bc7f0b5497b83d

https://qiita.com/miya_gis/items/966113ce9732cb112c49

https://qiita.com/miya_gis/items/f45b67fbc2575f0d6d77

https://qiita.com/miya_gis/items/67eac96071aa7d7d24dd


# DataTable とは

簡単に言えば、「データを`表形式`で格納する」ものです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/88eb9db5-b873-118a-5b63-ed6dc7fa4054.png)
後で説明しますが、UiPath では この「DataTable」が Excel 操作等で多用されるため、概念と使用方法を理解する必要があります。


# DataTable の背景と歴史

そもそも DataTable は `SQL Server 等のデータにアクセスするための機能` として作成されたクラスで、ADO.NET と呼ばれるライブラリや、VB の中でも利用頻度の高い、重要なクラスとして登場しました。

https://docs.microsoft.com/ja-jp/dotnet/api/system.data?view=net-6.0

DataTable は、DataSet の内部にある機能で、概念としては「データを`表形式`で格納する」ものです。

全体像をイメージにすると、以下のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/750712b3-1bd5-e451-a033-90e073921e2f.png)

- **DataProvider** を使用して、データベース（DataSource）のデータにアクセス
- DataProvider には、**DataAdapter** というデータの格納・変更用クラスがある
- DataAdapter は **DataSet** でデータを保持している
- DataSet には、**DataTables** というコレクションがあり、内部に **DataTable** がある
- DataTable は **DataRow** と **DataColumn** で構成される
- DataTable には **DataView** というデータフィルタ（加工機能）がある

表で整理すると、以下のようになります。

| 用語 | 何を表すもの？ | 言葉で言えば？ |
|:-:|:-:|:-:|
| DataSet | データ **ベース** | 色々な種類のデータが集まった箱  |
| DataTable  | データ **表** | ある１種類のデータが集まった表  |
| DataColumn | データ **列** | データの縦列  |
| DataRow  | データ **行** | データの横行  |
| DataView | データ **フィルタ** | データの集計・並び替え  |

<br>

DataTable の歴史は古く、昔は「データの操作 ＝ DataTable」という位にメジャーでした。

現在では「O/Rマッパー」のような便利ツールが主流で、以前のようには多用されませんが、DataTable の「`データ定義が簡単に出来て、自由にデータを格納できる`」という機能は素晴らしく、特に RPA などの「エクセルに書かれた縦横の表データ」を扱う場合には、非常に便利です。

:::note info
DataSet・DataProvider・DataAdapter は、UiPathでは覚えなくて大丈夫です（意識する必要はありません。）
:::

https://docs.microsoft.com/ja-jp/dotnet/api/system.data.datatable?view=net-6.0


# UiPath での DataTable

RPAツールの UiPath では、DataTable は Dictionary と並び「多用される`型`ランキングのTOP5」に入ります。その「機能の豊富」さと「使用頻度の高さ」から、「`DataTable を制する者は UiPath を制する`」と言っても過言ではありません。（逆に、DataTable の操作に不安があると、UiPath で困るシーンが増える とも言える）

例えば、以下のように「`読み込んだデータの格納先`」として使用されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/cbad4885-8634-47fa-3155-c6b483e3f5f3.png)
また、Excelへの`書き込み（書き戻し）データ`としても使用できます。

Excelを使わない場合でも、処理中のデータを格納する用途にも利用できます。要するに「`便利な箱・処理データベース`」として、幅広く使用できるのです。


# Excel シートからデータを読み取るときの注意

たまにあるのですが、読み込みたい Excel 表の「列名」が重複していることがあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/c3202e17-aa75-3b58-7dac-7ad3751a6d43.png)

UiPath の「範囲を読み込み」アクティビティで表を取得したいところですが、DataTable の列名は、ユニーク（重複はNG）にする必要があるため、この場合、列名をヘッダーから読み込むことが出来ません。この場合、以下のいずれかの対応をします。

```
1）Excelシート上の列名を変えてもらう
　※ 列名は変えたくない（変える労力が大きすぎる）場合は諦めて「２」へ

2）いったん「ヘッダーなし」で読み込んでから、列名を自分で設定して回避

3）ヘッダー以外のデータ範囲を指定読み込みしてから、列名を自分で設定する
```

「ヘッダーなし」で読み込む場合、以下のオプションのチェックを外します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/4de87ba0-6531-3f83-3c16-1118cffd7c72.png)
ヘッダーなしで読み込むと、データテーブルの列名は「Column1」のように設定されているので、妥当な名前に自分で変えていくイメージです。列名の設定方法は、この後の「列定義」の話で説明します。


# DataTable の列定義

DataTable は「列の定義」を自由に作成・変更できます。

新規作成時なら、標準アクティビティの「データ テーブルを構築」で対応可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/e24afca1-ff69-156b-8a0d-94bc3c274287.png)
ですが、定義の内容が [データテーブル...] ボタンを押さないと見えないのと、列を3個以上にすると、横スクロールが発生して分かりにくい　のが残念です。

以下のように「データ列を追加」アクティビティでも追加できますが「１列をづつ足していく」ので、列が多いと面倒です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/720745e7-01d7-849a-a19a-ace654bd0842.png)
以下のように「InvokeCode で 1列づつ定義を足していく」ことも出来ますが、同じく、列が多いと面倒です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/8e6b233e-00de-6893-ec5b-00500ba77de7.png)

こういう時は「InvokeCode」アクティビティで書くと、楽で見やすくなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/a1f5a30e-621a-6a43-129c-a0f3550e1c2e.png)

`.Columns.Add（"列名"）` または `.Columns.Add（"列名", データの型）` で列追加します。あとで合算などの計算をしたい場合は「型」を指定しておくと便利です。（計算時などに別途、数値型に変換しなくて済む）

型は `Type.GetType("System.{型名}")` で指定できます。
指定可能な型名は、以下の公式ドキュメントに一覧があります。

https://docs.microsoft.com/ja-jp/dotnet/api/system.data.datacolumn.datatype?view=net-6.0

ちなみに「列名変更」は `.Columns(列インデックス値).ColumnName` で変更できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/781d9a1a-ca7d-3c5a-350b-8e8f9eff7ae1.png)

複数ある場合は、定義作成時と同じ要領で「InvokeCode」アクティビティで書くと、見やすくなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/3b726b48-f23d-fd9f-b770-95bd3d16e49b.png)

# DataTable を生成しておきたい

頻度は少ないですが、データテーブルを生成しておきたい時があります。
（例：If 分岐で DataTableが作られないことがあるが、後続の処理で「.rowCount」で件数を確認したい）

その場合は、以下のように初期化・生成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/3a312a87-2314-f42b-e40d-afa23a84207c.png)

`New DataTable()` のカッコの中に識別用の「データテーブル名」を指定することも出来ますが、UiPathでは使用することはありません。（そもそも変数名で区別出来るようにすべき）

InvokeCode で実施するなら
```
dt = New DataTable()
```
と書いておきます。Studioの変数パネルの「規定値」で初期化しても同じです。


# DataTable の中身を消して、空にしたい

消去の方法は２つあります。通常は「Clear」でデータだけを消します。
Resetにすると列定義も消えます（Resetを使うケースは、ほぼ無いです）

| メソッド | 内容 |
|:-:|:-|
|.Clear | DataTable からすべてのデータを消去（列の定義はそのまま）|
|.Reset | DataTable からすべてのデータ・定義を消去（まっさらに初期化） |


# DataTable をコピーしたい（別の名前で同じのが欲しい）

別オブジェクトとして複製を作成します。
中身＝データを残して複製する場合は「.Copy」です。


| メソッド | 内容 |
|:-:|:-|
|.Copy | DataTable の構造と値をコピー|
|.Clone| DataTable の構造だけをコピー（中身は無し） |


# DataTable の中身にアクセス

DataTable内のデータにアクセスるする際は、行番号、列番号／列名を指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/76be2091-076a-6b2f-42b6-eb16561f83a3.png)

「繰り返し (データ テーブルの各行)」アクティビティで、行ループしながらアクセスする場合は、列番号／列名を指定します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/3216104a-452c-a66c-c086-4203200da155.png)

:::note info
「row.Item（"列名"）」も「row（"列名"）」も同じです。以下のように「好み」で変えても問題ありません。
　A）文字数を減らしたい　　　　⇒　「.Item」を付けない
　B）列名の指定内容を見やすくしたい　⇒　「.Item」を付ける
:::


# UiPath で提供されているアクティビティ

データテーブル関連で、UiPath に標準で用意されているアクティビティ は以下です。
（2022年5月時点。UiPath.System.Activities は 「22.4.1」で確認）

| No | 名称 | 説明 |
|:-:|:-|:-|
| 1 | データ テーブルをクリア<br>(Clear Data Table)   | 全てのデータをクリアします  | 
| 2 | データ テーブルをフィルター<br>(Filter Data Table)  | 条件を指定してデータをフィルターします  | 
| 3 | データ テーブルをマージ<br> (Merge Data Table) | データテーブルを結合します。  |
| 4 | データ テーブルを並べ替え<br>(Sort Data Table)  | データを降順または昇順に並べ替えます。  |  
| 5 | データ テーブルを出力<br>(Output Data Table) | CSV 形式の文字列として出力します。  | 
| 6 | データ テーブルを検索<br>(Lookup Data Table)  | 指定の値を検索し、見つかったセルの行インデックスを返します。  | 
| 7 | データ テーブルを構築<br>(Build Data Table)  | 指定したスキーマに従ってデータ テーブルを構築します。  | 
| 8 | データ テーブルを結合<br> (Join Data Tables)  | 共通の値を使用し、データを結合します。  | 
| 9 | データ列を削除<br>(Remove Data Column)  | データ列を削除します。  | 
| 10 | データ列を追加<br> (Add Data Column)   | データ列を追加します。  | 
| 11 | データ行を削除<br>(Remove Data Row) | 指定したデータ テーブルからデータ行を削除します。 |
| 12 | データ行を追加<br>Add Data Row | データ行を追加します。 |
| 13 | テキストからデータ テーブルを生成<br>(Generate Data Table) | 構造化テキストからデータ テーブルを生成します。 |
| 14 | 繰り返し (データ テーブルの各行) <br>(For Each Row)| データテーブルの各行に対してアクションを 1 回実行します。 |


# 終わりに

今回は、データテーブルの「基本知識」について書きました。次回以降は、具体的な操作方法を説明していきます。

この記事が参考になったら、 LGTMをお願いします。閲覧ありがとうございました。