KNOWLEDGE & INSIGHTS

2024.12.18

【RPA】DataTable型変数で取得できないExcelファイルを UiPathで自動化する方法

UipathにおけるDataTable型の概要と課題

 UiPathのDataTable型変数は、ExcelファイルやCSVファイルに入力されたデータを一つにまとめて、行や列での繰り返し処理や値の絞り込み等が可能となる業務自動化に欠かせない変数型です。ですが、DataTable型でうまく動かせるデータは、1セルにつき1つの値のみが入力され、列や行の間に空白が存在していないものとなります。もちろんデータによっては表に空白セルが生まれる場合もありますが、その場合でも他の行や列には値が入っているため、DataTable型のレイアウトは崩れません。
 ですが、いわゆる「Excel方眼紙」と呼ばれる、均等なサイズの行および列の中で複数のセルを結合して、印刷したときや人の目で確認したときに揃って見えるように作られたExcelファイルの場合は、DataTable型としての機能をほぼ失ってしまいます。
 具体的には、このレイアウトで作成されたExcelファイルから表になっている箇所をUipathで読み込むと、1セルに複数の値が入力され、不要な行および列がDataTableの中に作られてしまってどの値がどの行や列に紐づくのかが崩れてしまい、正確なDataTable型として取得できず後続業務に支障をきたしてしまいます。
 今回は、そんなExcel方眼紙をUiPathで自動化する必要が発生した案件に携わった経験から、Uipathでの業務自動化を図っている方々の参考になるよう、対処方法を共有したく思います。

 

そもそもDataTable型による課題を回避するには

 この記事ではExcel方眼紙を正しい形のDataTable型で取得できるようにする方法を解説します。ですが、「これなら自動化できる」とExcelファイルの形式を見直さずに自動化するのは非常に問題です。
 そもそも、RPAは「人の手による判断が不要」「複雑な分岐が少ない」「決まった操作を繰り返し行う」業務に対して、人が手で業務を行うことで発生する可能性のあるミスの防止や、人が単純作業に割く業務時間短縮のためにある技術です。そのため、フォーマットが統一されていなかったり、文字色・背景色・取り消し線・図形などで処理を分岐する必要があったりするExcelファイルとの相性は悪いです。このようなExcelファイルをそのまま自動化することは、その後のメンテナンスが複雑になったり、安定稼働の妨げになったりとメリットはありません。
 基本的には、RPAでの自動化をする前に「本当にこのExcelファイルの形式で効率的に業務自動化を進められるか?」と確認してください。
 事例として挙げる案件では、携わっている部署が多岐にわたっており統率が取れないとのことで、ファイルをRPAで読み取りやすい形に見直してExcelファイルの形式を変更することをやむを得ず断念しております。このようにどうしても、といった場合を除き、まずはExcelファイルの形式を見直すところから始めるのが「業務改善」の正しい形です。
 また、実際にどうやったらRPAで加工しやすい様式になるか、という例を開発側が提示して、どこまでなら実務担当者側と合意できるかを話し合うのが最適でしょう。

 

事例を基にしたDataTable型の課題対策の解説

 今回使用するExcelファイルは以下の形です。

 この場合は、下図のような形で改善案を提示し、改善できる点、できない点を擦り合わせていくのが良いかと考えられます。
 A案の方がより良い形ではありますが、同じ値を繰り返し入力したくないといった要望がある場合は、B案の形にして、空白行があれば上の行の値を保持して埋める、と処理する方法も考えられます。

 

実際にExcelファイルを加工した手順

 改めて今回使用するExcelファイルを確認していきます。なお、実案件でのファイルをベースにしていますが、記事にするうえで大幅に改変しております。
 このファイルの問題点としては、Excel方眼紙形式である点に加えて以下が挙げられます。

  1. 1セルの中に読点で区切られた複数の文字列がある
  2.  ヘッダがない列項目が存在している(M~R列)
  3.  項番ごとに含まれる行数が固定されていない
  4.  ファイルごとにレイアウトが若干異なる場合がある(列数が異なるファイルが存在していました)

 このままでは、単純に読み取りを行っただけでは空白だらけのデータテーブルが構築されてしまいます。また、例えば項番1では列項目「部署」と、M列~R列(以降「項目詳細」と呼称)の紐づけが正しく行われません。この場合では、総務人事に対しての勤怠、入退社、経費精算と、営業1課、営業2課に対しての取引会社一覧となってしまいます。
 参考までに、このままの状態で取得したデータテーブルを出力すると以下の形になります。ヘッダも正しく取得できておらず、DataTableとしての活用が難しいことがわかります。

 では、このExcelファイルの問題を一つずつ解決していきたいと思います。

 

