3.A.4. エクセルリード

この例では、Excel ファイル (.xlsx)に含まれるいくつかの請求書を読み込み、その中のデータを取り込んで、マージされたデータを含む新しいExcel ファイルを生成します。

この例を示すために使用する請求書は、こちらでご覧いただけます。請求書(https://github.com/open-rpa/examples-files/raw/master/bpa-doc/read_excel/invoices/invoices.zip)

images/openrpa_workflow_example_read_excel_invoice_example.png

.rarファイルを任意のディレクトリで解凍し、そのフォルダパスをどこかに保存してください(後で使用します)。

このワークフロー例を実現するために、以下のステップを踏んでいます。

  1. 空のDataTableを作成する

  2. 各請求書について
    • 個々のセルを読み取る

    • テーブルのセル(”items”)を読み込む

    • DataTableにこのイテレーションのインボイスを追加する。

  3. DataTableからExcelを書き出す

3.A.4.1. 空のDataTableの作成

請求書から読み込まれるExcelデータは、すべてDataTableに保存されます。

CreateDataTableアクティビティをメインシーケンスの末尾にドラッグします。

最初の入力フィールドで、DataTableの名前をinvoicesDataTableとする。

備考

OpenRPAは、アクティビティ/プロパティに必要な正しい型を持つ新しい変数を自動的に作成することができます。プロパティボックスで新しい変数を作成する場合、変数名を入力した後、キャレットを入力フィールドに入れたまま、Ctrl+Kキーを押します。

この場合、2つ目の入力フィールドに割り当てられるフィールドはヘッダーです。したがって、2番目の入力フィールドには、{"Invoice Number", "Company Name", "Shipping Address", "Shipping Tel. Number"、 "Due Date"、 "Qty. of Items"、 "Due Balance"}を内容として記述します。

各アクティビティのDisplayNameを意味のあるものにリネームすると、ワークフローの各パーツが何をするのかが把握しやすくなるのでおすすめですそう考えると、このアクティビティを「Create Empty DataTable」にリネームしてみましょう。

images/openrpa_workflow_example_read_excel_create_empty_data_table.png

備考

OpenRPAでは、DataTableは値を保持するために使われる2次元の非シリアライズ可能なオブジェクトに相当します。これはij列の行列と考えることができます。i行は.Rows(n)属性でアクセスできます。ここでnはアクセスしたい行の番号です(0から始まります)。j個の列には、.Item(n)属性を使ってアクセスします。nは、アクセスしたい列の番号-0から始まる-です。ここで、ユーザがRows属性にアクセスしなければならないことを思い出してください。したがって、ユーザがデータ テーブルの 3 行目の 2 列目にアクセスしたい場合は、.Rows(2).Item(1)属性を使用することになります。

備考

.NET APIでは、DataTable オブジェクトは、同じ名前のクラスのDataSet オブジェクト 含まれるインメモリデータの1つのテーブルに対応します。Excel ファイルを読み込むと、それは自動的にDataSetクラスに割り当てられ、すべてのシートは DataTableクラス(0からExcel ファイル内のシート数まで番号が付けられている)に保存されます。ここで、DataTableオブジェクトは大文字と小文字を区別することに注意しましょう。

3.A.4.2. 各インボイスについて

最初のアクティビティは、ディレクトリをループして、そこに含まれるすべてのファイル名を返します。

まずAssignアクティビティをドラッグして、ループさせたいディレクトリの絶対パスを変数に代入します(例:path)。

images/openrpa_workflow_example_read_excel_assign_path.png

ForEachWithBodyFactory<>アクティビティをメインシーケンスにドラッグします。

プロパティボックス内の適切なTypeArgumentパラメータをStringに設定します。これは、反復処理されるディレクトリにファイルパスが含まれ、それがString型の値として返されるためです。

アクティビティの右側で、filePathに割り当てられているアイテム変数を変更します。

アクティビティの左側に、System.IO.Directory.GetFiles(path)を挿入してください。

filePath変数に、各請求書のフルファイルパスへの文字列が入るようになりました。

images/openrpa_workflow_example_read_excel_for_each_with_body_factory.png

個々のセルを読み取る

ここでは、ロボットは単一の値のみを含むフィールドの個々のセルを読み取ります。これらのフィールドは静的です(行数は固定で1つです)。

これらのステップは非常に繰り返しが多いので、invoiceNumber変数のステップのみを再現します。さらに練習したい場合は、他の変数、つまりcompanyNameshippingAddressshippingTelephoneNumberdueDateについても同様に行うことを強くお勧めします。

Recorderでセルを選択するか、OpenRPA.Utilitiesツールボックス内にあるReadCellアクティビティをForEachWithBodyFactory<>アクティビティ内のシーケンスにドラッグしてください。

Recorderが使用されていない場合、ユーザーはこのアクティビティを使用するために、さらにいくつかのステップを踏む必要があります。まず、プロパティ・ボックス内のFilenameパラメータをfilePath変数に割り当てて、読み込まれるExcel ファイルを 選択します。Cellパラメータにキャプチャされるセルを入力します。この例では、請求書番号に対応する「H3」です。

ReadCellアクティビティはExcel ファイルから読み込んで、デフォルトでString変数にセルを保存します。ユーザーは、Propertiesタブ内のArgumentTypeパラメータを変更することで、取り込むデータの種類を変更することができます。

この変数はまだ存在しないので、まず作成する必要があります。この変数には必ずSystem.Data.String 型を設定しなければならないことに注意してください。

プロパティタブ内のResult入力欄をクリックし、使用したい変数名を入力するだけです。この場合、invoiceNumberとなります。

ここで、残りの変数についても、上記の手順を繰り返してください。

images/openrpa_workflow_example_read_excel_read_individual_cell.png

ここで集めた値をすべて取り込んで、後でDataTableに保存できるようにするためには、変数Scopeを一番外側のシーケンスに変更する必要があることを忘れないでください。

images/openrpa_workflow_example_read_excel_change_scope.png

備考

プロパティボックスで新しい変数を作成する場合、変数名を入力した後、キャレットを入力フィールドに置いたまま'K'を押すと、OpenRPAはこの新しい変数をアクティビティに必要な正しいタイプで自動的に作成します。

テーブルのセル(”items”)を読み込む

ここでは、ロボットが請求書内の「表」を読み取ります。個々のセルを読み取るのとは異なり、表は通常動的です(行の数は変化する可能性があります)または。これは、開発者が手動で各変数のReadCellアクティビティを追加することを許可するように、単にあまりにも巨大であるセルの特定の範囲を読み取ることができるプログラム的な方法で行われます。

この「テーブル」は「itemsDataTable」という新しいDataTableに格納され、空の列の削除、値の合計やカウントなど、いくつかのロジックも適用される。

Sequenceアクティビティをドラッグして、Items Processing Logicと名付けます。

このシーケンス内で、CreateDataTableアクティビティをドラッグして、itemsDataTableという名前のテーブルを作成します。

このDataTableのヘッダは、{"itemName", "quantity", "rate", "subTotal"}でなければならない。

images/openrpa_workflow_example_read_excel_read_items_processing_logic_create_data_table.png

課題では、0、3、5、7列を使用します。請求書のテンプレートを見てみると、これらはデータを含む列のインデックスになっています。

Read Rangeアクティビティを利用して、テーブルの内容をDataTableに取り込みます。

まず、「Filename」入力フィールドに、アクティビティが読み込むファイルのパスを入力します。

プロパティボックスの中の「セル」フィールドに、取り込みたいセルを入力します。この例では、「A14:H18」です。

images/openrpa_workflow_example_read_excel_range_cells.png

インデックス0357は、現在の行の内部にあるインデックス付きオブジェクト、つまり列を参照します。

プロパティボックスの DataTableフィールドに、保存するDataTableの名前を入力します。今回の場合、このDataTableは itemsです。

プロパティ]ボックスで、[IgnoreEmptyRows]プロパティを見つけ、この値を[True]に設定します。このテーブルにはヘッダーがないので、Use Header RowプロパティをFalseに設定します。これにより、アクティビティはデータの最初の行 (行 14) を読み込むようになります。

