3.1 · CALCULATE وسياق التصفية (Filter Context) والمتغيرات (VAR)

المستوى 3 · التحليل المتقدم

3.1CALCULATE وسياق التصفية (Filter Context) والمتغيرات (VAR)

الهدف: قراءة سياق خلية مرئي بصوت عالٍ، وكتابة «النسبة من الإجمالي» عبر CALCULATE مع ALL وVAR، وتشخيص أي نتيجة DAX انطلاقًا من سياقها.
الوقت المقدّر: 25 دقيقة · قراءة ذاتية · إذا كان لديك 5 دقائق فقط: اقرأ «الأساسي في 30 ثانية» + المخطط.

الأساسي في 30 ثانية

  • لكل خلية في أي مرئي سياق تصفيتها الخاص: خلية «باريس × يناير» في مصفوفة تحسب [Total CA] مُرشحًا على باريس ويناير معًا، دون أن تكتب أي شيء.
  • تُعدّل CALCULATE هذا السياق: تضيف مرشحًا، أو تتجاوز آخر، أو تزيله عبر ALL — مفتاح «النسبة من الإجمالي».
  • VAR/RETURN تُهيكلان كل صيغة تتجاوز سطرًا واحدًا: وضوح، وأداء، وتصحيح أخطاء ميسّر.

حالة مصغّرة متسلسلة — زينب تقرأ خلاياها بصوت عالٍ بالجزائر

زينب، مراقبة التسيير في مؤسسة صغيرة ومتوسطة للصناعات الغذائية بالجزائر، تعرض مصفوفة المدينة × الشهر لـ [Total CA] وتبقى حائرة أمام خلية تبدو خاطئة. تطبّق منهج القسم: بدل إعادة كتابة المقياس، تقرأ السياق بصوت عالٍ — «هذه الخلية = رقم الأعمال مُرشحًا على ليون ويناير» — وتفهم أن لكل خلية سياقها. فتضيف CA Toutes villes = CALCULATE([Total CA]; ALL(Ventes[Ville])): القيمة نفسها في كل مكان، مع إزالة مرشح المدينة. ثم تجمع حصة كل مدينة بمتغيّر: Part ville = VAR Total = CALCULATE([Total CA]; ALL(Ventes[Ville])) RETURN DIVIDE([Total CA]; Total). وترشح مع مقسم بيانات (Slicer) للبائعين نشطًا: تُعاد الحصة داخل نطاق المقسم — وهو بالضبط ما تريد شرحه لإدارتها.

حالة قائمة بذاتها لهذا القسم: تعود في الدرس والمخطط والنصّ البرمجي وتحدي 48 ساعة للقسم 3.1.

1. سياق التصفية (Filter Context)

هذا هو الفصل الذي يفصل المستخدم عن ممارس DAX. يُحسب كل مقياس داخل سياق تصفية: فخلية «باريس × يناير» في مصفوفة تحسب [Total CA] مُرشحًا على باريس ويناير معًا — دون أن تكتب أي شيء. ولكل خلية في أي مرئي سياقها الخاص: تتراكم فيها المحاور ووسائل الإيضاح ومقسمات البيانات والمرشحات.

2. CALCULATE وALL وVAR

CALCULATE تُعدّل هذا السياق: تضيف مرشحًا، أو تتجاوز آخر (حصة الإجمالي)، أو تزيله عبر ALL. تتجاهل ALL(Ventes[Ville]) مرشح المدينة وتعطي الإجمالي العام — وهو مفتاح العملية الأكثر طلبًا: «النسبة من الإجمالي».

3. الهيكلة والتشخيص

نلفّ كل شيء في متغيرات VAR/RETURN: يُحسب الإجمالي العام مرة واحدة، وتُقرأ الصيغة بسلاسة، ويصبح تصحيح الأخطاء بسيطًا. ومنعكس التشخيص جملة واحدة: أي نتيجة DAX «غريبة» تكون غالبًا سياقًا مساء فهمه — تقرؤه زينب بصوت عالٍ قبل لمس الصيغة.

