یکی از پیچیدهترین و در عین حال پرکاربردترین مفاهیم در نوشتن Measure در DAX، مدیریت Filter Context است. در بسیاری از گزارشهای Power BI، نیاز است محاسبهای نسبت به یک Context متفاوت از Context فعلی سطر یا سلول انجام شود. برای مثال، محاسبه درصد فروش هر محصول نسبت به مجموع فروش زیرمجموعهای که کاربر از طریق Slicer انتخاب کرده است، بدون توجه به گروهبندی سطرهای جدول یا ماتریس.
تابع ALLSELECTED دقیقاً برای پاسخ به این نوع نیازها طراحی شده است. این تابع بر اساس Contextی عمل میکند که در سطح Query یک Visual تعریف میشود و بهجای حذف کامل فیلترها مانند ALL، تنها فیلترهای Row و Column ایجادشده در همان Query را نادیده میگیرد، در حالی که فیلترهای صریح و سایر Contextهای موجود را حفظ میکند.
در این مقاله از لاندا، تعریف دقیق ALLSELECTED بر اساس مستندات رسمی، نحوه عملکرد آن در Evaluation Context، تفاوت آن با ALL و REMOVEFILTERS، کاربرد آن در Visual Total، سناریوهای واقعی، محدودیتهای مستند شده و اشتباهات رایج بررسی میشود.
تعریف تابع ALLSELECTED
ALLSELECTED برای محاسبه بر اساس Context انتخابشده در سطح Query طراحی شده است. این تابع فیلترهای Row و Column ایجادشده در Query را نادیده میگیرد، اما فیلترهای صریح و سایر فیلترهای خارج از این Context را حفظ میکند. به همین دلیل، در گزارشهای Power BI میتواند برای محاسبه Visual Total، درصد از مجموع انتخابشده و Running Total محدود به محدوده انتخابی استفاده شود.
ALLSELECTED به معنای واقعی کلمه اطلاعی از قصد یا انتخاب کاربر ندارد. این نکته یکی از مهمترین نکات درباره این تابع است، زیرا یکی از رایجترین سادهسازیهای نادرست درباره ALLSELECTED این است که گفته شود این تابع فیلتر Slicer را نگه میدارد. اگرچه این مدل ذهنی در بسیاری از سناریوهای رایج نتیجه درستی میدهد، اما تعریف دقیق تابع بر اساس نوع فیلتر، یعنی Row/Column Filter در برابر Explicit Filter و سایر Contextها، استوار است، نه بر اساس اینکه فیلتر از کجای رابط کاربری آمده است یا کاربر چه چیزی را انتخاب کرده است.
این تابع بخشی از خانواده توابع تغییر Context در DAX است و معمولاً در کنار توابع تجمعی مانند SUM، CALCULATE و SUMX برای محاسبه مقادیری استفاده میشود که باید نسبت به یک زیرمجموعه انتخابشده، نه کل جدول، سنجیده شوند.
نحوه عملکرد ALLSELECTED
Syntax پایه
ALLSELECTED ( [ TableNameOrColumnName ] )
این تابع میتواند به سه شکل استفاده شود.
ALLSELECTED ()
ALLSELECTED ( TableName )
ALLSELECTED ( ColumnName )
در حالت بدون آرگومان، ALLSELECTED() Contextی ایجاد میکند که فیلترهای Row و Column مربوط به Query فعلی را نادیده میگیرد، اما فیلترهای صریح و سایر Contextهای خارج از این محدوده را حفظ میکند. در حالت با آرگومان جدول یا ستون، این رفتار محدود به همان جدول یا ستون مشخصشده خواهد بود.
مفهوم Query Context در ALLSELECTED
نکته کلیدی برای درک ALLSELECTED این است که این تابع بر اساس مفهومی به نام Query Context عمل میکند. زمانی که یک Visual در Power BI رندر میشود، Power BI برای آن یک Query تولید میکند که شامل فیلترهایی از منابع مختلف است، از جمله فیلترهای Slicer، فیلترهای سطح صفحه، فیلترهای سطح گزارش و گروهبندیهای داخل خود Visual مانند سطرها و ستونهای یک Matrix که در قالب Row و Column Filter در Query ظاهر میشوند.
ALLSELECTED فیلترهای Row و Column این Query را نادیده میگیرد، اما فیلترهای صریح، مانند فیلترهایی که از طریق Slicer یا فیلتر سطح صفحه اعمال شدهاند، دستنخورده باقی میمانند. این تفکیک بر اساس نوع فیلتر است، نه صرفاً محل قرارگیری آن در رابط کاربری.
به همین دلیل، رفتار ALLSELECTED کاملاً به محل استفاده آن وابسته است. اجرای یک Measure مبتنی بر ALLSELECTED در ابزاری مانند DAX Studio که Visual واقعی پشت آن وجود ندارد، لزوماً همان Contextی را ایجاد نمیکند که Power BI هنگام اجرای Query یک Visual ایجاد میکند. برای تحلیل دقیق این نوع Measureها، باید ساختار Query و فیلترهای Row و Column ایجادشده در آن نیز در نظر گرفته شود، نه صرفاً این پرسش که آیا یک Visual واقعی پشت این Query وجود دارد یا خیر.
مقایسه ALLSELECTED با ALL
تفاوت اصلی میان ALL و ALLSELECTED در نحوه برخورد آنها با فیلترهای صریح مانند Slicer است.
Total Sales All =
CALCULATE (
SUM ( Sales[Amount] ),
ALL ( Sales )
)
این Measure فیلترهای مربوط به جدول Sales را حذف میکند. بنابراین فیلترهای اعمالشده مستقیم روی این جدول، از جمله فیلترهای ناشی از Slicer یا گروهبندی Visual در صورت اعمال آنها روی ستونهای Sales، حذف میشوند. اگر فیلتر از طریق جدول دیگری مانند Products به Sales منتقل شده باشد، نتیجه باید با توجه به روابط مدل و Expanded Table تحلیل شود. برای حذف فیلترهای کل مدل بدون محدود شدن به یک جدول خاص، استفاده از ALL() بدون آرگومان مفهوم متفاوتی دارد.
Total Sales AllSelected =
CALCULATE (
SUM ( Sales[Amount] ),
ALLSELECTED ( Sales )
)
این Measure فیلترهای Row و Column مربوط به جدول Sales را در Query فعلی نادیده میگیرد، اما فیلترهای صریح، مانند انتخاب کاربر در یک Slicer، همچنان در محاسبه لحاظ میشوند.
جدول مقایسه ALL و ALLSELECTED
| ویژگی | ALL | ALLSELECTED |
|---|---|---|
| نوع فیلتر حذفشده | تمام فیلترهای جدول یا ستون مشخصشده | فیلترهای Row و Column در Query فعلی |
| برخورد با فیلترهای صریح مانند Slicer | حذف میشود | حفظ میشود |
| وابستگی به ساختار Query | کمتر | بیشتر |
| کاربرد اصلی | محاسبه کل مطلق بدون وابستگی به انتخاب کاربر | Visual Total و محاسبات نسبت به Context انتخابشده |
| پیچیدگی رفتار | معمولاً سادهتر و قابل پیشبینیتر | بیشتر، بهویژه در ترکیب با Iteratorها و Context Transition |
مقایسه ALLSELECTED با REMOVEFILTERS
REMOVEFILTERS برای حذف فیلتر از جدول یا ستون مشخصشده استفاده میشود و از نظر کاربرد در CALCULATE میتواند جایگزین خواناتری برای الگوهای حذف فیلتر با ALL باشد. با این حال، برخلاف ALL، وظیفه آن صرفاً حذف فیلتر است و برای برگرداندن یک Table Expression استفاده نمیشود.
Total Sales RemoveFilters =
CALCULATE (
SUM ( Sales[Amount] ),
REMOVEFILTERS ( Sales )
)
از نظر رفتاری، REMOVEFILTERS معادل ALL عمل میکند و تمام فیلترهای مشخصشده را بدون قید و شرط حذف میکند. بنابراین REMOVEFILTERS جایگزین مناسبی برای ALL است، اما جایگزین ALLSELECTED نیست. تفاوت مفهومی این دو در این است که REMOVEFILTERS و ALL هر دو فیلتر را بهطور کامل و بدون در نظر گرفتن نوع آن حذف میکنند، در حالی که ALLSELECTED بر اساس نوع فیلتر، یعنی Row/Column Filter در برابر Explicit Filter، تصمیم میگیرد کدام بخش حذف شود.
محاسبه Visual Total با ALLSELECTED
یکی از کاربردهای اصلی و رسمی ALLSELECTED که در مستندات Microsoft و منابع تخصصی مانند SQLBI به آن اشاره شده، ساخت Visual Total در Table و Matrix است. Visual Total به مقداری گفته میشود که بر اساس Context کلی دادههای موجود در Visual و با حفظ فیلترهای بیرونی گزارش محاسبه میشود. این مقدار لزوماً معادل جمع ساده Measureهای نمایشدادهشده در سطرهای Visual نیست، بلکه نتیجه ارزیابی مجدد Measure در یک Context متفاوت است که فیلترهای Row و Column را کنار گذاشته و فیلترهای صریح بیرونی را حفظ کرده است.
Visual Total Sales =
CALCULATE (
SUM ( Sales[Amount] ),
ALLSELECTED ()
)
این Measure بهجای محاسبه مجموع فروش بدون توجه به هیچ Context، مقدار فروش را در محدودهای محاسبه میکند که توسط فیلترهای بیرونی گزارش، مانند Slicer و فیلتر سطح صفحه، تعیین شده است. این الگو معمولاً در ردیف Total یک Visual یا برای نمایش یک مقدار مرجع ثابت در کنار مقادیر جزئی هر سطر استفاده میشود.
سناریوهای واقعی استفاده
از ALLSELECTED معمولاً در موارد زیر استفاده میشود.
- محاسبه Visual Total که باید مقداری مرجع منطبق با محدوده فیلترشده گزارش را نشان دهد
- محاسبه درصد فروش هر ردیف نسبت به مجموع فروش زیرمجموعه انتخابشده توسط کاربر
- محاسبه Running Total یا Cumulative Total که باید محدود به بازه انتخابشده باشد، نه کل تاریخچه داده
- ساخت Measureهایی که باید نسبت به فیلترهای صریح حساس باشند، اما نسبت به گروهبندی داخلی Visual خنثی عمل کنند
مثال عملی
مثال محاسبه درصد از کل انتخابشده
فرض کنید جدولی از فروش محصولات در یک Matrix نمایش داده میشود که سطرهای آن بر اساس Products[ProductName] گروهبندی شده و کاربر میتواند از طریق یک Slicer، یک یا چند دستهبندی محصول را انتخاب کند.
Percent of Selected Total =
DIVIDE (
SUM ( Sales[Amount] ),
CALCULATE (
SUM ( Sales[Amount] ),
ALLSELECTED ( Products[ProductName] )
)
)
نکته مهم در این مثال این است که آرگومان ALLSELECTED دقیقاً همان ستونی است که در Visual بهعنوان گروهبندی سطر استفاده شده است. این کار باعث میشود فیلتر Row مربوط به ProductName که از گروهبندی سطرهای Matrix ناشی شده در Context داخلی Query کنار گذاشته شود، در حالی که فیلترهای صریح بیرونی، مانند محدوده انتخابشده کاربر در Slicer، حفظ شوند. در نتیجه، مقدار محاسبهشده در هر سطر، درصد سهم آن محصول از مجموع محصولاتی را نشان میدهد که در محدوده انتخاب فعلی قرار دارند، نه درصد از کل جدول بدون در نظر گرفتن فیلتر. هدف قرار دادن دقیق ستون مورد استفاده در گروهبندی Visual، بهجای استفاده کلی از ALLSELECTED(Sales)، نکتهای کلیدی در نوشتن صحیح این نوع Measureهاست.
مثال Running Total محدود به انتخاب کاربر
Running Total Within Selection =
CALCULATE (
SUM ( Sales[Amount] ),
FILTER (
ALLSELECTED ( Calendar[Date] ),
Calendar[Date] <= MAX ( Calendar[Date] )
)
)
در این Measure، تابع FILTER روی خروجی ALLSELECTED اعمال میشود تا تنها تاریخهایی که کوچکتر یا مساوی تاریخ سطر فعلی هستند در محاسبه لحاظ شوند. در صورتی که فیلتر بازه تاریخی بهعنوان یک Context بیرونی و صریح در سطح گزارش یا Slicer حفظ شود، Running Total بر اساس همان محدوده انتخابشده محاسبه خواهد شد و به دادههای خارج از آن بازه وابسته نخواهد بود.
مثال استفاده در سطح جدول بهجای ستون
Sales Percent of Report =
DIVIDE (
SUM ( Sales[Amount] ),
CALCULATE (
SUM ( Sales[Amount] ),
ALLSELECTED ()
)
)
استفاده از ALLSELECTED() بدون آرگومان، فیلترهای Row و Column تمام جداول درگیر در Query فعلی را نادیده میگیرد، در حالی که فیلترهای صریح مانند فیلتر سطح صفحه یا Slicer را حفظ میکند. این حالت معمولاً زمانی استفاده میشود که محاسبه باید نسبت به کل زمینه گزارش، نه یک ستون یا جدول خاص، سنجیده شود.
محدودیتهای مستند شده ALLSELECTED
یکی از نکات مهمی که در مستندات و منابع تخصصی DAX مانند SQLBI به آن اشاره شده، رفتار پیچیده و گاه غیرمنتظره ALLSELECTED در سناریوهای پیشرفته است.
نخست، رفتار ALLSELECTED در ردیف Total یک Visual مانند Table یا Matrix همیشه با انتظار اولیه کاربر یکسان نیست. از آنجا که ردیف Total خود یک سطر با Context متفاوت از سطرهای معمولی محسوب میشود، محاسبه ALLSELECTED در آن سطر ممکن است نتیجهای متفاوت از جمع ساده مقادیر سطرهای دیگر تولید کند.
دوم، رفتار ALLSELECTED به شدت به نحوه ساخت Visual و نوع Query تولیدشده توسط Power BI وابسته است. استفاده از همان Measure در ابزارهایی مانند DAX Studio که Visual واقعی پشت آن وجود ندارد، میتواند نتیجهای متفاوت از رفتار درون گزارش Power BI تولید کند، زیرا مفهوم Query Context که ALLSELECTED بر اساس آن عمل میکند، وابسته به ساختار Query برخاسته از Visual اصلی است.
سوم، تعامل بین Visualها، Cross-filtering و Cross-highlighting میتواند Context محاسبه را تغییر دهد و تحلیل رفتار ALLSELECTED را پیچیدهتر کند، زیرا در چنین سناریوهایی تشخیص اینکه کدام فیلتر Row/Column و کدام فیلتر صریح محسوب میشود، همیشه ساده نیست.
چهارم، ترکیب ALLSELECTED با Iteratorها مانند SUMX یا FILTER و همچنین وقوع Context Transition در داخل یک Measure میتواند رفتار نهایی را بهطور قابل توجهی پیچیدهتر کند. بهخصوص در Measureهایی که داخل Iterator اجرا میشوند، ALLSELECTED میتواند Contextهای ایجادشده در مراحل مختلف ارزیابی را تحت تأثیر قرار دهد. به همین دلیل، تحلیل آن صرفاً با مفهوم ساده «حذف فیلتر Visual» کافی نیست و نیازمند بررسی دقیق مرحلهبهمرحله Evaluation Context است.
محدودیت ALLSELECTED در Calculated Column و DirectQuery
ALLSELECTED عمدتاً برای Measureها و محاسباتی طراحی شده است که هنگام اجرای Query ارزیابی میشوند. Calculated Column هنگام Refresh مدل محاسبه میشود و Query Context ناشی از Visual را در اختیار ندارد. بنابراین استفاده از ALLSELECTED در Calculated Column برای محاسباتی که به رفتار Visual وابسته هستند، کاربرد مناسبی ندارد.
در مدلهای DirectQuery، استفاده از ALLSELECTED در Calculated Column و در قوانین Row-Level Security پشتیبانی نمیشود. این محدودیت بهصورت مشخص در مستندات رسمی Microsoft ذکر شده و مختص مدلهای DirectQuery است، نه یک محدودیت عمومی برای تمام مدلهای داده. در مدلهای Import، از نظر Syntax امکان استفاده از ALLSELECTED در Calculated Column وجود دارد، هرچند نتیجه آن معمولاً معنای مورد انتظار برای محاسبات مبتنی بر Visual را نخواهد داشت.
مزایای استفاده از ALLSELECTED
- امکان ساخت Visual Total منطبق با محدوده فیلترشده گزارش
- امکان محاسبه درصد و نسبتها نسبت به زیرمجموعه انتخابشده
- حفظ حساسیت Measure نسبت به فیلترهای صریح مانند Slicer و فیلتر سطح صفحه
- کاربرد طبیعی در محاسبات Running Total محدود به بازه انتخابی
محدودیتهای ALLSELECTED
- رفتار وابسته به ساختار Query برخاسته از Visual و غیرقابل تعریف دقیق در محیطهای بدون Visual مانند DAX Studio
- رفتار غیرمنتظره در ردیف Total برخی Visualها
- پیچیدگی در تحلیل رفتار هنگام استفاده همزمان با Cross-filtering، Cross-highlighting یا Visualهای مرتبط
- پیچیدگی بیشتر در ترکیب با Iteratorها و Context Transition نسبت به ALL یا REMOVEFILTERS
- عدم پشتیبانی در Calculated Column و RLS بهصورت اختصاصی در مدلهای DirectQuery
- دشواری Debug کردن نسبت به توابعی مانند ALL که رفتار قطعیتر و کمتر وابسته به Visual دارند
Best Practiceها
- استفاده از ALLSELECTED تنها در Measureهایی که قرار است در Visualهای تعاملی گزارش استفاده شوند
- تست رفتار واقعی Measureهای مبتنی بر ALLSELECTED مستقیماً درون Visual مقصد، نه صرفاً در DAX Studio یا محیط توسعه جدا از گزارش
- هدف قرار دادن دقیق همان ستونی که در Visual برای گروهبندی سطر یا ستون استفاده شده، بهجای استفاده کلی از ALLSELECTED در سطح جدول
- بررسی جداگانه رفتار Measure در ردیف Total پیش از انتشار نهایی گزارش
- پرهیز از استفاده ALLSELECTED در Calculated Column، بهویژه در مدلهای DirectQuery
- مستندسازی منطق ALLSELECTED در کامنتهای DAX، بهخصوص در Measureهای پیچیده که چند لایه CALCULATE و FILTER دارند
- استفاده از Variableها برای شفافسازی مراحل محاسبه در Measureهای ترکیبی مبتنی بر ALLSELECTED
اشتباهات رایج
- تصور اشتباه که ALLSELECTED مستقیماً انتخاب کاربر در Slicer را میخواند، بدون در نظر گرفتن اینکه رفتار آن ناشی از نوع فیلتر در Query است
- استفاده از ALLSELECTED بهجای ALL در سناریوهایی که هدف واقعی، محاسبه کل مطلق بدون وابستگی به هیچ فیلتری است
- استفاده از ALLSELECTED بهجای REMOVEFILTERS در Measureهایی که نیاز به حذف قطعی و کامل فیلتر دارند
- نادیده گرفتن رفتار متفاوت ALLSELECTED در ردیف Total نسبت به سطرهای معمولی Visual
- تست کردن Measure تنها در DAX Studio و انتشار آن بدون بررسی رفتار واقعی درون گزارش Power BI
- استفاده از ALLSELECTED در Calculated Column در مدلهای DirectQuery که این کار پشتیبانی نمیشود
جمعبندی
تابع ALLSELECTED در DAX ابزاری قدرتمند برای ساخت Visual Total و محاسبه مقادیر نسبی نسبت به زیرمجموعه انتخابشده در یک گزارش است. برخلاف ALL و REMOVEFILTERS که فیلترها را بهطور کامل و بدون قید و شرط حذف میکنند، ALLSELECTED بر اساس نوع فیلتر، یعنی فیلترهای Row و Column ایجادشده در Query در برابر فیلترهای صریح و سایر Contextها، تصمیم میگیرد کدام بخش حذف شود. این تابع خودش اطلاعی از قصد یا انتخاب کاربر ندارد، بلکه صرفاً بر اساس قواعد مشخص DAX، Contextهای موجود در هنگام ارزیابی Query را تغییر میدهد. این وابستگی به ساختار Query، هم قدرت اصلی این تابع و هم منشأ پیچیدگی و رفتارهای غیرمنتظره آن، بهویژه در ردیف Total، Calculated Column و محیطهای بدون Visual است. استفاده صحیح از ALLSELECTED نیازمند تست دقیق در Visual مقصد و درک روشن از تفاوت آن با ALL و REMOVEFILTERS است.
پرسشهای متداول FAQ
تفاوت اصلی ALLSELECTED و ALL چیست؟
ALL تمام فیلترهای مربوط به جدول یا ستون مشخصشده را بدون قید و شرط حذف میکند. ALLSELECTED تنها فیلترهای Row و Column ایجادشده در Query فعلی را حذف میکند و فیلترهای صریح مانند Slicer را حفظ میکند.
آیا ALLSELECTED و REMOVEFILTERS معادل یکدیگرند؟
خیر. REMOVEFILTERS از نظر رفتاری معادل ALL است و فیلتر را بهطور کامل حذف میکند، بدون اینکه یک Table Expression بازگرداند. ALLSELECTED رفتار متفاوتی دارد، زیرا بسته به نوع فیلتر تصمیم میگیرد کدام بخش حذف شود.
آیا ALLSELECTED واقعاً انتخاب کاربر در Slicer را میخواند؟
خیر. ALLSELECTED اطلاعی از قصد یا انتخاب کاربر ندارد. رفتار این تابع بر اساس نوع فیلتر موجود در Query، یعنی فیلترهای Row/Column در برابر فیلترهای صریح، تعیین میشود. در عمل، این رفتار در بسیاری از سناریوها معادل حفظ انتخاب کاربر به نظر میرسد، اما این نتیجهای از قواعد Context است، نه خواندن مستقیم انتخاب کاربر.
چرا نتیجه ALLSELECTED در DAX Studio با نتیجه آن در Power BI متفاوت است؟
اجرای یک Measure مبتنی بر ALLSELECTED در DAX Studio لزوماً همان Query Context را ایجاد نمیکند که Power BI هنگام اجرای Query یک Visual تولید میکند. برای تحلیل دقیق چنین Measureهایی باید ساختار Query و فیلترهای Row و Column موجود در آن بررسی شود.
آیا استفاده از ALLSELECTED در Calculated Column امکانپذیر است؟
در مدلهای Import از نظر Syntax امکانپذیر است، اما از نظر عملکردی توصیه نمیشود، زیرا Calculated Column هنگام Refresh محاسبه میشود و Query Context مرتبط با Visual را در اختیار ندارد. در مدلهای DirectQuery، استفاده از ALLSELECTED در Calculated Column و در Row-Level Security بهطور مشخص پشتیبانی نمیشود.
پیشنهاد مطالعه
- مرجع زبان DAX افزونه کوئری نویسی در اکسل و POWER BI
- مرجع زبان فرمول نویسی M در پاور کوئری
- طراحی داشبوردهای مدیریتی در Microsoft Power BI
مشاوره تخصصی Power BI و DAX با لاندا
اگر در طراحی Measureهای DAX، مدیریت Filter Context، محاسبه Visual Total یا بهینهسازی عملکرد گزارشهای Power BI با چالش مواجه هستید، تیم فنی توسعه فناوری اطلاعات لاندا میتواند در طراحی و بهینهسازی راهکار متناسب با ساختار داده و نیازهای کسبوکار شما کمک کند.
از طراحی مدل داده و توسعه داشبوردهای مدیریتی تا بهینهسازی Measureهای DAX و افزایش Performance گزارشهای Power BI، راهکارهای لاندا با تمرکز بر پایداری، دقت و عملکرد ارائه میشوند.
برای بررسی نیازهای پروژه و دریافت مشاوره تخصصی Power BI و DAX، با تیم لاندا در تماس ✆ باشید.


No comment