معرفی Calculation Groups در زبان Dax

پیشنیاز : آشنایی با زبان Dax

مدت زمان مورد نیاز برای مطالعه : ۲۰ دقیقه


در این مقاله قصد داریم معرفی از ویژگی Calculation Groups در زبان Dax داشته باشیم.در این مقاله نحوه ایجاد Calculation Groups  را در یک یک مدل Tabular مورد بررسی قرار میدهیم.

این ویژگی با قابلیت های محدودتر قبلا در زبان MDX وجود داشت. استفاده از این ویژگی بسیار راحت می باشد اما طراحی مدل ها و Measure  ها و نحوه درست استفاده از آن میتواند چالش خاص خود را داشته باشد.

قبل از اینکه بخواهیم توضیحاتی در ارتباط با این ویژگی ارائه دهیم ابتدا باید در این مورد صحبت کنیم که اصلا به طور کلی چرا این ویژگی تعریف و بوجود آمد و علت نیاز به آن چه بود؟

مثال ما در این زمینه شامل چهار Measure با نام های Sales Amount(مقدار کل فروش)، Total Cost(مقدار هزینه ها)، Margin(حاشیه سود) ، Sales Quantity(تعداد کل فروش) میباشد.

Sales Amount   := SUMX ( Sales, Sales[Quantity] * Sales[Net Price] )
Total Cost     := SUMX ( Sales, Sales[Quantity] * Sales[Unit Cost] )
Margin         := [Sales Amount] - [Total Cost]
Sales Quantity := SUM ( Sales[Quantity] )

تمام Measure های ذکر شده مفید ، با ارزش می باشد و میتواند از جهتی اطلاعات خوبی نسبت به بیزینس بدهد. همچنین هر چهار Measure ذکر شده میتواند کاندید خوبی برای آنالیز بر اساس زمان باشد.تعداد فروش سال به نسبت هر روز میتوانید به همان اندازه که میزان فروش و حاشیه سود مهم هستند ، اهمیت داشته باشند.همچنین این نکته برای بسیاری دیگر از ابعاد زمان همانند دوره رشد سال گذشته ، رشد نسبت به سال قبل (درصد) و بسیاری دیگر نیز صادق است.

با این اوصاف اگر قرار باشد در مدلی که طراحی میکنید به ازای هر Measure تمامی این محاسبات بر اساس زمان را انجام دهید قطعا بعد از مدتی با یک مدل به شدت بزرگ و شلوغ مواجه خواهید شد.در شرایط واقعی ، مدیریت یک مدل داده ای با صدها Measure  هم برای کاربر و هم برای  توسعه دهنده بسیار ترسناک می باشد.این نکته را هم در نظر داشته باشید که محاسبه تمامی انواع مختلف Measure ها براساس هر بعدزمانی خاص کاملا یکسان می باشد.برای مثال تابع DatesYTD برای چهار Measure ذکر شده به شکل زیر اجرا میشود.

YTD Sales Amount :=
CALCULATE (
    [Sales Amount],
    DATESYTD ( 'Date'[Date] )
)
 
YTD Total Cost :=
CALCULATE (
    [Total Cost],
    DATESYTD ( 'Date'[Date] )
)
 
YTD Margin :=
CALCULATE (
    [Margin],
    DATESYTD ( 'Date'[Date] )
)
 
YTD Sales Quantity :=
CALCULATE (
    [Sales Quantity],
    DATESYTD ( 'Date'[Date] )
)

در کدهای تولید شده تنها تفاوت در Measure اصلی می باشد.تمامی آنها فقط بر اساس متد DatesYTD فیلتر شده اند.خیلی جالت تر خواهد بود اگر توسعه دهنده بتواند یک تعریف عمومی داشته باشد که بدون نیاز به بازنویسی مجدد از این کد برای تمامی Measure های مورد نیازش استفاده کند.

YTD <Measure> :=
CALCULATE (
    <Measure>,
    DATESYTD ( 'Date'[Date] )
)