全体の進め方

 この形のExcelファイルは、一度にDataTable化しようとしない方が結果的に安定して動きます。
 今回の場合は、大きく操作を3段階に分けています。
 1つ目は「事前準備」として、出力に必要なDataTable型変数の構築を行っています。
 2つ目は「Excelファイルから値を取得する」として、Excelファイルに入力されている表の値を、列項目ごとに分けて取得して「事前準備」で作成した列項目ごとのDataTable型変数に格納していきます。
 3つ目は「まとめDataTable作成」として、2つ目で取得した値のDataTableを、1つのDataTableにまとめていく作業をしています。
 今回のExcelファイルでは必要な列項目が決まっており、更に項番が付けられているためどの行からどの行までを1つの塊として扱うか判断でき、この方法となりました。

 

列項目DataTableの取得方法

 それぞれのDataTableの取得方法としては、表のスタート位置を設定し、そこから特定の行までを1行ずつ繰り返して各行の列項目を取得していく方法を取りました。A1から表が始まらない形のため、ヘッダの文字列をExcelファイル内で検索し、ヒットしたところを始点としています。
 また、列項目の位置や表のスタート位置がファイルによって異なる場合があったため、ヘッダ行の名称で検索をかけ、検索にヒットしたセル番地を行および列として変数に保存し、繰り返しのたびに数字を加算したり、アルファベットを置換したりすることで正しい値が取得できるようにしています。
 では、個別の列項目ごとに、Excelファイルから値を取得する方法を説明していきます。

 

列項目「項番」

 セルが結合されていることが問題ですが、UiPathでは結合されたセルは最も左上の行に値が入っていると認識されます。
 今回この列項目は出力するDataTableには必要ありませんが、他列項目の紐づけを確認するため、どの行からどの行までが1項番以内かの情報を取得しています。
 サンプルExcelを使用して取得した項番情報のDataTableが下の図となります。

 

列項目「部署」

 問題点で挙げていた、複数の値が読点で区切られて入力されている列です。また、サンプルExcelで示した通り、列項目によって1行しかないものもあれば、2行に渡って値が入力されているものもあります。ただ、複数行に渡っている場合でも一旦行数と値をセットで取得する、という流れは変わりません。
 問題となるのは読点で区切られている点です。この解決方法としては、String型のSplidメソッドを使用しました。
 まず、通常通り値を取得します。そして、取得した文字列をSplidメソッドを使用して読点で区切り、リスト型変数に代入します。リスト型変数に代入した値を、「繰り返し(コレクションの各要素)」アクティビティを使用して、行数と共にデータ列に追加することで1つずつの値を取得できるようにしました。
 最終的にできる部署情報DataTableが以下の形となります。

 

列項目「項目詳細」

 列項目がヘッダになく、列項目「項目」を基準に値の入っている列を特定する必要があります。この列についても、ファイルによって位置が変わることがあるためセル番地を直接指定することはできませんでした。
 元々のヘッダ列から「項目」の位置を取得し、セル番地のアルファベットを数字に変換します。この数字を加算して更にアルファベットに戻すことで、右列を指定することができます。5回ほど「繰り返し(後判定)」アクティビティを使用して右列に進みながら、処理中の列の1行下に値があるかを判断し、あればその列を列項目「項目詳細」の始点として指定するようにしました。
 繰り返しの処理と、取得したDataTableは以下になります。

 

列項目「日付」

 列がそれぞれ分かれているので、一度年・月・日をそれぞれ取得してからyyyy/MM/ddの形にしてDataTableに格納しています。

 全ての列項目がそれぞれ行数と併せてDataTableに格納出来たら、第一段階は終了です。次に、この取得したそれぞれのDataTableを1つのDataTableにまとめていく作業を行います。

各列項目DataTableの統合方法

 1行に含めるデータの基準となるのは、列項目「項番」のDataTableです。この基準となるDataTableに対して、「繰り返し(データテーブルの各行)」アクティビティの中で更に各列項目のDataTableを繰り返していくことで、1行ずつ値を紐づけられるようにしました。列項目ごとの行数に応じて、どのDataTableの繰り返しの中に繰り返しを入れていくか、どの値を閾値とするかはExcelファイルの形式によりますので、もしこの記事を参考にUiPathのフローを作成する場合はご留意ください。
 では順を追ってDataTableから値を取得していきましょう。

 

