タグ別アーカイブ: DAX

コンテキスト遷移~DAXの何故こうなるのか?を解決する~

【このコンテキスト遷移の理解がDAX自体の理解の近道です】

DAXを使用していて「何故こうなるの?」ということに出会うことがあります

「何故こうなるの?」の不思議の一つが「コンテキスト遷移」です

早速、事例で見てみましょう

上の画像の2つの列は「大阪」で値が2300と1200と言う風に違いがあります

実際にメジャーの中身を見ると些細な違いしかありません

・MAXX_NoCal

  MAXX_NoCal = MAXX(‘担当者’,SUMX(‘売上’,’売上'[金額]))

・MAXX_withCal

  MAXX_withCal = MAXX(‘担当者’,CALCULATE(SUMX(‘売上’,’売上'[金額])))

MAXXの第二引数にCALCULATE関数があるかないかだけです

ところが、このCALCULATE関数のあるなしがとても大きいのです

CALCULATE関数があるメジャーは2300⇒1200となり、何らかの形でデータの絞り込み(フィルター)が行われています

今回の記事ではこの絞り込みが有効になる「コンテキスト遷移」の仕組みについて解説していきます

DAXで計算したいこと

今回は2つのテーブルを使用します

1つ目は担当者のテーブル、2つ目は売上テーブルです

売上テーブルは同一担当者が複数登場しています

DAXを使用して、この2つのテーブルを組み合わせて、東京と大阪で最大の売上をあげた担当者の金額を計算します

MAX関数での計算

「東京と大阪で最大の売上・・・」というように「最大」というキーワードが出てくるので、MAX関数を使用するのでは・と思った読者の方も多いと思います

では早速、MAX関数で計算してみましょう

MAX = MAX(‘売上'[金額])

そうすると上の画像のように、思ったよりも小さい金額算出されます

これはそもそも集計の単位が違っています

ですので、まずは担当者テーブルで新しい列を作成し、担当者別に売上金額を算出してみます

新しい列で担当者別の売上を算出した上で、MAX関数を使用してみます

これで意図とした通りの結果が出ました

ポイントは新しい列を作成する時、CALCULATE関数を使用していることです

画像に alt 属性が指定されていません。ファイル名: image-63.png

仮に、上の画像のCALCULATE関数を取り除いたらどうなるでしょうか?

全ての行の合計が算出されてしまいます

つまり、CALCULATE関数を使うことで遷移(全ての行⇒行別)が起こっているのです

MAXX関数/行評価

上のMAX関数の事例ではメジャーを作成するまえに、新しい列を作成しました

今度はMAXX関数を使用して、直接メジャーで担当者ごとの最高金額を大阪と東京で算出したいと思います

MAXX関数では単純に最大値を算出するのではなく、行別に式を評価した上で最大値を算出します

他の言葉で言い換えると、条件に合う「行の中」で最大値を算出してくれます

ちなみに、大阪と東京の合計金額は次の画像のようになっています

では、話を戻してMAXX関数を実際に使用して大阪と東京の担当者別の最大値を算出してみましょう

通常の合計金額と同じ結果になってしまっています

つまり、大阪もしくは東京という「行別」だけが考慮された計算金額になってしまっています

MAXX関数の第一引数はMAXX(’担当者’となっているのに「担当者の行別」は考慮されていません

これは、前に例に挙げた下の画像と同じ現象が起こっています

画像に alt 属性が指定されていません。ファイル名: image-65.png

この時はCALCULATE関数を使用して「行別への遷移」を起こしました

実は、今回も同じようにCALCULATE関数を使用すれば正しく算出されます

CALCULATE関数を使用することで、今回もMAXX関数内で「行別への遷移」を起こしているわけです

これで、DAXは何故こうなるのか?の謎が一つが解けたと思います

メジャー使用による行評価

番外編として、次の事例も紹介したいと思います

上の画像の一番右の式はCALCULATE関数を使用していません

MAXX_NoCal_withMEASURE = MAXX(‘担当者’,[売上合計])

その代わり、第二引数に[売上合計]というメジャーを使用しています

ですが、CALCULATE関数を使用したのと同じ結果がでています

これはメジャーを使うこと自体で、CALCULATE関数を使用するのと同等の効果があることを意味します

たとえメジャーの中身と同じ内容を関数の引数で使用しても、違う結果が出てしまうのはこの為です

<まとめ>

今回はCALCULATE関数を使用して、行別の評価を関数内で受け渡す「コンテキスト遷移」について解説しました

この概念を理解すると、格段にDAXの活用の幅が広がります

ぜひマスターしておきましょう!!

にほんブログ村 資格ブログ ビジネススキルへ

にほんブログ村

にほんブログ村 IT技術ブログ VBAへ

脱エクセルについて考える~資金繰り表をPower Platformで作成~第9回

【エクセルは本当に便利なツール。但し、効率と効果を上げるには限界があります】

資金繰り表はエクセルに向いている業務の典型です

それは何故か?

上の画像の黄色のセルには数式が入っており、預金残高の予想残高を計算しています

但し、この数式を必要に応じて実際の預金残高「数値」で上書きすることができます

実はこれってエクセル以外のソフトだと難しいんです

「数式」と「数値」を共存できるエクセルは本当に便利なんです

ではエクセルで業務を続けていたらそれでいいのか?

それはそれで問題があります

下の画像の「2023/1/5」の売上高の欄には120と入っています

入力数字は120でも、実は120という数字を別な表で複数の顧客の数字を積み上げて入力されているかもしれません

それに、表に存在する日付/列単位が膨大になってくると、入力箇所を見つけるのも面倒です

つまり量が膨大になってくると、この資金繰り表の1セルを入力する作業がかなり面倒になってきます

その理由は一般的なエクセルの資金繰り表では「データ蓄積」「作業」「計算」「表示」が分かれていないからです

ですので、作業や計算スペースを作る関係上、データの並びが不規則になってしまったりしますし、入力しやすいようなスペースを作ることも困難です

更に言えば、資金繰り表のシートのデータを活用して他のシートで別の目的の表を作成しようとするとかなり複雑なものになってしまいます

実は、Power BIのDAXを使用すれば預金口座の残高も、実残高と予想残高を共存させながら計算できます

今回の記事ではPower BIPower Appsを使用して、エクセルの資金繰り表の「データ蓄積」「作業」「計算」「表示」を分けて管理できる仕組みの概要を紹介します

そして、Power Platformの便利さに触れて頂けたら幸いです

ポイント

Power Platformを使って資金繰り表を作成するには、分解が結合がポイントです

データの分解・結合

預金残高は数式と数値を共存できるように、以下にデータを分けて管理します

・預金残高(実残高)

・入金

・出金

更にカレンダーテーブル

上記の4つをDAXで結合して使用します

今回はSharepointリストを使用します

入出力と表示の分解

今回は入出力はPower Appsで行います

Power Appsならページを分けて、売掛金や経費などの入出力専用ページを作成できます

そして、表示や主な計算はPower BIで行います

Power BIは集約計算の簡単にできるし、DAXで複雑な計算も行えますので、Power BIの機能もフル活用します

エクセルで日付毎に複数の顧客の売掛金を合計していた作業は、前述のテーブルを作成しておけば勝手にPower BIが行ってくれます

入出力と表示が分かれていると不便だろうという場合は、後述するPower BI内でPower Appsを使う方法もあります

預金残高を表示するDAXの作成

ここがエクセルの資金繰り表を他のソフトで行う最大の難所です

日付の管理がとても重要です

・実際に預金残高を入力した日付の残高⇒そのまま残高を表示

・預金残高を入力していない日付の残高⇒実際に預金口座を入力した日付以降の入出金を加味して計算

例えば、1月1日の残高が100、1月2日の入金が100、1月3日の出金が100だったとします

この場合は

1月1日残高⇒100/実績残高

1月2日残高⇒200(100+100)/予想残高

1月3日残高⇒100(100+100ー100)/予想残高

となります

こちらを実際にDAX式に直したのが以下です

*CashBalance:実際の預金残高、Receipt:入金、Disbursement:出金

預金残高 =  

VAR currentDay=MAX(‘Calendar'[Date]) 

VAR maxDay=CALCULATE(MAX(‘CashBalance'[Date]),FILTER(All(CashBalance),’CashBalance'[Date]<=currentDay)) 

VAR cashAmount=SUMX(FILTER(ALL(‘CashBalance’),’CashBalance'[Date]=maxDay),’CashBalance'[CashBalance]) 

VAR cashReceipt=CALCULATE(SUM(‘Receipt'[Amount]),FILTER(All(‘Receipt’),’Receipt'[Date]>maxDay &&’Receipt'[Date]<=currentDay)) 

VAR CashDisbursement=CALCULATE(SUM(‘Disbursement'[Amount]),FILTER(All(‘Disbursement’),’Disbursement'[Date]>maxDay &&’Disbursement'[Date]<=currentDay))

RETURN cashAmount+cashReceipt-cashDisbursement

今回の記事では詳細には解説を行いませんが、一見複雑なこの式の最大のポイントは「預金残高の最大日付:maxDay」を算出することです

冒頭のたとえを使って説明すると、今日が1月3日だとしたらその前に預金残高がテーブル:CashBalanceに貴重された日付の1月1日を算出するということになります

最大日付が算出できれば、おのずと入金金額を算出する期間と出金金額を算出する期間が求まります

ただ実際には、フィルターを意識してAll関数をうまく組み合わせていく必要があります

専用アプリによる預金残高表示

Power BIには様々なアプリ/ビジュアルがあります

今回は資金繰り表に活用できるビジュアルを1つ紹介します

その他のビジュアルの取得をクリックして「Calendar」と検索してください

すると「Beyondsoft Calendar」というビジュアルをダウンロードできます

こちらのビジュアルは日々の預金残高をカレンダー上で表示できるという優れものです

残高の状態によって色を変えたりもできます

エクセルではなくPower BIを使用することで、専用アプリを活用することもできるんです

Power BIとPower Appsの連携

Power AppsをPower BI内で使用したい場合は、こちらをクリックするところからはじめます

すると、Power Appsに使用するフィールドの入力ができるようになります

実は、こちらはなんでも構わないんです。取り合えば何か設定すればPower BI内で表示したいPower Appsのアプリを選択できるようになります

<まとめ>

今回は脱エクセルについて考えると称して、エクセルの資金繰り表をPower AppsとPower BIを連携させて作成する方法の概要を紹介しました

紹介したのはあくまで概要ですが、エクセル作業が改善されていく可能性を感じて頂けたら幸いです

現実に、エクセルは表計算ソフトですので大量のデータを処理するには向いていません

なので、Power PlatFormの仕組みを利用して「データ蓄積」「作業」「計算」「表示」を分解・結合できるようにすることはとても意義があります

そうは言っても、誰でも手軽に使えるエクセルと違ってPower BIのDAXなどが複雑であったりするので専門知識が必要です

それに当然、手間暇も必要です

ですので、最終的にはどの程度の量の業務をどんな風に変えたいかが一番のポイントなのかもしれませんね

にほんブログ村 資格ブログ ビジネススキルへ

にほんブログ村

にほんブログ村 IT技術ブログ VBAへ

購入会員の使用金額によるランク分け&ランク別使用額の分析

【エクセルの煩雑な作業不要のまま、数字の裏側にあるストーリーを炙り出せます!!】

今回の記事では、Power BIで売上金額を購入会員のそれまでの使用金額別に前期と比較できるようにします

*上記の使用ランクは年間の金額ランク付けを行っています

購入会員に使用金額のラベルを付けて比較できるようにすることで「売上の増減の原因」「売上の傾向」を分析するのに有用な示唆を得ることができます

この方法のいいところは、気になるところをラベルから辿って深堀できることです

例えば、年間2万円未満の層が減っていると思ったらフィルターで2万円の層の会員番号にアクセスすることができます

しかも、分析作業はエクセルで行うことを考えたら遥かに楽です

エクセルで同じことをおこなおうとしたら、ユニークな会員番号及び使用金額、注文数などを数シートに抽出した上で紐づけ処理を行うしかありません

今回の記事の内容を一言で言い換えるとセグメント分析の方法の解説です

ぜひセグメント分析を効率化して、有用な分析を継続していきましょう!

使用データ

今回使用するのは注文データのみです

会員別データは使用しないまま作業を行えるようにします

*Calendarテーブルも使用します

最終的には、会員別に各値を集計したテーブルを作成します

ポイント

今回のポイントは時系列での日付整理です

日付を整理したうえで、各データを抽出して組み合わせる形になります

・使用月の開始日、終了日

・使用月前の1年間(判定期間)の開始日、終了日

時系列での日付整理にはEOMONTH関数を使用します

この関数を使用して、使用する各日付を変数に設定しておきます

今回の記事では2022年4月(と前年同月の2021年4月)を分析します

分析テーブル作成

SUMMRIZE関数

上記の各日付を使用し、前述のようなテーブルを作成します

画像に alt 属性が指定されていません。ファイル名: image-42-644x151.png

このテーブル作成は、SUMMRIZE関数を使用します

但し、画像右の「使用ランク」「月」は後から列を足します

SUMMRIZE関数のグループ化の切り口は「当月使用した会員番号」になります

こちらについては、変数でCALCULATETABLEを使用して事前に作成しておきます

VAR myTable=      CALCULATETABLE
        (

          VALUES(OrderData1[Customer ID]),            

          ‘Calendar'[Date]>=DATEVALUE(firstDay),’Calendar'[Date]<=DATEVALUE(endDay)
             )

この時に、会員番号の抽出範囲を時系列で整理した日付(firstDay、endday)を使用して指定するのもポイントの一つです

ここからはFILTER関数でうまく抽出範囲を指定しながら、SUMMRIZE関数の各列を作成します

次が実際の数式です

RETURN 

  SUMMARIZE( 

①FILTER(‘OrderData1’,’OrderData1′[Customer ID] in myTable),

②’OrderData1′[Customer ID],   

③ “当月使用金額”, 

④  

SUMX(FILTER( ‘OrderData1’, 

    ’OrderData1′[Purchase Date]>=DATEVALUE(firstDay) && ‘OrderData1′[Purchase Date]<=DATEVALUE(endDay)

            ),   

     ‘OrderData1′[Price]*’OrderData1′[Quantity]

  ),   

⑤ “年間使用金額”,   

 SUMX(FILTER(‘OrderData1’, 

           ‘OrderData1′[Purchase Date]>=firstDay_Year && ‘OrderData1′[Purchase Date]<=endDay_Year

            ),         

   ’OrderData1′[Price]*’OrderData1′[Quantity]

    ),     

⑥”年間注文数”,   

 COUNTROWS( FILTER( ‘OrderData1’,

                ’OrderData1′[Purchase Date]>=firstDay_Year && ‘OrderData1′[Purchase Date]<=endDay_Year

            ) 

   ) 

  )

ここから上の数式のポイントだけを抜粋して解説します

①では使用元のテーブル指定しますが、「in」を使用して当月の会員のみの注文データ(myTable)に絞り込みます

②ではグループ化、集約の切り口を指定します

③④では、SUMX関数を使用して判定期間(当月前)の使用金額を抽出します

⑤⑥では、COUNTROWS関数を会員毎の判定期間での注文数を抽出します

IF関数

SUMMRIZE関数でテーブルを作成したら、IF関数でラベル分けを行います

IF関数は「新しい列」で追加します

IF関数の条件式(金額)はビジネスの状況に応じて適したものにする必要があります

こちらはあくまで事例です

使用ランク = IF(ISBLANK(‘2022年4月購入者分析'[年間使用金額]),”1.新規”,if(‘2022年4月購入者分析'[年間使用金額]<20000,”2.2万未満”,”3.2万以上”))

もし、前年のテーブルも作成して1つのマトリックス表の中で比較したい場合には、UNION関数で2つのテーブルを一緒にします

その際、テーブル内で各テーブルが区分できるように、各テーブルに「月」の列を追加しておきましょう

<まとめ>

今回は年間の使用金額でセグメント分析する方法を解説しました

様々なDAX関数を使用しますが、一番ポイントとなるのは「EOMONTH関数」で当月、判定期間(年間)の関連日付を整理することです

ぜひこの点は意識していきましょう

最後に、

今回の手法を使うと会員分析の精度は格段に上がります

更に精度を上げるには継続的に分析を行い、会員ランクの見直しやランク別の特徴の蓄積を行うことです

できたら、ランクを更に分解して「購入商品別」にも分類できるようにすると、もっと分析の精度が上がります

にほんブログ村 資格ブログ ビジネススキルへ

にほんブログ村

にほんブログ村 IT技術ブログ VBAへ

グラフの並び順を変える3つの方法~条件列、DAX、リレーション~

【グラフのX軸が思うように並んでくれない、そんな悩みは今回の記事で解決できます】

Power BIのグラフの並び変更は、通常だとグラフの右上の三点リーダーをクリックした後に下記の画像の箇所で変更します

今回は上の並べ方では解決できない場合の対処方法を3つ紹介します

いずれの方法もデータビュー画面・列ツールにて「列で並べ替え」機能を使用します

まずは「1.並び変えたい列を選択」した後「列ツール」の「列で並べ替え」にて、「2.順位を記述した列」を指定します

読者の方の中には「その方法は知っている、だけどDAXを書くとエラーになった」という方もいらっしゃると思います

今回の記事ではエラーを回避する方法も解説しています

やりたい事

今回使用するデータは次の画像のデータです

こちらの商品の並びを次のようにします

A⇒B⇒C⇒D⇒E ➡ C⇒D⇒E⇒A⇒B

DAX1

一つ目の並べ替え方法はDAXのSwitch関数で変える方法です

下は別データで並び変えた事例です

*過去記事⇒こちら

上の画像ではMONTHの並び順を1月ではなく、4月からはじまるように変えています

では、今回の場合はどうかというと、次のようなSwitch関数の式を書きます

ところが、今回の場合は実際に並び替えるとエラーが発生します

前述の月の並び替えの場合は、並び替え対象が「MONTH列」で順位列の式が「順位 = Switch(MONTH([Date]),1,10,・・・」となっています

つまり、Switch関数の中身が「並び替え対象」ではなく「Date列」となっています

今回の場合は、Switch関数の中身に「並び替え対象」が入っています

順位_DAX = SWITCH(‘Data'[商品],・・・

ですので、次のようなエラーがでます

これはSUM関数をSUM関数の対象範囲に含めるような形になります

ですので、今回は別な方法も紹介します

条件列

Power Queryエディタ画面で条件列を作成する方法も使えます

この条件列にて順位を指定すると次のようなグラフになります

別テーブルを手動で作成(DAX2)

最後に紹介する方法はこちらの画面:データの入力でテーブルを作成します

内容はこんな形で入力します

こちらで作成したテーブルはリレーションも組んでおきます

次にデータビュー画面でDAX(RELATED関数)を作成し、順位列を作成します

この順位列であれば循環の問題は発生しません

<まとめ>

今回は、グラフの並び順を変える方法を3つ紹介しました

DAXで順位列を作成する場合には「循環参照」の問題は常に意識しておきましょう

個人的にはPower Queryエディで条件列を作成するより、DAXで作成した方が手軽だと感じています

にほんブログ村 資格ブログ ビジネススキルへ

にほんブログ村

にほんブログ村 IT技術ブログ VBAへ

複数のメジャーを集約して分かりやすくまとめる方法

【複数のテーブルに散らばったメジャーを分かりやすく1つのテーブルに集約します】

メジャーを作成していたら、いろんなテーブルに散らばってわからなくなった・・・そんな経験はないですか?

今回の記事ではメジャー専用のテーブルを作成してまとめる方法を解説します

テーブルの手動作成

まず最初に複数メジャーのまとめ先になるテーブルを作成します

テーブルの作成は手動で行います

次に開いた画面では、ダミーデータを入力します

列名を指定したりする必要はありません

どのみち、後で削除します

但し、テーブル名は指定してください

メジャーの選択

前述の手動で作成したテーブルに複数メジャーを移動します

移動の指定は「モデル」画面で行います

モデル画面の右にあるデータで移動元のメジャーをまとめて選択します

各テーブルにて3点をクリックすると「メジャーの選択」があります

このメジャーの選択をクリックすると、該当テーブル内のメジャーをまとめて選択できます

メジャーの移動

次に選択したメジャーの移動先を「プロパティ」欄の「ホームテーブル」で指定します

テーブルの整理

最初にダミーで入力したデータは消去しておきます

<まとめ>

今回は、複数のメジャーを一つのテーブルにまとめて整理する方法を解説しました

今回の記事のように常にメジャーは分かりやすく一か所にまとめておくと他の人も分かりやすいので、常に「メジャーテーブルの作成」は行っておきましょう!

にほんブログ村 資格ブログ ビジネススキルへ

にほんブログ村

にほんブログ村 IT技術ブログ VBAへ

DAXを使用して注文数毎に会員を分類する~会員のセグメント~

【IF式をわざわざ重ねなくても、DAXを使用すれば注文数で会員をセグメントできます】

下の画像のようなデータから会員/Customer_IDを注文数でセグメントする場合はIF式やピボットテーブルを組み合わせる必要がありました

OrderData1

DAXとパラメーターを使用すれば、簡単にセグメントが行えます

ポイント

今回は注文データからセグメントを行いますので、一旦、SUMMARIZE関数を使用して会員番号毎に注文数を紐づけるテーブルを作成するのがポイントです

上記のテーブルからFILTER関数を使い、注文数毎に会員数を集計します

パラメーターの作成

まずはFILTER関数内で、注文数のフィルターに使用するパラメーターを作成します

次の画像で、フィルターに設定する数値範囲を設定します

上記の数値範囲を設定すると2つのものが作成されます

1つは数値範囲を設定したテーブルです

もう一つはメジャーです

こちらのメジャーをFILTER関数内で使用します

セグメントをするメジャーの作成

顧客別注文数 =

①VAR CustomerOrders=   

SUMMARIZE(

‘OrderData1’,

OrderData1[Customer ID], 

“注文数”, 

COUNT(OrderData1[Order ID])

)

RETURN

②COUNTROWS(   

FILTER(

CustomerOrders,

[注文数]=③[パラメーター 値]

)

)

③は前述のパラメーターを作成した時のメジャーになります

画像に alt 属性が指定されていません。ファイル名: image-33-644x63.png

パラメーターで設定した値(1~10)毎(行毎に)に会員を抽出する形になります

FILTER(CustomerOrders,[注文数]=③[パラメーター 値])

会員を抽出したら②の「COUNTROWS関数」でセグメント毎の会員数を集計します

マトリックスの作成

最後にマトリックスを作成します

行には下の画像のパラメーターを使用します

画像に alt 属性が指定されていません。ファイル名: image-32.png

<まとめ>

今回は注文データから、注文数で会員をセグメントしたデータを作成します

エクセルのワークシートで行おうとすればIF関数やピボットテーブルを組み合わせる必要があります

DAXを使用する場合は、FILTER関数をうまく使えば簡単に行えます

にほんブログ村 資格ブログ ビジネススキルへ

にほんブログ村

にほんブログ村 IT技術ブログ VBAへ

DAXを使いコホート分析~顧客のリピート状況を把握~

【もしエクセルで行おうとしたら、非常に手間なリピート状況の把握をDAXを使用して一発で解決】

前回は、新規と既存をDAXで集計しました。今回は同じ条件で顧客を並べた上でリピート状況をDAXで把握できるようにします!

上の画像のマトリックス表では、縦に顧客を初回受注月で並べ、横は初回受注月の経過月(1~12)別にリピート率を並べています

下の上の画像のズームアップを見てください

例えば、初回の受注月が2019年4月だった会員がもし100名いたとしたら、その100名のうち次の月に受注があったのは33名ということになります

このマトリックス表を作成することで、単に金額の増減を把握するだけではわからない、具体的な増減の要因をつかめるようになります

使用データ

使用するデータには、会員別の受注データを使用します

OrderData

ポイント

作成は3段階になります

1段階目で、新しい列を追加します

OrderData

会員毎の初回受注日を抽出する列を作成し、前述のマトリックス表の縦軸にします

2段階目で横軸にする連番をテーブルで作成します

3段階目でリピート率を計算するDAXを作成します

こちらのDAXは1段階目、2段階目で作成した縦横の軸を組み入れます

会員毎の初回受注日の抽出

CALCULATE関数とMIN関数を使用して、会員毎の初回受注日を抽出する列を作成します

CALCULATE関数の第二引数の条件にはFILTER関数を使用して、会員毎のテーブルを繰り返し作成し、会員毎の初回受注日を繰り返し抽出します

ただリピート率の計算は月単位で行うので、最小受注日は月末に揃えます

月末に揃える作業はEOMONTH関数を使用して行います

FirstOrderDate =

①VAR CurrentCustomer=’OrderData'[会員番号]
RETURN
②CALCULATE(

EOMONTH(MIN(‘OrderData'[受注日]),0),

FILTER(‘OrderData’,’OrderData'[会員番号]=①CurrentCustomer)

)

EOMONTHは第二引数に0を指定することで、第一引数の日程の月末日を抽出します

連番テーブルの作成

マトリックス表の横軸になる連番(0~12,増分は1)を作成します

こちらは新しいテーブルの作成となります

テーブルの作成にはGENERATESERIES関数を使用します

MonthAfter = GENERATESERIES(0,12,1)

リピート率を計算するDAXの作成

変数の作成

まず縦横の位置を変数で指定します

A: VAR CurrentMonthAfter=SELECTEDVALUE(MonthAfter[Value]) 

B: VAR CurrentFirstMonth=SELECTEDVALUE(OrderData[FirstOrderDate])

マトリックスの位置の行を抽出

テーブル:OrderDataから前述のAとBを組み合わせた位置に該当する行を、FILTER関数を使用して抽出します

この時に、EOMONTH関数を使用して月末日に揃えて行を抽出するのもポイントです

FILTER(‘OrderData’, EOMONTH(‘OrderData'[受注日],0)=EOMONTH(B: CurrentFirstMonth,A: CurrentMonthAfter))

CALCULATE関数による会員数抽出

上記のFILTER関数により抽出した行から、CALCULATE関数とDISTINCTCOUNT関数を使用して該当する会員数を抽出します

 CALCULATE(         

DISTINCTCOUNT(‘OrderData'[会員番号]), 

FILTER(‘OrderData’,

EOMONTH(‘OrderData'[受注日],0)=EOMONTH(CurrentFirstMonth,CurrentMonthAfter)

) ),

DIVIDE関数による率の計算

DIVIDE関数によって、分子:マトリックスの位置の会員数と分母:全体の会員数(実際には行でフィルターされる)で割ります

CustomerRetension% =  

A: VAR CurrentMonthAfter=SELECTEDVALUE(MonthAfter[Value]) 

B: VAR CurrentFirstMonth=SELECTEDVALUE(OrderData[FirstOrderDate])

RETURN  

DIVIDE(   

CALCULATE( 

DISTINCTCOUNT(‘OrderData'[会員番号]),

FILTER(‘OrderData’,

EOMONTH(‘OrderData'[受注日],0)=EOMONTH(B: CurrentFirstMonth,A: CurrentMonthAfter) 

),

DISTINCTCOUNT(OrderData[会員番号]) 

)

マトリックスの作成

実際にマトリックス作成の際には、2つの作業を事前に行います

日付の変更

個人の好みにもよりますが、そのままですと縦軸の初回の受注月はJan、Febなどの英語名になります

ですので、事前に日付を変換しておくことをお勧めします

仮メジャーの作成

マトリックスの「行」には上記の画像のFirstOrderDate、もしくは変換した内容、列には2段階目で作成した0~12の連番を指定します

値には普通にいけば、リピート率を配置します

ただ、このケースの場合には一旦、仮で作成したメジャーを一旦配置します

この仮メジャーを配置した後、リピート率を計算するDAXを配置します

<まとめ>

今回の記事では、初回受注月で会員を並べ、横軸に経過月毎にリピート率を並べるコホート分析のためのDAXの作成方法を解説しました

実際の作成はマトリックスの縦軸、横軸と値の3段階で行います

DAX関数は様々な関数を組み合わせて作成しますが、特にFILTER関数をどう使うかがポイントとなります

FILTER(‘OrderData’,’OrderData'[会員番号]=①CurrentCustomer)

FILTER(‘OrderData’,

EOMONTH(‘OrderData'[受注日],0)=EOMONTH(B: CurrentFirstMonth,A: CurrentMonthAfter) 

上記2つのFILTER関数はCALCULATE関数と組み合わせますが、この組み合わせは色々な場面で使用できるのでぜひ覚えておきましょう!

にほんブログ村 資格ブログ ビジネススキルへ

にほんブログ村

にほんブログ村 IT技術ブログ VBAへ

DAXを使い一発で新規顧客・既存顧客別に会員数と金額を集計する

【売上金額が単に増えた減ったとは別に新規と既存の切り口があると、金額の増減をストーリーで語れます】

数字の増減の理由を聞かれた時に、返答に困ったことはありませんか?

なかなか数字の増減の理由をつかめないのは、原因がずっと前に起こっていることもあるからです

例えば、ある企業の売上金額の80%が僅か顧客の20%から生まれていたとします

この優良顧客の離脱率は完全に0にはできません

しかも獲得した顧客もすぐに優良になるわけではありません。優良顧客になるまでに時間はかかるものです

優良顧客が離脱するペース以上に新規顧客を獲得して成長させないと売上は維持できません

ですので、新規顧客の獲得の減少が後々売上に響くこともあります

逆に新規顧客と既存顧客に分けた切り口で集計ができると、中長期期間での分析がしやすくなります

ところが、この新規既存の集計はエクセルのワークシートで行おうとすると猛烈に時間がかかります

今回の記事では、DAX一発で新規既存の数字を集計できるようにします

なお、新規と既存の切り口は売上金額の分析でなくても、在庫分析などでも活用できます

ポイント

新規と既存の違いとは何か?この定義がとても重要です

初回購入とはまた違いますので、その点は明確に意識しておきましょう!

次の図を見てみてください

対象期間より前に購入があった会員は新規と既存、どちらに区分されるでしょうか?

これは既存に区分されます

この「対象期間より前」の定義を数式で表すと次のようになります

<MIN(対象期間)

この数式を活用して既存会員をDAXで表現します

逆に新規はどう表現するか?

全会員-新規会員

上記で表現できますので、既存会員を式で表すことができれば難しい式を使う必要はありません

使用データ

使用するデータは次のデータになります

テーブル名:myData

横の軸は会員番号別の軸になります

4月1日から4日まで新規会員を1会員づつ獲得しており、新規会員からの金額は1日100となっています

上記のテーブルはPower BI内に取り込んだ後、ピボット解除で変換した上で使用します

尚、上記は売上データから新規・既存を集計しますが、会員データを別途作成しておくともう少しDAX式が簡単になります

会員データと売上データの間にリレーションを作成したうえで、DAXを使用する方法も少し紹介します

使用DAX(抜粋)

VALUES関数

今回のDAXではVAR/変数を使って複数のDAX関数を組み合わせます

その中の一つがVALUES関数です

VALUES関数はテーブル操作関数なので「新しいテーブル」を作成できます

上の画像では、全会員をテーブル化しています

CALCULATETABLE関数

こちらの関数はテーブル式をフィルター評価する関数です

CALCULATETABLE_NewTable = CALCULATETABLE(VALUES(myData[会員番号]),’myData'[日付]=MIN(‘myData'[日付]))

上のVALUES関数に加えて、フィルターを加えています

今回の記事では、この関数を使用して既存会員をテーブル化します

新規会員数

ポイントで前述したように、全会員から既存会員を引いたのが新規会員となります

NewCustomers =  
VAR CurrentCustomers= Values(myData[会員番号]) 

VAR CurrentDate=Min(myData[日付]) 

VAR OldCustomers=CALCULATETABLE(VALUES(myData[会員番号]),ALL(myData[日付]),myData[日付]<②CurrentDate) 

VAR NewCustomers=EXCEPT(①CurrentCustomers,③OldCustomers)

⑤RETURN COUNTROWS(④NewCustomers)

解説

①新規・既存会員を含めて全会員をリスト化します

②対象期間の最小日付、つまり新規と既存の境目となる日付を算出します

③②で算出した最小日付を基にして既存会員をテーブル化します

④①の全会員から③の既存会員をEXCEPT関数により差し引いて新規会員をテーブル化します

⑤COUNTROWS関数により、NewCustomersテーブルから新規会員数を出力します

既存会員数

上記の新規会員数を算出するDAX関数の一部を省略するだけです

OldCustomers =

① VAR CurrentCustomers= Values(myData[会員番号]) 

②VAR CurrentDate=Min(myData[日付]) 

③VAR OldCustomers=CALCULATETABLE(VALUES(myData[会員番号]),ALL(myData[日付]),myData[日付]<②CurrentDate)

④RETURN COUNTROWS(③OldCustomers)

新規会員金額

新規会員数を算出するDAXの最後のRETURNを変更します

 SUMX(NewCustomers,CALCULATE(SUM(myData[金額])))

SUMX関数を使用するのですが、第二引数でCALCULATE関数を使用することでNewCustomersテーブルの1行1行*を計算させるのがポイントです

行評価

NewCustomersAmount =

①VAR CurrentCustomers= Values(myData[会員番号]) 

②VAR CurrentDate=Min(myData[日付]) 

③VAR OldCustomers=CALCULATETABLE(VALUES(myData[会員番号]),ALL(myData[日付]),myData[日付]<CurrentDate) 

④VAR NewCustomers=EXCEPT(CurrentCustomers,OldCustomers)

⑤RETURN     SUMX(NewCustomers,CALCULATE(SUM(myData[金額])))

既存会員金額

OldCustomersAmount =  

①VAR CurrentCustomers= Values(myData[会員番号]) 

②VAR CurrentDate=Min(myData[日付]) 

③VAR OldCustomers=CALCULATETABLE(VALUES(myData[会員番号]),ALL(myData[日付]),myData[日付]<②CurrentDate)

④RETURN SUMX(③OldCustomers,CALCULATE(SUM(myData[金額])))

会員データを使用するパターン

使用する会員データは次の通りとなります

新規会員数

NewCustomers =  

①VAR CurrentDates=VALUES(myData[日付])               

②RETURN COUNTROWS(FILTER(‘CustomerFirstSale1’,’CustomerFirstSale1′[最小] in ①CurrentDates))

既存会員数

OldCustomers =

①VAR CurrentDates=VALUES(myData[日付])

②VAR CurrentCustomers=COUNTROWS(VALUES(myData[会員番号]))

③VAR NewCustomers=COUNTROWS(FILTER(‘CustomerFirstSale1’, ‘CustomerFirstSale1′[最小] in ①CurrentDates))    

④RETURN ②CurrentCustomers-③NewCustomers

新規会員金額

NewCustomersAmount =

①VAR CurrentDates=VALUES(myData[日付]) 

②RETURN SUMX(FILTER(‘CustomerFirstSale1’,’CustomerFirstSale1′[最小] in CurrentDates),’MeasureTable (2)'[SalesAmount]*)

*事前にSUM関数で合計を計算するメジャーを作成しておきますSalesAmount = SUM(myData[金額])

既存会員金額

OldCustomersAmount =  

①VAR CurrentCustomers= Values(myData[会員番号]) 

②VAR CurrentDate=Min(myData[日付]) 

③VAR OldCustomers=CALCULATETABLE(VALUES(myData[会員番号]),ALL(myData[日付]),myData[日付]<②CurrentDate)

④RETURN     SUMX(③OldCustomers,CALCULATE(SUM(myData[金額])))

<まとめ>

今回の記事ではDAX関数を使用して、新規と既存を区分して集計する方法を解説しました

複数の関数を組み合わせて集計しますが、一番重要なのはMIN(対象期間)により全期間から新規と既存の境目となる「時」を算出することです

DAX関数を使用することで、エクセルで複数シートをまたいで処理するのとは違い、即時に新規と既存を集計できます

今回は新規と既存の切り口での集計を紹介しましたが、後日、新規と既存の切り口以上に重要なリピートについても解説を行います

にほんブログ村 資格ブログ ビジネススキルへ

にほんブログ村

にほんブログ村 IT技術ブログ VBAへ

DAX関数の虎の巻

こちらのコーナーでは、DAX関数*をうまく使うためのコツを解説します

*エクセルのワークシートでは関数に相当するもの

フィルター評価と行評価

フィルター評価

Power BIのレポート画面では常にフィルター評価の影響を受けます

この点は常に意識しておく必要があります

例えば、次のようなデータがあったとします

こちらのデータをマトリックスで表示すると次のようになります

こちらのマトリックスの行にカラーを入れてみます

こちらは行単位で青、赤、緑のフィルターが適用されています

上の画像では、スライサーのフィルターが適用されています

このように、レポート画面ではフィルターの影響を常に受けるわけですが、DAXも同様です

但し、CALCULATEをDAX式で活用するとルールが変わります

試しに、青色の金額を抽出するCALCULATE関数でメジャーを書いてみます

Color_BLUE = CALCULATE(SUM(myTable[金額]),’myTable'[カラー]=”青”)

スライサーのフィルターを解除した上で、上記のメジャーをマトリックスに配置してみます

マトリックスの行単位での色別のフィルターは解除され、全て同じ値/6,600になっています

今度は、スライサーのフィルターを適用してみます

DAX外のフィルターはきちんと適用されているのが分かります

今度はメジャーにKEEPFILTERS関数を適用してみます

今度は、行単位での色別のフィルターが適用されています

以上、レポート画面では常にフィルターの影響を受ける点とCALCULATE関数を使うとルールが変わる点は常に意識しておきましょう!

行評価

フィルター評価と同じくらい重要で、フィルター評価より難解なのが行評価です

こちらは、明確にフィルター評価と区別して理解しましょう

例えば、次のようなデータがあるとします

こちらのデータから、行毎に値1と値2を乗算する列を作成してみます

次に値1x値2の列を合計する列を作成します

では上の画像と同じ「55」を算出するメジャーを、新しく作成した列をつかわないまま作成するにはどうしたらいいでしょう?

次のように式を書くと、突拍子もない数字になります

これはSUM関数が列自体を計算対象にしているからです

では、ここでSUMX関数を使用してみましょう!

expressionの箇所が「行評価」になっています

SUMX関数を使うと、テーブル「myNum」の1行1行を計算して合計するので正しい数字が出ています

これが行評価となります

行評価では、新しい列の作成と同じように1行1行を対象とするので、フィルター評価とは明確に区別する必要があります

ちなみにCALCULATE関数を使用すると、フィルター評価と同じようにルールが変わります

今回は、隣の列全体を合計するのではなく、1行1行の合計値を算出しています

このCALCULATE関数を使うとルールが変わる点は常に頭に入れておきましょう!

VARとRETURN~中学数学の要領でDAX使用~

DAXはVARとRETURNを使うと更に有効の活用できます

というより、VARとRETURNを使わないとかなりDAXを使う意義が薄れます

VARは変数/VARIABLEの略です

このVARを箱として活用します

エクセルのワークシートでも同じことができます

B2セルにmyValueという名前をつけました

この名前がVARに相当します

そしてD2セルで下の画像のようにmyValueを使ってみます

このD2セルの3がRETURNになります

ちなみに、B2セルの値のmyValueを2から3に変えるとD4セルのリターンは4になります

では、上記と同じ内容をPower BI内でも行ってみます

上の画像では、myValueという箱に2を入れ、更に1を加えてリターンしています

では、myValueを3にすると4がリターンします

実際には、このVARを多数組み合わせて使う形になります

ALLとALLSELECTEDとの使い分け~構成比の罠~

ALLALLSELECTEDの違いがDAXを使用したばかりだとよくわからないと思います

そもそも、ALLって何のためにあるの?という方も中にはいらっしゃると思います

ALLはスライサーなどでフィルター処理が行われた場合のためにあります

上のGIF画像では、分子がフィルターされた場合にも、分母の全体売上はALL関数により変わらないようになっています

ところが、分母の内容自体がフィルターされる場合が厄介です

上の画像では、構成比の分母は各都道府県の合計になります

仮に3つの都道府県にフィルターした場合には次のようになります

構成比_ALLの場合には、分母が固定ですから、小計が100%を割ります

構成比_ALL = DIVIDE(SUM(‘売上データ3′[売上金額]),CALCULATE(SUM(‘売上データ3′[売上金額]),ALL(‘売上データ3’)))

構成比_ALLSELECTEDの場合には、フィルターと連動して分母が動きます

構成比_ALLSELECTED = DIVIDE(SUM(‘売上データ3′[売上金額]),CALCULATE(SUM(‘売上データ3′[売上金額]),ALLSELECTED(‘売上データ3’)))

つまり、分母が何か?スライサーでフィルターする内容は何か?によってALLとALLSELECTEDを使い分ける必要があります

SUMX関数による高度な集計

エクセルのワークシート関数でもSUM系の関数は多数あります

SUM、SUMIF、SUMIFS、SUMPRODUCT・・・

DAXのSUMX関数は、ワークシート関数のSUMIFS関数とSUMPRODUCT関数を組み合わせた高性能なDAX関数です

次の表を見てください

値1の列と値2の列をそれぞれ掛け合わせ、E8セルで合計しています

E10セルにはSUMPRODUCT関数が入っており、列1と列2をそれぞれ乗じつつ、各行の結果を合計しています

H3セルにはSUMIFS関数が入っており、G3セルの条件に応じて、列1と列2を乗じた値の合計を計算しています

但し、Eの列で算出した値を参照しています

SUMPRODUCT関数のように、単独では計算できません

DAXのSUMX関数では、このSUMPRODUCT関数とSUMIFS関数の組み合わせを一発で計算できます

SUMX関数の文法は次のようになります

SUMX(テーブル,式)

試しに、前述のSUMPRODUCT関数と同じことをしてみます

元データは前と同じデータ(テーブル名:myTable)になります

下の画像では、myTableを第一引数のテーブルとして指定し、第二引数で式を指定しています

mySUMX = SUMX(‘myTable’,’myTable'[値1]*’myTable'[値2])

今度は、SUMIFS関数と同じように列1の値が<3とします

この場合は、第一引数のテーブルにFILTER関数を使います

mySUMX_FILTER = SUMX(FILTER(‘myTable’,’myTable'[値1]<3),’myTable'[値1]*’myTable'[値2])

これで、SUMIFS関数とSUMPRODUCT関数との組み合わせを計算できています

嬉しいのはSUMX関数ではSUMPRODUCT関数と違い、式を自由に指定できる点です

DAXの可能性をまさに感じさせる関数だと思います

SUMMRIZE関数による一時テーブルの作成

DAX関数内で参照用の一時テーブルを作成するのにとても便利です

文法は次の通りとなります

SUMMRIZE(テーブル,集計する切り口にする列,新列名1,集計式1,新列名2,集計式2・・・)

早速、使用例を見てみましょう

元のデータは次の通りです

売上データ3

これが上の画像のテーブルから都道府県別の売上合計、平均を算出するSUMMRIZE関数の事例1です

mySummarize = SUMMARIZE(‘売上データ3’,’売上データ3′[都道府県],”Revenue”,SUM(‘売上データ3′[売上金額]),”AVERAGE”,AVERAGE(‘売上データ3′[売上金額]))

事例2として集計の切り口を都道府県のみから、商品も加えてみましょう

mySummarize+Product = SUMMARIZE(‘売上データ3’,’売上データ3′[都道府県],’売上データ3′[商品],”Revenue”,SUM(‘売上データ3′[売上金額]),”AVERAGE”,AVERAGE(‘売上データ3′[売上金額]))

ピボットテーブルと同じような形ですよね

HASONEVALUE~値が複数か否か~

こちらのDAXは、値が複数あるケースとそうでないケースで表示を分けるのに便利です

値が複数ある場合は、FALSE、そうでない場合はTRUEを返します

ただ、上記の説明だと使用シーンが明確に浮かばないとおもうので実際の例を見てみましょう

上の画像にあるようなメジャーを作り、カレンダーテーブルの内容を行に仕込んだマトリックスの中にいれてみます

すると、MONTHの箇所は一つしか値がないのでTRUEになり、YEARの箇所はMONTHが複数あるのでFALSEになります

次にもう一つメジャーを作成します

IF式を使い、HASONEVALUEがTRUEであれば、金額を表示するようにします

YEARとMONTHで表示を切り替えられるようになりました

ISBLANKとISEMPTY~空白?空欄~

ISBLANKとISEMPTY、似てるようで明確に違いがあります

具体的には何が違うのでしょう?

ISBLANKは対象が、ISEMPTYはテーブルが対象になります

ISBLANK

下の画像では「ISBLANK1」という新しい列を追加しています

空欄の行では「TRUE」を返しています

次の画像ではIF式と組み合わせて空欄を0に置き換えています

ISEMPTY

ISEMPTY関数を使い、次のようなメジャーを作成してみます

上の画像内の「’EMPTY’」は次の画像のテーブルです

このメジャーの内容をカードで出力してみます

こちらはTrueで出力されます

今度はISEMPTYの中身のテーブルを変えてみます

’テーブル’は空でないのでFalseが返されます

REMOVEFILTERS関数~フィルターの影響を避ける~

思わぬところでフィルターの落とし穴にはまったことはないですか?

以下のグラフでは折れ線グラフが100%のまま水平になっています

これは元のデータにはABCだけでなく、EやFもあるのです

ただ、フィルターがかかっています

このフィルターがかかっている状態にて、折れ線グラフで使用するメジャーは次のような数式になっているのです

分子のメジャーは商品ABCの合計です

分母は全体の合計です

ただ前述のようにフィルターはABCにかかっています

ですので分母は常に商品ABCです

だから100%のままです

この場合にREMOVEFILTERS関数を使用します

A&B&C %_2 = DIVIDE(‘DATA'[Sales_A&B&C],CALCULATE(SUM(DATA[値]),REMOVEFILTERS(‘DATA'[商品])))

このREMOVEFILTERS関数により、商品に対してかかっているフィルターを取り除きます

そうすることで分母を常に正しく計算することができます

ちなみにALL関数を使うと時系列でのフィルターがかからないため、分母が異常に大きくなってしまいます

SUMMARIZECOLUMNS関数~簡単にグループ化~

SUMMARIZECOLUMNS関数を使用すると、下のようなデータを簡単にグループ化することができます

新しいテーブルからこのDAX関数を使用してみます

yyyyMM列をグループ化の切り口として「月小計」という列を作成し、「月小計」に受注数のグループ別の小計を計算します

NewTable=SUMMARIZECOLUMNS(①’OrderData'[yyyyMM],②”月小計”,③SUM(‘OrderData'[受注数]))

たった3つの引数だけで作成できるのでとても便利です

①:グループ化の切り口、②新列名、③計算式

こちらの関数は次のように変数にSUMMARIZECOLUNS関数で作成したテーブルを代入して使用することもできます

Sales_MaxMonth = VAR myTable=SUMMARIZECOLUMNS(‘OrderData'[yyyyMM],”月小計”,SUM(‘OrderData'[受注数]))
VAR MaxMonth=MAX(‘OrderData'[yyyyMM])
RETURNSUMX(FILTER(myTable,[yyyyMM]=MaxMonth),[月小計])

CALCULATE関数にて複数条件を指定する

CALCULATE関数は条件を指定しながら様々な集計ができる便利なDAX関数です

複数条件を指定する場合には次のような式になります

AND条件

CALCULATE関数に条件を追加する場合には「コンマ」を追加します

例えば、下の画像のデータから(商品=A)and (月=202303)という条件で合計金額を集計したいとします

その場合のメジャーは次のようになります

商品:A and 月:202303 = CALCULATE(SUM(‘DAX1′[金額]),’DAX1′[商品]=”A”,’DAX1′[月]=202303)

OR条件

OR条件の場合には「||」を使用します

商品:A or 商品:B = CALCULATE(SUM(‘DAX1′[金額]),’DAX1′[商品]=”A” || ‘DAX1′[商品]=”B”)

この場合、「in」を使用するという方法も使えます

商品:A or 商品:B_in使用 = CALCULATE(SUM(‘DAX1′[金額]),’DAX1′[商品] in {“A”,”B”})

SWITCH関数とTRUEの組み合わせ

通常

SWITCH関数は場合分けをするケースでとても便利です

注文金額3 = SWITCH(‘分析用2′[注文金額],1200,”1200″,8600,”8600″,”X”)

IF関数と比べて条件を複数追加することができます

ただ条件設定が「=しか指定できない」、「指定順序が間違いやすい」などの問題があります

TRUE

SWITCH関数の第一引数を「TRUE」とすると、もっと柔軟に条件を指定できるようになります

注文金額2 = Switch(true(),[注文金額]<2000,”2000未満”,[注文金額]<4000,”4000未満”,”4000以上”)

RANKX関数~順位付け~

DAXのRANKX関数を使えば、集計した値に対して順位付けが行えますのでとても便利です

RANKX関数の文法自体はとても簡単なものですが、実際には少々トリッキーな面があります

文法:RANKX(使用テーブル,順位を判断する値)

*実際には他にも指定できます

作成してみたけど結果が全て1になってしまった、という方も中にはいらっしゃると思いますので、トリッキーな面を中心に解説を行います

解説に使用するテーブル/テーブル名:Tableは以下です。カテゴリーが大小2つあります

こちらのデータから大、小のカテゴリーにて順位付けを行えるようにします

判断に使用する値は予めメジャーで算出しておきます

これが1つ目の大きなポイントです

次に実際にカテゴリー大を順位付けするメジャーを作成します

ここでAllを使用するのが2つ目の大きなポイントです

そして、Allの引数はカテゴリー列も指定します

Allを使用しないと、ビジュアルで表示する時にフィルターが効いて全て1になります

他の言葉で言い換えると、フィルターが効いても他の行の値と比較して順位付けできるようにします

では次にカテゴリー小を順位付けするメジャーを作成します

このメジャーをマトリックス表にセットしてみます

こちらは大カテゴリー内での順位が出力されます

今度は、カテゴリー大の関連はマトリックス表から抜いてみます

これでカテゴリー小の間で順位付けが行えました

繰り返しになりますが、順位付けを行う値は事前にメジャーにしておきましょう!

DISTINCTCOUNTROWS vs DISTINCT vs VALUES

一見、同じに見えるこれらの関数ですが、何が違うのでしょうか?

試しに、これらの3つのDAX関数を使用して下の画像のテーブルにて「客先名」をカウントするメジャーを作成してみたいと思います

実際に作成するメジャーの中身は次の通りとなります

ちなみにDISTINCT関数VALUES関数COUNTROWS関数と組み合わせます

CountBY DistinctCount = DISTINCTCOUNT(‘売上テーブル'[客先名])

CountBY Distinct = COUNTROWS(DISTINCT(‘売上テーブル'[客先名]))

CountBY Values = COUNTROWS(VALUES(‘売上テーブル'[客先名]))

結果は全く同じ結果になります(空欄もカウントしています)

ではどのような時に結果が違ってくるのでしょうか?

今度は客先マスタで客先名をカウントしてみます

但し、先ほどの売上テーブルとリレーションを組んでおきます

実際に作成するメジャーは次の通りとなります

CountBY DistinctCount = DISTINCTCOUNT(‘客先マスタ'[客先名])

CountBY Distinct = COUNTROWS(DISTINCT(‘客先マスタ'[客先名]))

CountBY Values = COUNTROWS(VALUES(‘客先マスタ'[客先名]))

結果は次の通りとなります

VALUES関数だけ売上テーブルの空欄をカウントしているという結果になりました

CalculateTable関数~テーブルの作成~

テーブルを作成する際に便利なのが、CalculateTable関数です

CalculateTable関数は条件付で計算をするのに便利なCalculate関数のテーブル版です

文法も一緒で、出力されるのがテーブルというだけです

テーブル関数も幾つかありますが、CalculateTable関数を使うケースは次のようなケースが典型的です

Customer IDs = CALCULATETABLE(VALUES(OrderData1[Customer ID]),OrderData1[yyyy-MM]=”2019-07″)

上のDAX式ではVALUES関数と組み合わせて、注文データ/OrderData1から2019年7月に注文があった会員の番号をリスト化しています

こんな風に1列をリスト化するVALUES関数と組み合わせて、条件に合うリストを作るケースなどで便利です

更には「VAR~RETURN」と組み合わせて、CalculateTable関数で出力したリストから更に別なものを出力するといった事もできます

EOMONTH関数~時系列で日付を整理する~

時系列で日付を整理するのに便利なのが、EOMONTH関数です

例えば前月末日を知りたいとします

その場合は次のようにメジャーを書きます

これだけで自動的に前月末日が出力されます

では、前月開始日を出したい場合にはどうしたらいいでしょうか?

その場合は「+1」をうまく使います

これで、開始日も自由に抽出できます

フィルターが複数あるケースで割合を計算する~Calculate&AllSelected&removeFilters~

よくこんな風にフィルターがスライサーを含めて複数かかるケースがあります

上の画像のケースでは「日付、しかも月」「商品」の2つです

この場合、グラフ内の選択商品の割合をどうやって計算しますか?

下の画像の場合は商品A~Cの合計が100で、選択された商品Bは45なので45%です

分子は該当の「月」で該当の「商品」の売上金額です

つまり純粋に選択されたものです

ですので以下のメジャーで簡単に算出されます

CALCULATE(SUM(‘テーブル'[売上金額]),ALLSELECTED(‘テーブル’))

では、分母はどうでしょう?意外と難しく感じられませんでしょうか?

フィルターは「月」だけです

ですが、Calculate関数内で指定できるのは「日付単位」です

この場合は、Calculate関数内で次のようにRemoveFilters関数を組み合わせればあっさりと解決します

CALCULATE(sum(‘テーブル'[売上金額]),ALLSELECTED(‘テーブル’),REMOVEFILTERS(‘テーブル'[商品]))

こちらが割合を計算するメジャーです

割合 =

VAR bunshi=CALCULATE(SUM(‘テーブル'[売上金額]),ALLSELECTED(‘テーブル’))

VAR bunbo=CALCULATE(

            sum(‘テーブル'[売上金額]),

            ALLSELECTED(‘テーブル’),

            REMOVEFILTERS(‘テーブル'[商品])

      )

RETURN DIVIDE(bunshi,bunbo)

にほんブログ村 資格ブログ ビジネススキルへ

にほんブログ村

にほんブログ村 IT技術ブログ VBAへ

カレンダーテーブルの活用により、数字を時系列の軸で自由に集計するツアー

今回のシリーズ記事では、カレンダーテーブルを使用してデータを「前年データ」や「累計」などの時系列で簡単に整理し直す技術を解説したいと思います

カレンダーテーブルとは、売上データなどの日付が入ったデータをカレンダーのそれぞれの日付に割り当てて整理するためのテーブルです

カレンダーテーブル

このカレンダーテーブルが活用できるようになると、今までエクセルのワークシートで手動での転記処理に頼っていた「時系列でのデータの整理」が簡単にできるようになります

カレンダーテーブルの作成・準備

作成

ここまでの解説だと「カレンダーテーブルとはなんなのか?」が具体的にはよくわからないと思います

シンプルに言えば、まさにカレンダーのような連続した日付列を起点として作成されたデータテーブルです

この連続した日付データに年や月などを紐づけておき、売上データなどを時系列で括りなおせるようにします

リレーション

作成したカレンダーテーブルは、他テーブルとリレーション(紐づけ)を行って使用します

このリレーションを適切に行わないと、カレンダーテーブルを活用できません

会計年度の調整

日本の企業は大抵が3月決算です

ですから、1月~3月のデータは実際の年より前の年で会計年度が割り当てられます

この会計年度の調整を事前にカレンダーテーブルで行っておきます

メジャーの作成(前年比、累計など)

前年比や累計など、作成したカレンダーテーブルを活用して作成する数字はメジャーで作成します

エクセルを使用してきた感覚の延長だと、このメジャーというのはなかなか理解しがたいものです

何故なら、テーブルの列にメジャーで作成した数字はでてこないからです

これはメジャーで作成する前年比などの数字は穴埋め問題みたいなものだからです

穴埋め問題の答えは、あくまで前後の数字が決まってから答えが決まります

例えば、前年比ならば集計対象が2022年6月ということが決まってから2021年6月に対する前年比を算出することが決まります

このメジャーが穴埋め問題である点に慣れれば、後はDAXというPower BI(Power Pivot)独自の関数を使用して計算していくだけです

このDAXはワークシート関数と同じ感覚で使用できますが、文法が若干違うので注意が必要です

<まとめ>

数字を見ると時のツボは時系列で比較することです

私もこの辺の時系列のデータ整理はさんざん苦労しました

エクセルではどんなに頑張っても手動処理が入るからです

しかも、かなり気を遣うので疲れます

Power BIのカレンダーテーブルを活用して時系列でデータを自動整理する仕組みは、まさにPower BIの醍醐味といっても過言ではありません

ぜひ次回からの回でしっかりカレンダーテーブルを活用する技術を身につけましょう!

2回目:カレンダーテーブルを実際に作成する~カレンダーテーブルを活用するツアー~

3回目:カレンダーテーブルを実用的に調整する~カレンダーテーブルを活用するツアー~

4回目:前年の値や累計を使う~カレンダーテーブルを活用するツアー~

にほんブログ村 資格ブログ ビジネススキルへ

にほんブログ村

にほんブログ村 IT技術ブログ VBAへ