<img src="//trc.taboola.com/1222697/log/3/unip?en=page_view" width="0" height="0" style="display:none">

ナレッジベース

Excel "Read Range"アクティビティにおける"unexpected process termination!"エラーの回避方法

概要

"Read Range"アクティビティを使い、Excelシートのデータを読み込む際に「UiPath Robotは動作を停止しました」「Message:Job "プロジェクト名" stopped due to unexpected process termination!」というエラーメッセージが出ることがあります。これはほとんどの場合、Excelシート全体の情報を読み込もうとしてメモリ不足となりプロセスが終了することが原因です。この記事ではこの問題を回避するための3つの方法を紹介します。

問題の背景

"Read Range"アクティビティでは"Range"プロパティを設定しないと使用されている範囲全域を取得しにいきます。この場合問題になるのが、一見するとセルがブランクでデータが入っていないように見えても、実はセル書式が設定されている場合です。"Read Range"アクティビティはこうした場合、書式のみが設定されているセルも読み込みに行きます。
Excel2010の仕様ではワークシートは最大で1,048,576行、16,384列が使用可能です。もしシート全体に書式が設定されている場合、この数だけ読みに行ってしまいます。このため、実際に使用されていて読み取る意味のある範囲に限定する必要があります。

問題の回避方法

① まず最初は当然ながら、読み取る範囲を予め定義できるか検討します。業務上発生する件数がわかる場合や過去に発生した最大件数がわかる場合はその数字に対して2倍や3倍というように余裕を持たせて定義しておきます。また、シート内容を"For Each"アクティビティで読み取る処理を進める途中で処理件数をカウントしておき、万が一予め定義した最大件数に到達した場合は"Throw"アクティビティを使って例外を発生すると「全件を読んでいないにも関わらず正常終了してしまう」といったことを防ぐことができます。

② 2つ目の方法は、"System - File - Workbook"配下の"Read Range"アクティビティを使う方法です。Excelを操作するためのアクティビティには2系統あり、1つは"App Integration - Excel"配下のアクティビティでこちらはExcelがインストールされている必要があります。もう一つは"System - File - Workbook"配下のアクティビティで、こちらはExcelがインストールされていないPCでも利用することができます。セルに値がなく書式だけ広範囲に埋め込まれているようなシートでは、こちらのアクティビティの方がメモリの消費が低くなることがあります。必要な処理をすべて"System - File - Workbook"配下のアクティビティで実行してもいいですし、Read Rangeで取得したDataTableから最大件数だけを取得して、その値を"App Integration"配下のRead RangeアクティビティのRangeプロパティとして指定するやり方もあります。

③ 3つ目にご紹介する方法は、"Invoke Code"アクティビティを使って実際に使用されているセル範囲を取得する方法です。書式のみ設定され値が入っていないセルは読み取り範囲から外し、値が入っている範囲の最大行数と最大列数を取得します。なお、Excelが端末にインストールされていることが前提となります。
ただし、ここでご紹介する方法はXAMLファイルを直接テキストエディタで編集する内容を含み、UiPath Studio以外での編集はサポートの対象外となることにご注意ください。この方法以外ではどうしても問題が解決しない場合の最終手段として自己の責任において実施する必要があります。

手順

(1) まず"Invoke Code"アクティビティ内で"Microsoft.Office.Interop.Excel"アセンブリを使用するため、XAMLファイルをメモ帳などのテキストエディタで開き次の行を追加します。
 
<Activity ...
...
<TextExpression.ReferencesForImplementation>
...
<sco:Collection x:TypeArguments="AssemblyReference">
...
<AssemblyReference>Microsoft.Office.Interop.Excel</AssemblyReference>
...
</sco:Collection>
</TextExpression.ReferencesForImplementation>
...
</Activity>

(2) 次に、Excelシート内で使用されている範囲を取得するための処理を"Invoke Code"アクティビティで記述します。
 
Dim app As Microsoft.Office.Interop.Excel.Application = New
Microsoft.Office.Interop.Excel.Application()

app.Visible = False
Dim wb As Microsoft.Office.Interop.Excel.Workbook = app.Workbooks.Open(file)
Dim ws As Microsoft.Office.Interop.Excel.Worksheet = CType(wb.Sheets(sindex), Microsoft.Office.Interop.Excel.Worksheet)
rc = ws.UsedRange.Find("*", , Microsoft.Office.Interop.Excel.XlFindLookIn.xlFormulas, ,Microsoft.Office.Interop.Excel.XlSearchOrder.xlByRows, Microsoft.Office.Interop.Excel.XlSearchDirection.xlPrevious).Row
cc = ws.UsedRange.Find("*", , Microsoft.Office.Interop.Excel.XlFindLookIn.xlFormulas, ,Microsoft.Office.Interop.Excel.XlSearchOrder.xlByColumns, Microsoft.Office.Interop.Excel.XlSearchDirection.xlPrevious).Column

wb.Close()
app.Quit()
wb = Nothing
app = Nothing

GC.Collect()
GC.WaitForPendingFinalizers()
GC.Collect()
 
変数fileは読み取り対象のExcelファイルへのパス、sindexはExcelファイル内のシートの位置(1以上)を表します。
 
実行すると変数rcに使用されている最大行数、ccに使用されている最大列数が格納されます。
 
これらの"Invoke Code"アクティビティ内の変数は、UiPath StudioのVariablesフィールドで定義されたそれぞれ対応する変数(file→filename, sindex→sheetIndex, rc→rowIndex, cc-->colIndex)に"Invoke Code"アクティビティの"Edit Arguments"で紐づけます。
 
ご利用の環境に合わせてfilename, sheetIndex変数を変更してください。
※変数"filename"を想定パスで指定する場合、”ドキュメント”フォルダがデフォルトのフォルダになることにご注意ください。
※オブジェクトの開放とGCについてはこちらの記事を参考にしました。

(3) 次に、(2)の処理で戻された使用されている最大列数を変数colIndexとして受け取り、アルファベット表記のカラム名に変換する部分を"Invoke Code"アクティビティで記述します。
 
Dim iAlpha As Integer
Dim iRemainder As Integer
iAlpha = CType(Math.Floor((iCol - 1) / 26), Integer)
iRemainder = iCol - (iAlpha * 26)
If iAlpha > 0 Then
result = Chr(iAlpha + 64)
End If
If iRemainder > 0 Then
result = result & Chr(iRemainder + 64)
End If
 
これで、列数が例えば10だった場合はアルファベットの"J"が変数resultとして返されます。

(4) 最後に、取得した最大行数と最大カラム名から"Read Range"アクティビティの"Range"プロパティに指定する文字列を組み立てます。
 
"A1:"+colName+rowCount.ToString

これで読み取る範囲が限定でき、メモリ不足が原因で起きるエラーを回避する手立てができました。

サンプルワークフロー

実際のサンプルはこちらです。

動作検証バージョン

UiPath v2018.1.4
UiPath.Excel.Activities 2.3.6660.23035