کد بالا یک کد واقعی در زبان Dax نیست ولی یک تعریف خوب برای یک Calculation Item  میتواند باشد. کد بالا میگوید زمانی که میخواهید به طور مثال متد DatesYTD را بر روی Measure خود اجرا کنید کافیست Measure خود را در نقطه مورد نظر قرار دهید.این همان کاری هست که Calculation Item انجام میدهد.یک Calculation Item به عبارتی یک عبارت به زبان Dax می باشد که بخشی از آن قرار هست که قبل از اجرا توسط یک Measure پر شده و اجرا گردد.به زبان دیگر یک calculation Item میتواند روی هر Measure ای اجرا و استفاده شود.

علاوه بر این شاید در جایی نیاز داشته باشید ابعاد مختلف زمانی را بر روی یک Measure استفاده و تحلیل کنید. بر فرض مثال روز نسبت به کل سال و یا روز نسبت به فصل و یا مقایسه سال جاری با سال قبل و … که به نوعی تمامی اینها زیرمجموعه یک گروه می باشند.خلاصه مطلب Calculation Group ها شامل تعدای Calculation Item میباشند که به نوعی از یک جنس و زیرمحموعه یک موضوع تحلیلی می باشد.

CALCULATION GROUP "Time Intelligence"
    CALCULATION ITEM CY := <Measure>
    CALCULATION ITEM PY := CALCULATE ( <Measure>, SAMEPERIODLASTYEAR ( 'Date'[Date] ) )
    CALCULATION ITEM QTD := CALCULATE ( <Measure>, DATESQTD ( 'Date'[Date] ) )
    CALCULATION ITEM YTD := CALCULATE ( <Measure>, DATESYTD ( 'Date'[Date] ) )

همانطور که در کد بالا مشاهده میکنید چهار Calulation Item که به نوعی به هم مربوط هستند در یک Calulation Group به نام Time Intelligence قرار گرفته اند و میتوانند ۱۰ها Measure را در خود جای داده و بدون هیج هزینه اضافی مورد استفاده مجدد قرار گیرند.

همچنان جزئیات برای درک کردن بهتر این موضوع باقی مانده است.اما فقط یک چیز برای رسیدن به درک کامل نسبت به این ویژگی ویژگی وجود دارد!

چگونه کاربر یکی از این Item های ایجاد شده را انتخاب میکند؟

همانطور که گفتیم CalculationItem یک Measure نیست و فقط به نوعی بخشی از دیتای یک Measure می باشد.بنابراین کاربر نیاز دارد که در گزارش خودش بر اساس این تایپ ها بتواند مقدار Measure خود را بررسی کند.ضمنا از آنجایی که کاربران معمولا عادت دارند که اطلاعات خود را از جدول انتخاب کنند، Calculation Group  هم به همین شکل این امکان را به کاربر میدهد که انتخاب خود را به مانند یک ستون از یک جدول به راحنی انجام دهد.با این روش کاربر میتواند از Caclucation Group  طراحی شده خود به مانند یک ستون در یک ماتریکس استفاده کند  و دیتای مورد نیاز خود را بر اساس آنها تحلیل و بررسی کند.

ایجاد Calculation Groups با استفاده از Tabular Editor

Tabular Editor اولین نرم افزاری هست که قابلیت ایجاد Calculation Groups  را به توسعه دهنده میدهد.زیرا این قابلیت نیاز به  Compatiblity Level 1470 از مدل داده ای Tabular دارد.

تقریبا از خرداد سال ۱۳۹۸ این ویژگی به Analysis Service 2019  و همچنین Azure Analysis Service اضافه شد.

در Tabular Edito در بخش منو با انتخاب آیتم Model و پس از آن انتخاب New Calculation Group میتوانید یک Calculation Group جدید ایجاد کنید.هماهنطور که در عکس زیر مشاهده میکنید یک Calculation Groups جدید به نام Time Intelligence ایجاد شده است.

یک Calculation Group در Tablar Editor به نوعی یک جدول است با یک ستون که میتواند شامل تعدادی آیتم باشد.

