...というタイトルを見ると、「なんだ、並列ステートの説明か」と思われるかもしれないが、僕はなるべくなら並列ステートを使いたくないし、極力シンプルに作りたいと常々思っている。
今回はちょっと変わったワザを使って実現してみる。
#まずはデータ作成
まずはデータ作成からいくね。
このコードはproductとamountにはなんの因果関係もないので悪しからず。
LET vCustomerCnt =100000;
LET vProductCnt = 10000;
LET vCategoryCnt = 10;
LET vTranCnt = 1000000;
LET vStoreCnt = 10;
LET vDateStart = 43831;
LET vDuration = 365 * 2;
Customer:
LOAD RowNo() as customer_id,
Hash128(RowNo()) as customer_name
AutoGenerate $(vCustomerCnt);
Product:
LOAD RowNo() as product_id,
'Product_' & RowNo() as product_name,
Ceil(RowNo()/$(vProductCnt)*$(vCategoryCnt)) as category_id
AutoGenerate $(vProductCnt);
Category:
LOAD RowNo() as category_id,
'Category_' & RowNo() as category_name
AutoGenerate $(vCategoryCnt);
Store:
LOAD RowNo() as store_id,
'Store_' & RowNo() as store_name
AutoGenerate $(vStoreCnt);
Transaction:
LOAD RowNo() as tran_id,
Date($(vDateStart) + Floor((Rand() * $(vDuration))),'YYYY/MM/DD') as date,
Ceil(Rand()*$(vCustomerCnt)) as customer_id,
Ceil(Rand()*$(vStoreCnt)) as store_id,
Ceil(Rand()*$(vProductCnt)) as product_id,
Mod(Floor(pow(Rand(),2)*10),3)+1 as unit,
Ceil(Sqrt(Rand()*10000000)) as amount
AutoGenerate $(vTranCnt);
MasterCalendar:
LOAD tmp_date as date,
Year(tmp_date) as year,
Month(tmp_date) as month,
Date(MonthStart(tmp_date),'YYYY/MM') as yearmonth;
LOAD
Date(mindate + IterNo()) as tmp_date,
maxdate
WHILE mindate + IterNo() <= maxdate;
LOAD min(FieldValue('date',RecNo()))-1 as mindate,
max(FieldValue('date',RecNo())) as maxdate
AutoGenerate FieldValueCount('date');
#簡単なチャートを作ってみる
上記のスクリプトから簡単な積み上げの棒グラフを作ってみる。
よくある商品カテゴリの売上推移をみるチャートだ。
このグラフを応用して、「2つの店舗でカテゴリ毎の売上推移を比較したい」というのが今回のお題。
store_nameで複数の店舗を選択すると、当然ながら2つの店舗の合計の売上が表示される。
積み上げ棒グラフを2つ作っても、さらにリストボックスを2つ作っても同じものが表示されるだけだから、このままではどうすることもできない。
そんな時には一般的には
- store_nameリストボックスA →StateA
- store_nameリストボックスB →StateB
のように並列ステート化してやりなさい-というのが一般的だ。
ここで面倒なのが、
- 店舗を1つしか選べないようにする
- 絞り込みが異なるのは店舗だけとして、その他の条件は全体のリストボックスで制御したい
など、余計な気を使わなきゃいけなくなることだ。
ただ、店舗を別々に選択して比較したいだけなのに...
#素敵なドロップダウンリストを作ってみる
QlikViewでドロップダウンリストを作成する最も簡単な方法はマルチボックスを使う方法だ。それ以外にもリストボックスを使用して条件付き表示で制御しながらドロップダウン風に見せるという方法もある。
今回はあまり一般的ではないが、フィールドの値を表示する入力ボックスでドロップダウンリスト表示を実現してみよう。
・入力ボックスを作成し、変数vStoreAをする。
・「制御」タブで上のように設定する。
通常リスト値を指定する時は、セミコロンで区切る。例えば
store_1;store_2;store_3
みたいに...
ここで、全部記述することはできないし、店舗は増えることもあるわけだから、できればフィールドの値を表示できないだろうかと考えるのが自然な流れだろう。
そこでその方法なのだが、こんなふうに数式で指定する。
=Concat({1} distinct store_name,',',SubField(store_name,'_',2))
【解説】
Concatを使用してユニークなstore_nameを抽出し、カンマ区切りで結合する。そうするだけで、ドロップダウンでstore_nameが表示されるようになり、ここで選択したものが vStoreAに入る仕掛けだ。
"SubField(store_name,'',2)"は何かというと、Concatする時のソート順であり、これを使用しないと
store_1
store_10
store_2
store_3
・
・
のように表示されるため、SubFieldを使用して、「store_nameを''で分割し、2番目の値でソートする」と指定している。
降順にしたければ、-SubField(store_name,'_',2) としてあげればいい。
上記の通りに入力ボックスができたら、チャート側の数式を以下のように変更する。
sum({$<store_name={$(vStoreA)}>} amount)
これで、ドロップダウンリストで指定した店舗のカテゴリ別の売上推移が表示されるようになる。
同様にvStoreBのドロップダウンリストを作成し、チャートの数式も対応させるとこうなる。
これで2つの店舗を別々に選択してカテゴリ別の売上の推移が比較できるようになった。
どうかなあ...
僕はこのやり方のほうがシンプルだと思うんだけどね。
入力ボックスのドロップダウンリストで、フィールドの値が使えると何かと便利だよ。