images/openrpa_workflow_example_read_excel_items_processing_read_range.png

そして、ForEach DataRowアクティビティでDataTableをループさせることで、Add DataRowアクティビティを使用して、各アイテム情報を「itemsDataTable」にループさせています。

images/openrpa_workflow_example_read_excel_items_processing_for_each_and_add_data_row.png

ここで、小計の値を計算し、その値を合計値に加算するロジックが登場するが、これは最終的なExcel シートで説明される。

System.Decimal 型の新しい変数quantityを宣言します。Assignアクティビティを使用して、その値をquantity + Convert.ToDecimal(row(3).ToString)に割り当てます – これにより、この変数はアイテムの反復ごとにその値を増加させることになります。

System.Decimal 型の新しい変数currentQuantityを宣言します。Assignアクティビティを使用して、その値をConvert.ToDecimal(row(3).ToString)に代入します。

変数currentRateについてもrow(5)を基準値として、上記の手順を実行します。

System.Decimal 型の新しい変数subTotalを宣言します。Assignアクティビティを使用して、その値をcurrentQuantity*currentRateに代入します。

最後に、System.Decimal.Decimal 型の新しい変数dueBalanceを宣言します。Assignアクティビティを使用して、その値をdueBalance + currentQuantity*currentRate に代入します。

ここで集めた値をすべて取り込み、後でDataTableに保存するためには、ユーザは変数のScopeを一番外側のシーケンスに変更しなければならないことを指摘しておく。

images/openrpa_workflow_example_read_excel_items_logic_assign_variables.png

備考

範囲を読み取る」アクティビティでは、「:」というコロン記号で取り込みたい範囲を区切り、その左側のセルを開始セル、右側のセルを終了セルとします。

3.A.4.3. この反復のインボイスをDataTableに追加する

このイテレーションの請求書から重要なデータをすべて集めたので、この情報をステップ1で作成したDataTableに追加したいと思います。

AddDataRowアクティビティをForEachWithBodyFactory<>アクティビティ内のシーケンスの最後にドラッグしてください。

最初の入力フィールドに、invoicesDataTable を挿入します。

2つ目の入力フィールドに{invoiceNumber, companyName, shippingAddress, shippingTelephoneNumber, dueDate, quantity, total}を挿入します。

images/openrpa_workflow_example_read_excel_add_invoices_data_table.png

3.A.4.4. DataTableからExcelを書き込む

これは、ワークフローの最後の部分である。ここでユーザーは最終的に、収集したすべてのデータを含むExcel ファイルを 作成することになります。

WriteExcelアクティビティをメインシーケンスの末尾にドラッグしてください。

...ボタンをクリックして、Excel ファイルを保存するファイル名を選択します。表示されるエクスプローラーウィンドウのファイル 入力フィールドにファイル名を入力します。その後、「保存」を押して、最終的に割り当てます。

収集したデータをExcel ファイルに保存するDataTable の名前を、Properties ボックスの DataTableプロパティに入力し、指定します。

Excel ファイルのスタイル設定に使用するテーマを、プロパティボックスの Themeプロパティに入力します。

images/openrpa_workflow_example_read_excel_write_excel.png

3.A.6. ファイルの操作

この例では、OpenRPAでファイルを操作する方法を説明します。ファイルの保存、移動、削除、および基本的なディレクトリ操作など、すべての基本的な手順が網羅されています。

異なるタイプのファイルを含むディレクトリがあるとします。最初の作業は、これらのファイルを拡張子に従って異なるサブディレクトリに分離することです。.txtでないファイルは削除されます。

その後、ロボットは.txtファイルにアクセスし、与えられたキーワードを検索する。ここでのアイデアは、製品の説明文の分類の自動化をシミュレートすることです。もしファイルがキーワードを持っていれば、特定のサブディレクトリに移動されます。

各アクションの後、ロボットはファイルの名前、作成日、ファイルに含まれる商品情報(種類、価格、割引)などの情報をログとしてエクセルシートに書き込む。

手順は以下の通りです。

  1. 新規ディレクトリの作成

  2. DataTableの作成

  3. ディレクトリ内のファイルを繰り返し処理する

  4. ファイル名の取得

  5. 拡張子でファイルを分ける

  6. ファイルを読む

  7. ファイル作成日の取得

  8. ファイルの内容(マッチング)を確認し、情報を抽出する

  9. 移動ファイル

  10. ファイル名の変更

  11. DataTableに情報を追加する

  12. ファイルの削除

  13. データテーブルをExcelファイルに保存する

3.A.6.1. 新しいディレクトリを作成する

最初のステップは、ファイルのあるディレクトリ(ルートディレクトリ)を指定することです。これを行うには、新しいSequenceを開始し、AssignActivityをその中にドラッグします。To “フィールドに、既存の引数を指定します。この引数のタイプは「String」でなければなりません。なぜなら、ディレクトリへのパスはテキストとしてこの引数に割り当てられるからです(つまり、引用符で囲まれます)。

次のステップでは、ファイルの移動先となるサブディレクトリを作成します。この例では、製品情報を含むファイル(「製品情報」)、製品情報を含まないファイル(「その他のtxtファイル」)、ログファイル(「Logs」)の3つのディレクトリを作成します。作成の手順はどれも同じで、違うのはそれぞれの名前だけです。

新しいディレクトリを作成するには、ユーザーはAssignActivityをSequenceにドラッグします。最初のフィールドで、ユーザーは別の引数を指定します。この引数のタイプは、「Browse for Types…」オプションで確認できます。ユーザーは、”System.IO.DirectoryInfo “と入力するか、参照することができます。この引数は、文字列や整数を格納するのではなく、新しいディレクトリを作成するための式を受け取ることを意味します。引数の名前はディレクトリの名前にはならないので、ロボットの使用のためだけであることに注意してください。

images/openrpa_manipulatingfiles_createdirectories.png

2番目のフィールド(すなわち「VB式の入力」)には、ユーザーは「System.IO.Directory.CreateDirectory(path of the new directory)」と入力することになります。括弧の中には、ルートディレクトリのパスと新しいディレクトリの名前を、すでに存在しているかのように入力します。ここでも、パスは引用符で囲む必要があります。たとえば、次のようになります。

ルートディレクトリが「C:example」の場合、ユーザーは「C:examplesubdirectoryName」と入力して、サブディレクトリを作成する必要があります。

3.A.6.12. ファイルを削除する

この例ではテキストファイルのみを対象としているので、他のファイルは削除されます。このアクションは変数に格納する値を生成しないので、変数や引数を使用することはできません。そのため、ユーザーはもう一度Invoke CodeActivityを使用する必要があります。

この例では、.txtでないファイルだけが削除されます。つまり、このActivityは、ファイルの拡張子フィルタのELSEフィールドに落とされることになります。

ファイルを削除する最短の方法は、エディタに次のコードを追加することです。System.IO.File.Delete(file_name).

images/openrpa_manipulatingfiles_deletefile.png

3.A.6.2. DataTableの作成

ファイルに移る前に、もう1つのステップが必要です。ワークフロー実行後に Log Excel ファイルが保存されるため、処理中のデータを格納する Datatable を作成する必要があります。これは、ワークフローの時点で作成され、グローバルに値を保存します。

このトピックは、このドキュメントの他の例ですでにカバーされています。Create an Empty DataTableに従って、変数の名前が同じでないことに留意してください。