خطأ شائع في الفهم: «DAX صيغ تُحفظ عن ظهر قلب؛ والنتيجة الخاطئة تخفي خطأ في الكتابة، والسياق لا يغيّر شيئًا.» لا، ثلاثة أخطاء. أي نتيجة DAX «غريبة» تكون غالبًا سياق تصفية مساء فهمه: نقرؤه بصوت عالٍ أولًا وقبل كل شيء. CALCULATE لا تحسب «أكثر»: إنها تغيّر السياق — تضيف مرشحًا أو تتجاوزه أو تزيله (عبر ALL). وكل صيغة تتجاوز سطرًا واحدًا تُهيكل بـ VAR/RETURN، وإلا صارت غير مقروءة وكرّرت حساباتها.
تعديل سياق التصفية قراءة السياق، وتعديله بـ CALCULATE، وتصغيره بـ ALL — وهيكلته بـ VAR. سياق التصفيةما ترشحه الخلية (يُقرأ)+CALCULATEتضيف / تتجاوز مرشحًا+ALLتزيل المرشحات (النسبة من الإجمالي) VAR/RETURN متى تجاوزت الصيغة سطرًا واحدًا.
قراءة السياق، وتعديله بـ CALCULATE، وتصغيره بـ ALL — وهيكلته بـ VAR.
نص المخطط (SEO / قارئات الشاشة / الترجمة): 1) زينب، مراقبة التسيير بالجزائر، تقرأ السياق: خلية «ليون × يناير» في مصفوفتها = [Total CA] مُرشحًا على ليون ويناير معًا، دون أن تكتب أي شيء. 2) تُعدّله: CALCULATE([Total CA]; ALL(Ventes[Ville])) تزيل مرشح المدينة وتعيد الإجمالي لكل المدن؛ مُجمّعًا في متغيّر، يعطي حصة كل مدينة من الإجمالي. 3) تُهيكل بـ VAR/RETURN — الإجمالي العام محسوب مرة واحدة، وصيغة مقروءة، وتشخيص عبر السياق. الدرس: أي نتيجة غريبة تبدأ دائمًا بسياق مساء فهمه نقرؤه بصوت عالٍ.

🔎 مثال ملموس — 🔎 مثال ملموس — النسبة من الإجمالي

العملية الأكثر طلبًا، بصيغ قصيرة ومقروءة:

CA Toutes villes = CALCULATE([Total CA]; ALL(Ventes[Ville]))

Part ville =
VAR Total = CALCULATE([Total CA]; ALL(Ventes[Ville]))
RETURN DIVIDE([Total CA]; Total)   // منسّق بالنسبة %

القراءة: ALL(Ventes[Ville]) تزيل مرشح المدينة: فيعرض المقياس القيمة نفسها في كل سطر — الإجمالي لكل المدن.

الدرس: DIVIDE([Total CA]; Total) تعطي حصة كل مدينة، معادًا حسابها داخل نطاق مقسمات البيانات النشطة.

مفردات القسم

سياق التصفية (Filter Context)
مجموع المرشحات النشطة على خلية مرئي (المحاور، ووسائل الإيضاح، ومقسمات البيانات، والمرشحات): لكل خلية سياقها الخاص.

مثال بسيط: تعلن زينب: «خلية ليون × يناير = رقم الأعمال مُرشحًا على ليون ويناير».

ما ليس كذلك: حساب واحد صالح لكامل المرئي.

رد فعل: نتيجة غريبة ← اقرأ السياق بصوت عالٍ.

CALCULATE
تُقيّم تعبيرًا داخل سياق معدّل: تضيف مرشحًا أو تتجاوزه.

مثال بسيط: تفرض زينب مرشحًا على مدينة عبر CALCULATE لعزل نتيجتها.

ما ليس كذلك: مقياس يخضع للسياق دون تعديله.

رد فعل: تعديل مرشح ← CALCULATE.

