Microsoft Power AppsでCSVファイル読み取りアプリを作成してみた
はじめに
この記事の筆者の私は、テスターとしてのキャリアを開始し、マッチングサービスを中心に、単体テスト、結合テスト、総合テストを一通り経験。
また、参加したミニ人工衛星作成プロジェクトでは、ソフトウェアのみならず、ハードウェアも品質管理にも携わりました。
2017年よりベトナムから日本へ来て、2018年ハイペリオンに入社しました。
品質保証計画プロジェクトへメンバーとして参加するなど、品質管理のエキスパートとして経験を重ねてきました。
今回は、Microsoft Power Platformのファイル読み取り技術を体験するために開発したアプリを紹介します。
開発経験があまりない初心者向けに開発方法を解説します。

Microsoft Power Platformの紹介
Microsoft Power Platformとは

Power Platform (パワー・プラットフォーム)は、ユーザーがアプリを構築し、ワークフローを自動化し、データを分析するのに役立つ、Microsoftが組織に提供するローコード ツールのコレクションで、Power Apps、Power Automate、Power Pages、Power BI などのクラウド ツールが含まれる。
Microsoft Power Appsについて
Power Apps(パワー・アップス)は、コーディングの知識がなくても、業務に必要なアプリを構築するために短時間で開発できるアプリ、サービス、コネクタ、およびデータ プラットフォームのスイート。
Power Appsを使用すると、Microsoft Dataverse(データバース) という基盤となるデータ プラットフォームまたはオンラインおよびデータ ソースに保存されているデータにアクセスできるカスタム ビジネス アプリをすばやく構築できる。
Microsoft Power Automateについて
Power Automate(パワー・オートメイト)は、ローコードと AI を利用した包括的なエンドツーエンドのクラウド自動化プラットフォーム。
Power Automateを使用すると、ユーザーやチームがよく使うアプリとサービス間で自動化されたワークフローを作成し、業務の自動化、同期、通知の受信、データの収集など日常的なタスクを行うことができる。
開発機能のご紹介
アプリのオーバービュー

コンセプトは、Power AppsでCSVファイルを読み込み、DBにインポートした後、画面で内容を表示するためのアプリを作成してみる。
ファイル内容取得の処理はPower Automateの自動フローでやってみた。
Microsoft Power Platformを体験する初心者向けの記事ので、アプリを作成するための簡単な考え方とできるだけやり方で紹介してきる。
また、このアプリの例では、Googleドライブに保存されているCSVファイルになる。
CSVファイルインポート画面
概要

このPower Apps画面には、アップロードされたCSVファイルの一覧が表示される。
画面上でファイルを選択し、読み込みプロセスを介して、CSVファイルのデータをDBにインポートできる。複数の選択が可能。
開発方法
日付テキストボックス

画面には日付テキストボックスがあり、デフォルト値は今日の値に設定されている。
日付を指定するとき、データソースのファイルリストから対応するCSVファイルがフィルタリングされ、一覧エリアに表示される。
日付を変更すると、一覧エリアに表示されるデータは、新しく指定した日付に従って再反映される。
一覧エリア

一覧エリアを開発するために、画面にギャラリーエリアを追加し、それをGoogleドライブに保存されているCSVファイルのデータソースと紐付ける。
取得結果のフィルタ条件の設定もあり、日付テキストボックスの指定の値と逼迫される。
以下のギャラリーのItems属性の例には、ファイルはCSVのタイプ、ファイル名は日付含むことになる。Filter(TestGoogleDrive.ListFolder("ドライブフォルダーIDの33桁数をここに指定"), MediaType="text/csv" && Text(DateValue(DatePicker_ファイルインポート.SelectedDate),"yyyymmdd") exactin Name)
一覧エリアのチェックボックス

一覧エリアで複数選択機能を有効にするには、チェックボークスが追加され、選択・未選択のレコードがコレクション内で管理されている。
・チェックボークスをチェックするとき、レコードのIDがコレクションに追加される。
そのため、チェックボックスのOnCheck属性を次のように設定する。
If(IsBlank(LookUp(CheckedItems,fileId=ThisItem.Id)),Collect(CheckedItems,{fileId:ThisItem.Id,fileName:ThisItem.Name}))
・チェックボークスをアンチェックするとき、レコードのIDがコレクションから削除される。
そのため、チェックボックスのOnUncheck属性を次のように設定する。
If(!IsBlank(LookUp(CheckedItems,fileId=ThisItem.Id)),Remove(CheckedItems,LookUp(CheckedItems,fileId=ThisItem.Id)))
インポートボタン