開始行と終了行の指定

 繰り返しの初めに、列項目「項番」DataTableのループの中で他項目列DataTableを繰り返す条件を設定するため、開始行と終了行の値を設定します。これを設定することで、各項目列DataTableの行数列の値が開始行から終了行の間の数値であれば1行に含める、と判定できるようになります。 


 

 開始行の指定は、列項目「項番」DataTableに入っている行数の値を取得すれば問題ありません。
 問題は終了行で、例えばExcelファイルに1行しかデータがない場合や、項番DataTableをループし最終行にたどり着いてしまうと、その下に値がないため最終行を取得する基準がなくなってしまいます。かといって、上記の場合は列項目「項番」DataTableの最終行の行数に1を加算して取得しようとすると、部署名などが2行以上だった場合に最終項番内にある2行目の値が取得できなくなってしまいます。
 そのため、列項目「項番」DataTableの行数をカウントし、1行しかなかった場合はその時点で最終行を先に取得していた「最終行の行数」に指定するようにします。そうでなければ、基本的に最終行は「列項目『項番』DataTableの現在処理している行数の1つ下の行に入力されている行数-1」の数を最終行に指定します。ループを繰り返す中で、ループのカウントが列項目「項番」DataTableの行数と等しくなった際に、最終行の指定を「最終行の行数」に指定するようにしました。
 これで、開始行の行数が変数「int_PreItem」に、最終行の行数が変数「int_NowItem」に入りました。

列項目DataTableの繰り返し

 変数を指定した下に、「繰り返し(データテーブルの各行)」アクティビティを追加します。次は部署をそれぞれ取得していく流れです。
 追加した繰り返しアクティビティの中に条件分岐アクティビティを入れ、条件を以下のように指定します。
int_PreItem <= Cint(deptRow(“行数”)) and Cint(deptRow(“行数”)) < int_NowItem
 ※deptRowは繰り返しアクティビティで使用するDateRow変数です。この場合、列項目「部署」の行を指定しています。
 つまり、繰り返している列項目「部署」DataTableの行数に入力されている値が、処理中の項番行数内かを判定する条件となります。今回のサンプルExcelファイルの1項番目で例えると、5行目以上8行目未満であれば、値を取得してくるようになります。
 条件に当てはまれば、代入アクティビティで該当する値を変数に保存します。

 この作業をそれぞれのDataTableに対して繰り返していきます。
 そして、これを実行した結果を出力したものが、以下のDataTableとなります。1行に1つずつデータがまとまったため、このDataTableから他システムへ情報を転記するなどの継続処理が容易にできる形になりました。

 

繰り返し処理における時短テクニック

 また、ここで対象の項番以内である場合は代入処理だったり、更なる列項目DataTableの繰り返しだったりを行いますが、対象外としてElseになった場合の処理に少し工夫してあげるとより時短に繋がります。 
A以上B未満、として繰り返している今回の条件では、A以下の場合は繰り返すことでAに到達する必要がありますが、B以上になった場合はそのあとのデータ行全て対象外になります。そのため、閾値を超えたら(項番の終了行以上の行数に達したら)「繰り返しを終了」アクティビティでループを終わり、次の項番に進めるようにすると不要な繰り返しを防げます。因みに、アクティビティを検索する際は「break」と入力すると早く見つけられます。
 こういった繰り返しと条件分岐を何度も重ねるシナリオは必然的に実行時間が延びてしまう傾向にあるので、なるべく不要な繰り返しは避けられるようにして挙げるのが良いでしょう。

まとめ

 RPAで業務の効率化を図りたい場合、どうしても最短でやりたいことを実行しようとしてしまいがちです。ですが、今回のように複雑なExcelファイルの場合であれば、コード実行でマクロを実行させたり、DataTable化を複数回繰り返したりといった回り道が結果的に最も安定して速さを出せるシナリオになることがあります。
 再三の繰り返しにはなりますが、そもそもはExcelファイルの在り方から見直して、RPA化しやすい形を関係者全員で協議することから始めるのが最も良いRPA化の在り方と言えるでしょう。ですが、どうしてもその方法が取れずExcel方眼紙を自動化しなくてはならない、となったときに、開発の一助となりましたら幸いです。

 

熊谷菜海

アーツアンドクラフツConsulting & Solution事業部/プログラマー。得意分野はRPA