ALL
تزيل المرشحات: تتجاهل ALL(Ventes[Ville]) مرشح المدينة — مفتاح «النسبة من الإجمالي».

مثال بسيط: تحسب زينب رقم الأعمال لكل المدن لمقارنة كل مدينة بالإجمالي.

ما ليس كذلك: مرشح يبقى نشطًا فيفسد الحصة.

رد فعل: النسبة من الإجمالي ← ALL على العمود.

VAR / RETURN
متغيرات DAX: نسمّي حسابًا وسيطًا مرة واحدة، ثم نعيده بـ RETURN.

مثال بسيط: تكتب زينب VAR Total = ... RETURN DIVIDE([Total CA]; Total).

ما ليس كذلك: حساب واحد مكرر ثلاث مرات في صيغة.

رد فعل: أكثر من سطر ← VAR/RETURN.

انتقال السياق (Context Transition)
الآلية المتقدمة التي تحوّل بها CALCULATE سياق الصف (Row Context) إلى سياق تصفية.

مثال بسيط: تعرف زينب تسميته وتنوي تعميقه عبر مرجع SQLBI.

ما ليس كذلك: مجرد سياق تصفية لخلية مرئي.

رد فعل: يُعرف بالاسم، ويُعمّق لاحقًا.

في التطبيق — تطبيق عملي — تشريح «النسبة من الإجمالي»

  1. أنشئ مصفوفة المدينة × [Total CA] واقرأ كل خلية معلنًا سياقها: «هذه الخلية = رقم الأعمال مُرشحًا على ليون»، مثل زينب.
  2. اكتب CA Toutes villes = CALCULATE([Total CA]; ALL(Ventes[Ville])) وأضفها إلى المصفوفة: القيمة نفسها في كل مكان (أُزيل مرشح المدينة).
  3. ركّب بالمتغيرات: Part ville = VAR Total = CALCULATE([Total CA]; ALL(Ventes[Ville])) RETURN DIVIDE([Total CA]; Total)، ثم نسّقها بالنسبة %.
  4. اختبر مع مقسم بيانات (Slicer) للبائعين نشطًا: تُعاد الحصة دَاخل نطاق المقسم — أعد قراءة الصيغة حتى تستطيع شرح السبب.
الثلاثي سياق + CALCULATE/ALL + VAR متقن على العملية الأكثر طلبًا: النسبة من الإجمالي.

نصّ خطوة بخطوة — اقرأ سياقًا مثل زينب (8 دقائق)

1) اعرض [Total CA] في مصفوفة، المدينة في السطور والشهر في الأعمدة. 2) انقر خلية وانطق سياقها: تقاطع المرشحين النشطين. 3) أنشئ CA Toutes villes = CALCULATE([Total CA]; ALL(Ventes[Ville])): تحقق من أن القيمة متطابقة في كل السطور. 4) أنشئ Part ville بـ VAR/RETURN: VAR Total = CALCULATE([Total CA]; ALL(Ventes[Ville])) RETURN DIVIDE([Total CA]; Total)، منسّقة بالنسبة %. 5) ضع مقسم بيانات للبائعين: لاحظ إعادة حساب الحصة داخل النطاق، واشرحه بصوت عالٍ.

إذا بدا إجمالي ما خاطئًا، فارجع إلى النقطة 2: في تسع حالات من عشر، السياق هو ما يفسّر النتيجة.

نموذج للنسخ واللصق — مقاييس سياقي

CA Toutes villes = CALCULATE([Total CA]; ALL(Ventes[Ville]))

Part ville =
VAR Total = CALCULATE([Total CA]; ALL(Ventes[Ville]))
RETURN DIVIDE([Total CA]; Total)   // %

قاعدة: اقرأ السياق ← عدّله (CALCULATE/ALL) ← هيكله (VAR/RETURN).

الحصة من الإجمالي

تعرض زينب حصة كل مدينة في الإجمالي العام: تركيبة CALCULATE + ALL + VAR، منسّقة بالنسبة %.

الإجمالي لكل المدن

