計算式プラグインで、テーブル内項目で計算式を指定するとテーブル行数が多いと処理時間が問題になるケースがあります。
その原因調査と対策を検討してみます。
概要
rex0220 計算式プラグイン テーブル内小計をテーブル行数を100行で検証
操作:分類を「明細」から「概要」に変更
処理時間(秒) | 対策 | |
---|---|---|
改善前 | 25 | |
対策1 | 45(+20) | テーブル内項目の計算式から集計関数を無くす |
対策2 | 4(-21) | プラグインの計算処理を非同期化し、無駄なイベント処理をスキップ |
対策3 | 2(-23) | 対策1+対策2。集計関数を無くしプラグインの計算処理を非同期化 |
-
対策1:テーブル内項目の計算式から集計関数を無くす
- 約45秒(+20秒 悪化)
- 集計関数の代わりにテーブルに項目を追加して、行単位の累計処理に変更
- 集計関数の処理時間が減ったが、値変更イベントが増加し、結果的に処理時間増加
- 対策2:プラグインの計算処理を非同期化し、無駄なイベント処理をスキップ
- 約4秒(-21秒 改善)
- 計算式プラグイン Ver.62 以降の「非同期計算」(ベータ版機能)指定
- 対策3:集計関数を無くし、プラグインの計算処理を非同期化し、無駄なイベント処理をスキップ
- 約2秒(-23秒 改善)
処理時間の調査
とりあえず地道に何に時間がかかっているか調べます。
主にかかっている処理時間
- テーブル内項目で集計関数を実行すると、秒単位で時間がかかる
- 集計関数: テーブル全行をループ処理で計算
- 金額の計算;LASTIF, SUMIF が集計関数を指定
.JS
LET(CNO,ROWNO(テーブル),
SWITCH(分類,
"明細",数量*単価,
"小計",LET(PNO,NVL(LASTIF(AND(ROWNO(テーブル)<CNO,分類="小計"),ROWNO(テーブル)),-1),
SUMIF(AND(ROWNO(テーブル)<CNO,ROWNO(テーブル)>PNO,分類="明細"),金額)),
"")
)
- 値変更イベントが多い
- 計算結果を他項目の計算で指定すると、値変更イベントで再計算する
- 数量、単価、金額の値変更イベントで再計算
※計算処理で設定した値によって、値変更イベントが発生するため、再計算しても結果は変わらない
対策1
テーブル内項目の集計関数の代わりに、セット累計金額を追加し累計処理に変更
改善前.js
// 金額
LET(CNO,ROWNO(テーブル),
SWITCH(分類,
"明細",数量*単価,
"小計",LET(PNO,NVL(LASTIF(AND(ROWNO(テーブル)<CNO,分類="小計"),ROWNO(テーブル)),-1),
SUMIF(AND(ROWNO(テーブル)<CNO,ROWNO(テーブル)>PNO,分類="明細"),金額)),
"")
)
対策1.js
// 金額
SWITCH(分類,
"明細",数量*単価,
"小計",NVL(SUBTABLE(セット累計金額,ROWNO(テーブル)-1),0),
"")
// セット累計金額
LET(w,NVL(SUBTABLE(セット累計金額,ROWNO(テーブル)-1),0),
SWITCH(分類,
"明細",TR_SUM(金額,w),
"小計",w,
"")
)
- 対策案1の影響
- 値変更イベント処理の増加: 結果的に処理時間が増加
- 追加項目の非表示処理
セット累計金額を非表示に指定してもテーブル行表示が完了するまで、イベント処理が実行されないため、セット累計金額がしばらく表示される。
※項目非表示プラグインを適用で、テーブル行表示完了前もセット累計金額を非表示にできます。
項目非表示プラグインの設定
対策2
プラグインの計算処理を非同期化し、無駄なイベント処理をスキップ
※計算式プラグイン Ver.62 以降(ベータ版機能)
- 対策案2の影響
- 計算処理のタイミングが変わる
- 従来: 項目の値変更の計算処理後に、カーソル移動
- 非同期: 項目の値変更でカーソル移動後に計算処理
- 他プラグイン等のイベント処理との競合
- 処理タイミングが変わることにより、他プラグイン等へ影響が考えられます。
- 計算処理のタイミングが変わる
対策3
対策1と対策2を適用することで処理時間を削減できますが、影響も同様に発生します。
まとめ
テーブル行数が多い場合は、対策2の非同期計算を実施することで、処理時間を改善できそうです。
ただし他プラグイン等への影響を検証する必要があります。
実用的には、対策3の方が使いやすいと思いますが、項目追加などの手間が必要ですので、要件に合わせて検討。