در زیر ۳ آیتم به آن ا  ضافه شده است.هرآیتم شامل یک عبارت Dax میباشد که میتوان آن را بر اساس نیاز خود ویرایش کرد.

متد SelectedMeasure() همان جایگزین شده <Measure>در عبارت توضیح داده شده قبلی می باشد. تک تک عبارت های نوشته شده در ادامه با توضیحات هر کدام در بالای آن بدین شکل ایجاد میشود.

-- 
-- Calculation Item: YTD
-- 
    CALCULATE (
        SELECTEDMEASURE (),
        DATESYTD ( 'Date'[Date] )
    )
 
-- 
-- Calculation Item: QTD
-- 
    CALCULATE (
        SELECTEDMEASURE (),
        DATESQTD ( 'Date'[Date] )
    )
 
-- 
-- Calculation Item: SPLY
-- 
    CALCULATE (
        SELECTEDMEASURE (),
        SAMEPERIODLASTYEAR ( 'Date'[Date] )
    )

با این تعریف کاربر در بخش مدل خود یک جدول با یک ستون و ۳ مقدار با نام های YTD ، QTD و  SPLY میبیند.کاربر با ایجاد یک Slicer و یا به عنوان استفاده در یک ستون از جدول میتواند از این مقادیر استفاده کند.دقیقا شبیه به یک ستون واقعی در مدل خود.

برای مثال زمانی که کاربر YTD را انتخاب میکند. ، سیستم به صورت اتوماتیک تمامی Measureهایی که در داشبورد وجود دارد را بر اساس فیلد انتخابی تغییر وضعیت میدهد.به مثال بعدی که این شرایط را روی Measure میزان فروش نمایش میدهد توجه کنید.

اگر در همین گزارش کاربر آیتم  SPLY را انتخاب کند گزارش بدین شکل تغییر خواهد کرد.

اگر کاربر هیچ کدام از Caclulation Item ها را انتخاب نکند سیستم به صورت اتوماتیک Measure اصلی را بدون اعمال هیچ تغییری در گزارش نمایش میدهد.

این قابلیت میتواند حتی خیلی جداب تر هم باشد!

در ابتدای این مقاله ما ۴  Measure را تعریف و تولید کردیم با نام های :  Sales AmountTotal CostMargin, و Sales Quantity.این گزارش خیلی جذاب تر خواهد شد اگر علاوه بر این Calculation Group یک Slicer  برای انتخاب Measure های طراحی شده هم داشته باشد. به عبارتی دیگر یک گزارش جنریک ، منعطف و پویا که دست کاربر را برای بررسی خیلی بیشتر باز میگذارد.

برای ایجاد یک همچنین شرایطی ما به راحتی میتوانیم با تولید یک Calculation Group جدید و قرار دادن این چهار Measure درون آن این شرایط را فراهم کنیم که کاربر بتواند بین آنها انتخاب کند.

واقعا جالب نیست؟! فبل از ایجاد این قابلیت برنامه نویس باید با تعداد زیادی  سویچ و If else این شرایط را بوجود می آوردیم اما الان با این قابلیت با حجم بسیار کم کد این قابلیت در اختیارتان قرار میگیرد.

اما نکاتی هم وجود دارد

در زمانی که شما تعدادی Calculation Groups در مدل خود دارید حتما باید ابتدا در مدل خود ترتیب اجرای آنها را مشخص کنید.ویژگی به نام Precedence  در Calculation Group وجود دارد که میتوانید با تغییر آن ترتیب اجرا را تغییر دهید.اولین Calculation Group ای که اعمال میشود گروهی می باشد که ترتیب بالاتری داشته باشد.

به منظور دستیابی به نتیجه مطلوب ویژگی Precedence  در Calculation Group  ، Time Intelligence را به مقدار ۱۰ تغییر میدهیم.

در نتیجه سیستم قبل از اینکه Measure  ها را محاسبه و اعمال کند ابتدا Time Intelligence را مورد بررسی قرار میدهد.کد های زیر عبارات Dax ایجاد شده به ازای هر Measure میباشد.