「インポート」ボタンをクリックすると、コレクション内で選択されているレコードは処理対象になり、データをDBにインポートするためのPower Automateフローを呼び出され、入力パラメータを渡される。
そのため、ボタンのOnSelect属性を次のように設定する。ForAll(CheckedItems,Flow_ファイルインポート.Run(CheckedItems[@fileId],CheckedItems[@fileName]))
CSVファイルインポート処理
概要



CSVファイルインポート画面でファイルを選択し、「インポート」ボタンをクリックすると、Power AutomateのCSVファイルインポートプロセスを呼ぶ。
プロセスフローの各ステップの処理を、以下に1つずつ説明する。
開発方法
ステップ①:プロセスの入力パラメータの設定

初期ブロックに処理プロセスを実行するために画面から取得する入力パラメータを指定する。
・fileId:画面で選択したCSVファイルのファイルIDのパラメータ
・fileName:画面で選択したCSVファイルのファイル名のパラメータ
ステップ②:ファイル内容読み込みの処理

ファイルIDで指定したCSVファイルの内容を取得し、読み込む。
このアプリの例では、データソースはGoogleドライブに保存されているCSVファイルなので、Googleドライブのファイルコンテンツ取得ブロックを使う。
このステップでファイルパスの指定もある。
ステップ③:CSV_FILENAMEパラメータの初期設定

ファイル名を処理するためのパラメータのInitialize Variableブロックを作成し、fileName入力パラメータを指定する。
パラメータのタイプはStringになる。
ステップ④:CSV_CONTENTSパラメータの初期設定

読み込んだCSVファイルの内容のパラメータのInitialize Variableブロックを作成し、設定する。
パラメータのタイプはString、値はステップ②で取得された内容になる。
ステップ⑤:EACH_ROW_RAWパラメータの初期設定

CSVファイルの内容を個別の行に分割するためのパラメータのInitialize Variableブロックを作成し、設定する。
パラメータのタイプはArray、値は以下の改行で切り分け、アレイに配るために関数になる。
関数には、改行コントロール記号を明確し、処理できるため、URIエンコード処理も含む。split(encodeUriComponent(variables('CSV_CONTENTS')),'%0D%0A')
ステップ⑥:CSV_SEPARATORパラメータの初期設定

CSVファイルの列区切り記号のパラメータのInitialize Variableブロックを作成し、設定する。
実際には、区切り記号はCSVファイルによって異なる(画面から入力パラメータとして設定可能)が、このアプリの例では、一旦カンマの固定値として設定する。
パラメータのタイプはString、値はカンマになる。
ステップ⑦:HEADER_LINEパラメータの初期設定

CSVファイルの内容は、ヘッダとデータの2つの部分で構成される。
このステップで、CSVファイルの内容を分割し、ヘッダ行のパラメータのInitialize Variableブロックを作成し、設定する。
パラメータのタイプはString、値は以下の関数になる。
ヘッダコンテンツのURIデコード処理も含む。decodeUriComponent(string(variables('EACH_ROW_RAW')[0]))
ステップ⑧:HEADERSパラメータの初期設定

ヘッダ行を各ヘッダ項目に分けるためのパラメータのInitialize Variableブロックを作成し、設定する。
パラメータのタイプはArray、値は以下の関数になる。split(variables('HEADER_LINE'),variables('CSV_SEPARATOR'))
ステップ⑨:CONTENT_LINESパラメータの初期設定

CSVファイルの内容を分割し、データ部分のパラメータのInitialize Variableブロックを作成し、設定する。
パラメータのタイプはArray、値は以下の(ヘッダ部分の最初行を省く)関数になる。skip(variables('EACH_ROW_RAW'),1)
ステップ⑩:LOGパラメータの初期設定

処理ログのパラメータのInitialize Variableブロックを作成する。
パラメータのタイプはArray、値は未設定する。
ステップ⑪:LOOPの処理

各CSVデータの行ごとに、同じデータの処理があるので、Apply to eachループのブロックを作成する。
ループ処理の対象はCONTENT_LINES(データ部分のパラメータ)になる。
ステップ⑫:データコンテンツデコード処理

