はじめに
PowerAppsで文字列操作の練習をするために、FWログの集計をしてみました。
実用性はなさそうです。
やりたいこと
以下のようなログがあった場合に、 10分区切りの同じ時刻において、ポートごとの、転送Byte数を算出する
'Receive Time' , 'Destination Port' , 'Bytes'
2020/04/01 10:13:00 , 22 , 100
2020/04/01 10:15:00 , 22 , 120
2020/04/01 10:43:00 , 23 , 30
2020/04/01 10:45:00 , 445 , 300
2020/04/01 10:48:00 , 23 , 80
2020/04/01 10:49:00 , 22 , 90
'Receive Time' | 'Destination Port' | 'Bytes' |
---|---|---|
2020/04/01 10:13:00 | 22 | 100 |
2020/04/01 10:15:00 | 22 | 120 |
2020/04/01 10:43:00 | 23 | 30 |
2020/04/01 10:45:00 | 445 | 300 |
2020/04/01 10:48:00 | 23 | 80 |
2020/04/01 10:49:00 | 22 | 90 |
これを以下のように表示させたい
LOG , 10:1X , 10:4X
22 , 220 , 90
23 , , 110
445 , , 300
LOG | 10:1X | 10:4X |
---|---|---|
22 | 220 | 90 |
23 | 110 | |
445 | 300 |
画面の準備
元ログを表示するラベル、集計ログを表示するラベル、集計ボタンを配置
元ログを表示するラベル
もとのデータソースをカラムごとに表示させるだけです。
元ログを表示するラベル.Text
Concat(ColDataSource,'Receive Time'&","&'Destination Port'&","&Bytes,Char(13)&Char(10))
集計ログを表示するラベル
集計ボタンで処理した結果を表示させるだけです。
集計ログを表示するラベル.Text
strLog
集計処理を行うボタン
ボタンが押されると処理が走ります。
集計処理を行うボタン.OnSelect
// 本チャンのデータソースを読み込む場合は、適当なコネクタを入れて、データを読み込みます。
// 今回はテスト表示なので、コメント
// ClearCollect(ColDataSource,[@FWlog])
// テスト用のログを設定
ClearCollect(ColDataSource,Table( { 'Receive Time': DateTimeValue("2020/04/01 10:13:00") , 'Destination Port': "22" , 'Bytes': 100 }, { 'Receive Time': DateTimeValue("2020/04/01 10:15:00") , 'Destination Port': "22" , 'Bytes': 120 }, { 'Receive Time': DateTimeValue("2020/04/01 10:43:00") , 'Destination Port': "23" , 'Bytes': 30 }, { 'Receive Time': DateTimeValue("2020/04/01 10:45:00") , 'Destination Port': "445" , 'Bytes': 300 }, { 'Receive Time': DateTimeValue("2020/04/01 10:48:00") , 'Destination Port': "23" , 'Bytes': 80 }, { 'Receive Time': DateTimeValue("2020/04/01 10:49:00") , 'Destination Port': "22" , 'Bytes': 90 } ))
//
// 集計対象とするデータソースを、以下の4つのカラムを持つコレクションにコピーします
// COLUMN : 横方向の要素(この場合、'Receive Time'の YYYY/MM/DD hh:mm:ss のうち、時刻の部分の先頭4バイト分、 )
// ROW : 縦方向の要素(この場合、'Destication Port')
// VALUE : 集計対象にする数値(この場合、'Bytes')
// SUM_TARGET: 集計対象を判断するための仮のカラム(COLUMNとROWをカンマ区切りにする)
//
;ClearCollect( ColLog,
ForAll( ColDataSource,{
COLUMN: Left(Text('Receive Time',ShortTime24),4)&"X" ,
ROW: Text('Destination Port'),
VALUE: Value('Bytes'),
SUM_TARGET: Left(Text('Receive Time',ShortTime24),4)&"X"&","&Text('Destination Port')
}
)
)
// ColLog_ALL_ROWs
// 期間中の行方向の全成分を単一列にまとめる
// ログに存在しない行方向の成分を含める場合は、ここに追加する
;ClearCollect( ColTemp,ForAll(ColLog,{ROW:ROW}))
;ClearCollect( ColLog_ALL_ROWs,
SortByColumns(
RenameColumns( Distinct(ColTemp,ROW) , "Result" , "ROW_check") ,
"ROW_check"
)
)
// ColLog_ALL_COLUMNs
// 期間中の列方向の全成分を単一列にまとめる
// ログに存在しない列方向の成分を含める場合は、ここに追加する
;ClearCollect( ColTemp,ForAll(ColLog,{COLUMN:COLUMN}))
;ClearCollect( ColLog_ALL_COLUMNs,
SortByColumns(
RenameColumns( Distinct(ColTemp,COLUMN) , "Result" , "COLUMN_check") ,
"COLUMN_check"
)
)
// ColLog_VALUEsum_PER_COLUMNs
// VALUEを合算したい対象カラム(SUM_TARGET)をグループ化して、SUMる
;ClearCollect( ColLog_VALUEsum_PER_COLUMNs,
AddColumns( GroupBy(ColLog,"SUM_TARGET","GROUP_SUM_TARGET"),
"TOTAL VALUE PER COLUMN" , Sum( GROUP_SUM_TARGET, VALUE ) ,
"COLUMN" , First(Split(SUM_TARGET,",")).Result ,
"ROW" , Last(Split(SUM_TARGET,",")).Result
)
)
// strLogに吐き出す
;Set(strLog,
// 最初の行はヘッダ
"LOG,"&Concat(ColLog_ALL_COLUMNs,COLUMN_check,",")&Char(13)&Char(10)&
// 行方向でループさせつつ、
Concat(ColLog_ALL_ROWs,
// -------------------> 列方向でループさせ
ROW_check & ","& Concat(ColLog_ALL_COLUMNs,
// --------------------------> 行&列が合致した集計済数値を表示させる
Text( LookUp(ColLog_VALUEsum_PER_COLUMNs,ROW=ROW_check&&COLUMN=COLUMN_check).'TOTAL VALUE PER COLUMN'),
"," ) ,
Char(13)&Char(10)
)
)
さいごに
これを、「CSVで出力」できるとうれしいのですが、Export/Importの機能は、コレクションをPowerAppsアプリ同士で交換するための機能のようで、強制的にJSONになっちゃうんですね。
単純なループの処理ができないので、とっても文字列操作がやりにくいですね。
果たしてこんな処理をPowerAppsの中でやる意味はあるのか。。。
まぁ、練習です。