3.A.6.3. ディレクトリ内のファイルに対する反復処理

タスクはルートディレクトリの各ファイルを分類することであるため、それらを繰り返し処理することが必要である。

ユーザーは、ForEachWithBodyFactor<>アクティビティをメインシーケンスにドラッグして、DataTableの作成の下に置きます。最初のフィールドには、ディレクトリ内の各ファイルを表す “item “という単語が表示されます。この名前は変更可能で、どんな名前でも大丈夫です。

最も重要なのは、2番目のフィールド(”in”)である。ここでユーザーは、System.IO.Directory.GetFiles(path)という式を入力します。ここで「path」は、メインシーケンスの最初にルートディレクトリのパスで既に設定されているArgument(「パス」)です。この式は、そのディレクトリにあるファイルのフルパスのリストを返します。したがって、ForEachアクティビティはこのリストに対して反復処理を行います。

images/openrpa_manipulatingfiles_iteratedirectory.png

3番目のフィールドはBodyで、リストの各ファイルに対してActivityが実行される場所です。このBodyの中では、以下のActivityが実行される。

3.A.6.4. ファイル名を取得する

Body内部の最初のActivityは、ファイルの名前を取得することになります。System.IO.Directory.GetFiles()式は、フルパスのリストを返すことに注意してください。後のActivityに進むには、ユーザーはファイル名だけを取得する必要があります。

それを実現する最もシンプルな方法は、VBエクスプレッションを使うことです。ユーザーはAssignActivityをBodyにドラッグします。この例では、Variableの名前は「file_name」になります。式はSystem.IO.Path.GetFileName()で、ファイルのフルパスは括弧の中、つまり Variable “item” の中に挿入しなければなりません。

備考

この値は反復処理のファイルに応じて変更されるため、ユーザーは引数ではなく、変数を使用する必要があります。このVariableのスコープは、ForEachWithBodyFactor<>(ここでは「Iterate over files」という名前)のBodyの中のSequenceでなければならないことに注意してください。このVariableのタイプは “string “である。

images/openrpa_manipulatingfiles_getfilename.png

3.A.6.5. Extensionに従ってファイルを分割する

その後、ユーザーは最後のステップのすぐ後に、IfActivityをドラッグすることになります。ここでは、ファイルを拡張子によって分離することを考えます。この例では、.txtファイルだけが読み込まれるため、他の拡張子は考慮されません。

条件」フィールドに、System.IO.Path.GetExtension(file_name OR full path) = ".txt "と入力します。

備考

ファイルの拡張子を取得する方法は、これだけではありません。ユーザーは、「file_name.EndsWith(“.txt”)」というVB式を使用することもできます。この式は、文字列の中にある文字列を探すので、引用符で囲む必要があることに注意してください。

つまり、ファイルの拡張子が「.txt」であれば、ロボットは「Then」フィールドに進み、そうでなければ、「Else」フィールドに進むことになる。

3.A.6.6. ファイルを読む

ここでは、Sequenceを2つに分割しています。まず、テキストファイルがどうなるかを考えてみましょう。

テキストファイルで実行される最初のアクティビティは、その内容を読み取ることです。ここでも、ユーザーはAssignActivityを「Then」フィールドにドラッグし、Variableを使用します。この例では、Variableの名前は「content」、タイプは「string」です。

ファイルを読み込むための式はSystem.IO.File.ReadAllText(file_name) を使用します。内容は、割り当てられたVariableに格納されます。

images/openrpa_manipulatingfiles_readfile.png

備考

この例では、.txtでないものを削除します。このチュートリアルでさらに説明します。

3.A.6.7. ファイル作成日を取得する

次に、ファイルの作成日を取得します。この手順は、前の手順(Read File)とよく似ています。つまり、ユーザーはAssignActivityを使って、VB式の内容を保存することになります。

この場合、式はSystem.IO.File.GetCreationTime(file_name).ToShortTimeString となります。