このステップでエンコードされたデータをデコードする。
Composeブロックを追加すると、入力処理は以下の関数になる。decodeUriComponent(items('Apply_to_each'))
ステップ⑬:各データ項目の分割処理

次に、列区切り記号によってデータ行を各ヘッダ項目に分ける。
Composeブロックを追加すると、入力処理は以下の関数になる。split(outputs('Compose_EACH_ROW'), variables('CSV_SEPARATOR'))
ステップ⑭:不正なデータチェック処理

各データ行とヘッダの項目数量が一致していないか確認する。
Conditionブロックを追加すると、条件は以下の関数になる。length(outputs('CSV_content_array')) is equal to length(variables('HEADERS'))
ステップ⑮:エラーログ追記処理

チェック処理でデータの不一致がある場合、ログにエラーメッセージを追記する。
Appendブロックを追加すると、LOGパラメータに値を追記する。
関数に、ステップ⑬の値を取得し、出力メッセージに渡す。
ステップ⑯:データ登録処理

チェック処理でエラーが発生しなければ、データを登録する。
そのため、先ずはデータ処理ブロックを追加し、データ先を指定する。その後、テーブル構造に合わせて、各列の値を設定する。
このアプリの例では、以下の列を持つ「テストサービス」というテーブルにデータを登録する。
・ID:レコードのID、ランダムに生成する。設定の値は以下の関数になる。
concat(convertFromUtc(utcNow(),'Tokyo Standard Time','yyyyMMdd'),rand(10000,99999))
以上の関数を使うと、システム日付と10000~999999のランダムの数字を組み合わせたテキスト文字列を作成できる。
・サービス名:CSVファイルのデータから値。設定の値は以下の関数になる。
outputs('CSV_content_array')[1]
・価格:CSVファイルのデータから値。設定の値は以下の関数になる。
outputs('CSV_content_array')[2]
・ファイル名:CSVファイルのファイル名から値。CSV_FILENAME入力パラメータを設定する。
・記録日時:登録時点の値。以下のシステムの現時日時を取得する関数を使って、設定する。
utcNow()
ステップ⑰:ログ追記処理

データをDBに登録した後、ログを追記する。
Appendブロックを追加すると、LOGパラメータに値を追記する。
関数に、ステップ⑬の値を取得し、出力メッセージに渡す。
ステップ⑱:その他の処理(アプリの将来の改善の可能性)

自動フロー処理が完了すると、他の処理にも追加できる。例えば、
・ログがJSON出力パラメータとして、メッセージに渡して、アプリ画面に表示する。
・ログの内容がメールテンプレートに渡して、メールを指定のメールアドレスに送る。
データ読み取り結果確認画面
概要

このPower Apps画面には、インポートされたデータを一覧で表示する。
開発方法
一覧エリア

インポートされた情報を素早く簡単に確認するために、開発時には、画面にギャラリーエリアを追加し、データが登録された「テストサービス」というテーブルに紐付ける。

そして、一覧に「サービス名」や「価格」など表示したい情報を指定する。
改善のポイント
適切な画面や処理などを追加・連携することで、インポート流れ従うだけではなく、手動で新しい情報を登録したり、既存の情報の詳細を確認、更新、削除したりするアプリの機能を延長できる。
以下はサンプルの画面になる。(今回の記事は詳しい開発方法については触れない。)
・情報登録/更新画面

・詳細情報確認画面

まとめ
Microsoft Power Platformは、ノーコード開発プラットフォームではなく、ローコード開発プラットフォームであり、複雑な数式が多数含まれているため、Powerスイートのツールを効率的に使用するには、基本的な開発知識が推奨されます。
初心者は、Powerスイートのツールの使い方を習得するのに、ある程度の時間が必要になると思います。
一方、Microsoft Power Appsは強力なツールであり、Google AppSheetよりカスタマイズ性が高く、従来の開発ツールに比べて便利で、開発時間を短縮できます。
初めてPower Appsを使ってアプリを作成する場合は面倒かもしれませんが、本格的なアプリを自分で作成できれば楽しいですよね。
お問い合わせフォーム
この記事やサービスについてご質問やご相談がある方は必要事項をご入力の上、お気軽にお問い合わせください。
2〜3営業日以内に、担当者よりメールでご連絡差し上げます。