-- 
-- Calculation Item: Margin
-- 
    [Margin]
 
-- 
-- Calculation Item: Sales Amount
-- 
    [Sales Amount]
 
-- 
-- Calculation Item: Sales Quantity
-- 
    [Sales Quantity]
 
-- 
-- Calculation Item: Total Cost
-- 
    [Total Cost]

این  Calculation Item  ها هیچ تغییری در اصل  Measure تولید شده ایجاد نمیکنند بلکه به عنوان خروجی جایگرین مقدار اصلی مشوند. برای رسیدن به این هدف ما متد SELECTEDMEASURE() را حذف کرده ایم.SELECTEDMEASURE() در اغلب Calculation Item ها مورد استفاده قرار میگیرد اما استفاده از آن هم اجباری نیست.

اضافه کردن و حذف کردن یک Measure از  Calculation Itrem

این سناریویی که تا الان بوجود آوردیم یک نقص دارد. این مورد را فراموش نکنیم که طبیعتا شاید یک  Calculation Item تولید شده روی یک Measure خاص اصلا قابل استفاده نباشد.به طور پیش فرض هر Calculation Item تولید شده بر روی تمامی Measure  ها تاثیر میگذارد که این مورد تایید شاید نباشد!

با توجه به نمونه های ذکر شده در پایین اگر Measure ذکر شده در لیست ISSELECTEDMEASURE() باشد محاسبه اعمال خواهد شد در غیر این صورت خیر و همچنین با قرار دادن یک Not در متد معرفی شده بالا این عمل به صورت معکوس برای همه Measure ها بجز Measure های معرفی شده اعمال خواهد شد.

IF (
    NOT ISSELECTEDMEASURE ( [Margin %] ),
    DIVIDE (
        SELECTEDMEASURE (),
        COUNTROWS ( 'Date' )
    )
)
IF (
    NOT ( SELECTEDMEASURENAME () = "Margin %" ),
    DIVIDE (
        SELECTEDMEASURE (),
        COUNTROWS ( 'Date' )
    )
)

ISSELECTEDMEASURE به دلایل ذکر شده در زیر به SELECTEDMEASURENAME  ترجیح داده میشود

  • امکان دارد نامی که در متد بر اساس نام استفاده میشود غلط املایی در آن وجود داشته باشد و خطایابی سخت شود.
  • اگر نام Measure در زمان استفاده از ISSELECTEDMEASURE شامل غلط املایی باشد همان لحظه خطا میدهد و میتوانید متوجه شوید.
  • اگر یک Measure تغییر نام دهد تمامی اسامی قبلی در مدل در زمان استفاده از ISSELECTEDMEASURE به صورت اتوماتیک تغییر نام میدهد اما در SELECTEDMEASURENAME به این شکل نخواهد بود و باید به صورت دستی تمامی موارد تغییر کند.

SELECTEDMEASURENAME   زمانی مورد استفاده قرار میگیرد که فرضا شما اطلاعات اسامی Measure ها را در یک منبع بیرونی در می آورید. به طور مثال اطلاعات آن از یک جدول استخراج میشود.

نتیجه گیری

Calculation Group یک ویژگی بسیار خوب و تقریبا جدید در زبان DAX میباشد.در اولین مقاله در این ارتباط ما فقط سعی کردیم که یک معرفی از این قابلیت داشته باشیم.در مقالات بعدی سعی میشود در قالب نمونه های جذاب تر این ویژگی بهتر و بیشتر توضیح داده شود.

با ما همچنان همراه باشید…

1 پاسخ
  1. زینب کاشانی
    زینب کاشانی گفته:

    عالی
    ممنون میشم در مورد طریقه نصب و استفاده از tabular editor همراه با مثال نیز مطلب ارائه بفرمایید

    با تشکر

    پاسخ

دیدگاه خود را ثبت کنید

تمایل دارید در گفتگوها شرکت کنید؟
در گفتگو ها شرکت کنید.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *