DataTableの行の間に、行を挿入する

## 皆もすなるQiitaといふものを、儂もしてみむとてするなり。

と言う訳で、こん＊＊は！はなっち！です。

昨日は、UiPathブログ発信チャレンジ2022サマーの1日目。
@saosao885の[【TryCatchのハナシ(延長戦)~反省会とTerminate Workflowを使ってみる~】](https://qiita.com/saosao885/items/5cf23dc127c249827fcf)でしたね！
今日ははなっち！の番です！

この記事はUiPathブログ発信チャレンジ2022サマーの2日目の記事です。

## 【序章】
EXCELでもCSVからでもいいのですが、UiPathでデータを扱い際、DataTable型を中心に扱う事が多いと思います。例えば。売上明細データがあって、その売上日毎の合計値を求めたい。こういった場合は、EXCELの、PIVOTテーブル的なアクティビティを使って実装してあげるとか...( **[はなっち！のピボット風アクティビティパック](https://marketplace.uipath.com/ja/listings/muvjzlni8d7tl2is39dsp)** をご覧ください）

時には、売上日毎の最後の行の下に、合計行を挿入したいなんて要望もあるかと思います。
EXCELで言えば、挿入したい場所の行をアクティブにして、右クリックして「挿入」し、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/c460943f-d82c-2707-9eaa-8d13aab889ae.png)
その空いた行に、SubTotalワークシート関数などを設定してあげればOK!
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/0c0d4fa7-8df8-6500-5e8c-4a161a717d67.png)

なのですが、ここはUiPathのQiitaですので、UiPathではどうやるのがいいか、ちょっと考えてみましょう！


## 【本題】
~~基本的に、DataTable型の間の行に直接行を挿入する事はできないと思っています（出来るとおっしゃる方、私に教えてください(^^♪）。~~
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/6a1736f4-2612-ad1c-92bc-61e193ba96fd.png)

##### 2022/7/10 追記
前の文章で、「直接行を挿入する事はできない」とありますが、これは筆者の無知のなせる発言で、実はちゃんとDataTable型変数.Rows.InsertAtと言うメソッドがあり、これを使えば、ちゃんと行の間に直接行を挿入する事で出来る」んです。ちょっと検証はしていませんので、その方法などは別のスレッドに書いてみます。ありがとうございます！
@Risa_Mizushinaさん
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/979c978c-b154-51e9-23e4-5e2a687d4079.png)
で、以降の内容は、Rows.InsertAtメソッドを使わない、別の方法を前提にしている、**通常使うべきではない**方法である事を前提にお読みください。
##### 2022/7/10 追記終了




~~ですので、（"SEQ列"のような）行の位置を陽に持たせて、 **挿入する行の位置**  の下に挿入するのだったら、その **挿入する行の位置＋α** の行の位置を設定した行を最終行に挿入し、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/d7f7831a-840e-8223-0b23-352300962f79.png)
後で並べ替えをするのがセオリーかなと思っています（いや違う！とおっしゃる方、私に教えてください(^^♪）。~~


### 方法1（非推奨）

入力側のDataTableに、**SEQ列(Int32型)を用意し、そこに増分を挿入行+1として、各行に値を設定**していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/62c51cc1-398c-778b-21b5-681089c67caa.png)
追加側のDataTableにも**SEQ列(Int32型)を用意し、挿入すべきSEQ番号+1の値を設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/ba9deee6-189d-aaa9-b928-d7f4a71ddded.png)
その後、入力側のDataTableと、追加側のDataTableを併合してあげます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/7a403b3d-6585-bccf-8c65-9c949ac5cd6f.png)
最後に、SEQ列をキーにして、並び替えをしてあげれば、挿入されたことになりますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/16338c7d-7dba-a870-fe50-3a86cd27ab33.png)

「繰り返し (各行)」アクティビティを使って、行の位置を計算しつつ（SEQ=SEQ+2でも、SEQ=現在のインデックス変数 * 2でも）、値を設定するのは、ちょっと手間っちゃ手間ですね。後付けの「データ列を追加」アクティビティだと、DataTableを出力した時、最終列になっているし。。。デバッグの時に美しくない！なんて方もいらっしゃるかもしれませんね。

### 方法2（非推奨）
「データ列を追加」アクティビティには、 **自動インクリメント** と言うパラメタがあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/526935d1-4ac3-9117-3c0e-bb234b4185c6.png)
これは、行が追加されるたびに、その列に+1された値が自動的に設定される機能です。これなら、後で追加する行にも"n+α"してあげれば簡単そうですね。

やってみましょう！
まず、「データ列を追加」アクティビティで、 **TypeArgumentにはDouble型、自動インクリメントはTrue** とします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/b371359c-52c5-6d7f-0f65-ef6308da57b7.png)
この、”SEQ"列しかないDataTableに対して、入力側のDataTableを、「データ テーブルをマージ」アクティビティを使って、マージします。その際、 **スキーマがない時の動作はAdd** にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/5bb3fc83-01a0-183b-3037-e1d7891df41d.png)
一方、追加側のDataTableにも、"SEQ"列を新たに追加して、そこに0.5などの値を設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/f884adff-356f-75ce-d16d-ed73eabe12d7.png)
この状態で、「データ テーブルをマージ」アクティビティを使って、マージします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/6f3f2f17-7307-8ec2-7d91-18af58bc2612.png)

と、頭の中でのストーリーは完璧だったのですが、浅知恵でしたねぇ。。。自動インクリメントをTrueにすると、そのTypeArgumentはInt32型に修正されてしまうのです！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/5422d060-beba-4b98-7c9f-48b2c9c7277a.png)
ですので、並び替えしても、合っているのかどうか、確証が持てません！ **この方法は使えません！**

### 調査！
「データ列を追加」アクティビティには、 **自動インクリメント** と言うパラメタがありました。何か他にも設定できる何かがあるのでは？と思い、探ってみました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/99122ed7-8f85-2303-f7dc-a840111ffdf8.png)
+ AllowDBNull これはパラメタの「DBNullを許可」ですね
+ AutoIncrement これはパラメタの「自動インクリメント」ですね
+ AutoIncrementSeed これは???「自動インクリメント」+「Seed（種)」ですね!?
+ AutoIncrementStep これは???「自動インクリメント」+「Step（足踏み)」ですね!?
もしかして、 **AutoIncrementSeedは自動インクリメントの開始の値、AutoIncrementStepは自動インクリメントの増分の値** ではないか？

やってみましょう！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/8788b066-b0f1-58ce-29e0-88347f9fc2f6.png)
この設定を施したDataTable型に対して、値のあるDataTableを「データ テーブルをマージ」アクティビティを使って、マージします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/510b5fb0-53a0-9d04-78ba-51521ebfeeb3.png)
"列A","列B","列名"の値は適当なのですが、"SEQ"の値は、確かに１から始まり、増分２となっていますね。

### 方法3（非推奨）
基本的には、**方法2** と同じです。
まず、「データ列を追加」アクティビティで、 **TypeArgumentにはInt32型、自動インクリメントはTrue** とします。「代入」アクティビティを使って、該当列のパラメタ、AutoIncrementSeed には1を設定、AutoIncrementStep には2を設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/6703a4c6-6372-cbba-9f2a-7cd145b4e59d.png)
この、”SEQ"列しかないDataTableに対して、入力側のDataTableを、「データ テーブルをマージ」アクティビティを使って、マージします。その際、 **スキーマがない時の動作はAdd** にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/02fd1868-a683-aca5-956d-89b146fbb610.png)
一方、追加側のDataTableにも、"SEQ"列を新たに追加して、そこに1などのInt32型の値を設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/df3b3fca-6115-3ab2-b35b-868854a7a57b.png)
この状態で、「データ テーブルをマージ」アクティビティを使って、マージします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/45abab0a-79be-81ac-a4fb-c58906aa442f.png)
マージしたDataTable、「データ テーブルを並び替え」アクティビティを使って、並び替えします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/67b911b5-74d3-2c04-eb57-936312d97bfc.png)
うまくいきましたね！（机上で見せただけですが、裏ではキッチリ確認しています<m(__)m>）

### 応用！（非推奨）
1行を追加挿入する事にしたので、AutoIncrementStep は2を設定しましたが、要件によっては2行追加挿入したいって事もあるかもしれませんね。その場合には、AutoIncrementStep は3を設定してあげればいいでしょう。
行が追加される度に、自動インクリメントがTrueとなった列の値には、AutoIncrementStep 分増えていくので、ここにマイナス値を設定すれば、減算されていくはずですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/a72d9dd0-174a-3ce4-432e-0318e2734bc5.png)
確かに、2ずつ減算された値が設定されていますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/d5f35334-00fc-8793-6747-71c1afd1f751.png)


- - - 
## おわりに
いかがでした？

~~先に紹介した、使えない方法も含んで３つの方法。~~
~~他にも、入力DataTaleの行を一行ずつ中間DataTableにImportRowしていき、ある条件を満たした時に追加側のDataTaleの行を中間DataTableにImportRowする方法もありますね。こちらの方が正攻法かもしれません。~~

~~いずれにしても、中間DataTableなどを使う方法が楽かな？って印象です。ただ、その場合、中間DataTableのメモリも消費するので、扱うDataTableの列数、行数と相談してみてください。~~

~~「DataTableの行の間に、行を挿入する」ってタイトルでしたが、 AutoIncrementSeed 、AutoIncrementStepがある！使える！って事を覚えていただければと思います！~~

今回も読んでいただきありがとうございました！
是非UiPathでのロボ開発の一助になればと思っています。

ありがとうございました！