[PowerApps]商品コード毎のデータ件数を取得
はじめに
最近ではPowerAppsを触れる機会が増えてきました。
全社へ展開となると対象となるデバイスがWindows、iPad、Androidとなってしまうので、どうしてもPowerAppsになっちゃいます。
というわけで、個人的に最近作ったアプリの中から一つの機能を紹介したいと思います。
商品コード毎のデータ件数を取得
まずは出来上がりを

複数行入力できるテキストボックスに改行で区切られた商品コードを入力。
集計ボタン押下で商品コード毎のデータ件数を表示。
想定する利用方法
バーコードとかQRコードとかをリーダー使って何も考えずにピッピピッピ読み取ると左のテキストボックスに入力される。
最後に集計ボタン押すと右のデータテーブルに各商品コードの個数を集計し表示する。
棚卸しとかで楽できるかな?
バーコードリーダーも2,3万で手に入るし、バーコードやQRコードも簡単に作れるしね。
実装
配置したコントロール

商品コードを入力するテキストボックス
モードは「複数行」
集計ボタン
データテーブル
結果出力用
クリアボタン
テキストボックス、データテーブル両方のデータをクリアする
コレクションの作成
データテーブルのソース用にコレクションを作成します。
Screen1のOnVisibleに以下のコードを記入。
ClearCollect(total,{item:""},{count:0});
今回は1画面なのでこれでも良いと思いますが、AppのOnStartでもいいかもしれません。
やってることは「item」列と「count」列を持つ「total」という名前のコレクションを作成しています。
初期値はそれぞれ空文字と0です。
集計ボタン
Clear(total);
With(
{
input:Split(Substitute(TextInput1.Text,Char(13),""),Char(10))
},
ForAll(Distinct(input, Result),
With(
{
itemNumber:ThisRecord.Result
},
If(itemNumber <> "",
Collect(total,
{item:itemNumber, count:CountIf(input, Result = itemNumber)}
)
)
)
)
)
解説
コレクションの作成
1行目で「total」コレクションの全レコードを削除します。
列は残ります。
With関数
3行目以降のwith関数は、with()の中だけで使うことができる変数を{}内で宣言できます。
,
この例だとinputという変数を宣言しています。
inputの中身はテキストボックスに入力された文字列を改行コードで分割しています。
こちらを参考にさせていただきました。
繰り返し処理
ForAllは繰り返し文です。()内のデータソースの各レコードに対して繰り返し処理します。
VBAでいうところのForEachに相当します。
PowerAppsだと
ForAll(Distinct(input, Result),
いろいろな処理
)
VBAに書き換えると
For Each Result In input
いろいろな処理
Next
ということになると思います。
ForAllの対象となるデータソースはinputから重複を省いた内容です。
次のWith関数で各レコードをitemNumber変数へ格納しています。
Distinct(input, Result)
Distinct関数の第二引数に指定しているResultについて、恐らく、Split関数の戻り値のデータ型はテーブルでその列名がResultなんだと思います。
たぶん名前もResultで固定。
繰り返し処理の中身
If関数以降は、変数itemNuberが空でなければCollect関数でコレクションtotalへデータを追加しています。
If関数を入れている一番の理由は最終行が空の場合があり、商品番号が空の余計なレコードが追加されてしまうからです。
バーコードスキャナーの設定で「読み取る毎に改行を挟む」という設定ができるので、どうしても最終行が空となってしまいます。
ダサいよね。

CountIf関数
関数で第一引数のデータソースに対して、第二引数の論理式が真である件数を取得します。
論理式の左辺は重複を省く前のテーブル。
右辺は重複を省いた結果のテーブル。
データテーブルコントロールへ出力
あとはデータテーブルコントロールのItemsプロパティへ「total」コレクションを設定してあげれば完成です。
CountIf関数とは別の方法
Filter関数で一致するレコードだけを抽出して、そのレコード件数をCountRows取得すればOK。
CountRows(Filter(input, Result = itemNumber))
完成

もっとこんないい方法あるよ!とかあったら教えてください。