images/openrpa_manipulatingfiles_getcreationdate.png

備考

ここでは、他の可能性もある。ユーザーは、時間、日、月、あるいは、ファイルの作成に関するその他の情報を取得することができます。これを行うには、ユーザーは式の最後の部分を必要な情報の種類に変更する必要があります(例えば、System.IO.File.GetCreationTime(file_name).Month)。

3.A.6.8. ファイルの内容(マッチング)を確認し、情報を抽出する

この例では、ファイルを移動する前に、テキストファイルから情報を抽出してログファイルに追加するためのアクションがいくつか追加されています。Matchesアクティビティが採用され、ユーザーはその3つのプロパティに注目する必要があります。「入力」、「パターン」、「結果」です。

最初の “Input “は、”Pattern “の検索対象となる文字列または文字列を格納するVariableである。この場合、値はファイルの内容に対応する “content “変数である必要がある。

“パターン “は、”入力 “内の文字列から検索されるRegEx式です(引用符で囲まれている必要があることに注意してください)。

最後に、”Results “は結果が格納されるVariableまたはArgumentです(この場合、Variableでなければなりません)。

この Variable の型はSystem.Text.RegularExpressions.Match でなければならないことにユーザーは注意しなければならない。これは、結果のリストになります。この例では、マッチごとに1つの結果のみが存在することになります。この結果を得るために、ユーザーは次の構文を使用する必要があります: variablename.First.ToString, つまり、リストの最初のアイテムは文字列に変換されます。

3.A.6.9. ファイルを移動する

これらの手順が完了すると、ロボットはファイルを内容に応じて分類する。この例では、製品情報があるかどうかが基準になっています。

ユーザーは、このSequenceに別のIfActivityをドラッグします(前のIf文のBody)。ここでは、ファイルの内容を格納する変数「content」が使用されます。メソッドは.Contains("string")で、構文は次のとおりです。content.Contains("product").

備考

なお、検索される語句は文字列であるため、引用符で囲まなければならない。

もし、そのような用語があれば、ロボットは「Then」フィールドに進み、そうでなければ、「Else」フィールドに進みます。つまり、このActivityは、ファイルを2つのカテゴリに分類しているのです。これは簡単な例ですが、より複雑な用語を検索することもできます。

最初の可能性(ファイルに製品情報がある)を考慮すると、ロボットはそのファイルを「製品情報」ディレクトリに移動します。これを行うには、別のアクティビティをシーケンスにドラッグして、Invoke Codeを作成する必要があります。このアクションは引数や変数に格納する値を生成しないので、Assignでファイルを移動することはできません。

images/openrpa_manipulatingfiles_movefile.png

ユーザーは、「エディターを開く」をクリックして、呼び出すコードを編集します。ユーザーは、好きなプログラミング言語を自由に選択することができます。この例では、VBを使用しています。式の構文は次のとおりです。System.IO.File.Move (移動 元の フルパス 移動先の フル パス )。ここで重要なのは、フルパスが必須であること、つまり、ファイル名を含むことです。

そして、オリジンのフルパスは、ファイルのフルパスを格納する変数(この例では、反復処理の「項目」)を介してアクセスされる。もう一つの方法は、ルートディレクトリのパス(この例では「path」という名前)を格納するArgumentを使い、サブディレクトリとファイル名を含む別の文字列と連結させる方法です。

備考

2つ以上の文字列を連結する方法は、”&”を使うことである。

3.A.6.A. ファイル名を変更する

移動時にファイル名を変更する場合、ユーザーが行うべきことは、移動先のフルパスに新しい名前を割り当てることのみです。

この例では、ファイル名の先頭に新しい単語を追加することでファイル名を変更しましたが、任意の名前を設定することができます。ファイルを移動する式を書くとき、ユーザーは新しい名前が式に書かれ、ディレクトリのパスに連結されていることを確認する必要があります。