تعزل زينب الإجمالي العام بـ ALL(Ventes[Ville]): القيمة نفسها مكررة على كل سطر، مرجع ثابت.

تشخيص خلية

نتيجة مشكوك فيها: تقرأ زينب السياق بصوت عالٍ قبل لمس المقياس — غالبًا يكون الخطأ هناك.

صيغة مقروءة

مقياس من خمسة أسطر يصبح واضحًا بفضل VAR: الحساب مسمّى مرة واحدة، وRETURN في النهاية.

✓ ممارسات جيدة

  • اقرأ سياق أي خلية بصوت عالٍ لفهم أي نتيجة.
  • استخدم VAR/RETURN منهجيًا متى تجاوزت الصيغة سطرًا واحدًا.
  • ابدأ كل تشخيص من سياق التصفية.

✗ أخطاء شائعة

  • كتابة CALCULATE متداخلة غير مقروءة دون متغيرات.
  • الخلط بين ALL (تزيل الكل) وALLSELECTED (تحترم مقسمات البيانات).
  • البحث عن الخطأ في غير السياق.

النقاط الأساسية

  • لكل خلية مرئي سياق تصفيتها الخاص: اقرؤوه بصوت عالٍ لفهم أي نتيجة.
  • تضيف CALCULATE المرشحات أو تتجاوزها؛ وتزيلها ALL: تغطي الإيماءتان أغلب الاحتياجات.
  • VAR/RETURN منهجيًا متى تجاوزت الصيغة سطرًا: الوضوح والأداء معًا.
  • أي نتيجة DAX «غريبة» = سياق مساء فهمه: يبدأ التشخيص دائمًا من هناك.

تحدي 48 ساعة — طبّقه غدًا

أعِد إنتاج مصفوفة زينب: [Total CA] حسب المدينة، ثم أضف CALCULATE([Total CA]; ALL(Ventes[Ville])) والمقياس Part ville المبني بـ VAR/RETURN. اكتب في جملة واحدة لماذا تُعاد حصة كل مدينة عندما يوضع مقسم بيانات.

قائمة الخروج من القسم
  • أستطيع قراءة سياق التصفية لأي خلية مرئي.
  • أعرف كتابة النسبة من الإجمالي بـ CALCULATE + ALL + VAR.
  • أشخّص أي نتيجة DAX انطلاقًا من السياق.
تقييم ذاتي 1-5: هل أشرح سياق التصفية دون غموض؟تقييم ذاتي 1-5: هل بنيت النسبة من الإجمالي بـ VAR/RETURN؟

أسئلة شائعة

ALL وALLSELECTED وALLEXCEPT: كيف نميز بينها؟

تزيل ALL كل مرشح على الهدف (الإجمالي العام)؛ وتحترم ALLSELECTED التحديدات الخارجية، مثل مقسمات البيانات؛ وتزيل ALLEXCEPT الكل باستثناء الأعمدة المذكورة. ابدؤوا بـ ALL، وانتقلوا إلى ALLSELECTED متى وجب أن تتبع النسبة مقسمات البيانات، واحتفظوا بـ ALLEXCEPT لاحقًا — وتتضح الحالات الدقيقة بالممارسة ومرجع SQLBI.

لماذا يكون مقياسي صحيحًا في التفصيل وخاطئًا في سطر الإجمالي؟

لأن سطر الإجمالي له سياق أوسع: لا مرشح مدينة نشط فيه. ويتدهور فيه أي مقياس مبني خطأً — والحالة الكلاسيكية هي متوسط النسب. والحل المعتاد هو إعادة الحساب بالتكرار عبر SUMX بدل توسط نتيجة مجمعة سلفًا. والمنعكس: صحيح في التفصيل، خاطئ في الإجمالي ← اشتبهوا في نسبة في غير موضعها.

تحقّق من فهمك

ما فائدة ALL داخل CALCULATE؟

موارد إضافية (اختياري، للتعمّق أكثر)

اختبار المستوى 3أسئلة جديدة وأصعب للتحقق من مكتسباتك