שני עמודי דשבורד שכל מספר בהם מגיע ממדד שאתם כותבים מאפס, עם חיווי צבע אוטומטי
לרווחיות המובילים. עובדים על Logistics_PowerBI_Star.xlsx — סכמת כוכב טהורה עם טבלת עובדות
אחת, שבעה מימדים ו-28,400 שורות משלוח. 29 תרגילים, כל אחד בדף נפרד ועם פתרון
מלא. שימו לב: ההורדה והתרגול הם במחשב בלבד — Power BI Desktop אינו קיים בטלפון.
הנתונים סינתטיים. שמות הערים והמדינות אמיתיים, אבל כל לקוח, מוביל, משלוח ומספר בקובץ נוצרו באופן מלאכותי עם זרע אקראי קבוע. אין להסיק מהם דבר על שוק השילוח האמיתי.
לפני שמתחילים — בניית המודל. בקובץ שבעה קשרים בדיוק, כולם מהמימד אל טבלת העובדות. סמנו את Dim_Date כטבלת תאריכים (Mark as date table על Full_Date), כבו Autodetect ובנו ידנית, וודאו שכל קשר הוא One to many בכיוון Single מהמימד אל Fact_Shipments. גיליון Relationships בקובץ מפרט את שבעת הקשרים אחד-אחד. אין קשר מימד-למימד ואין טבלת גשר — כל מימד נוגע ישירות בעובדות ורק בהן.
המלכודת הגדולה של הקובץ הזה. בטבלת Dim_Carrier יש 12 מובילים, אבל בטבלת העובדות מופיעים רק 11. השורה Danube Barge Union היא שורת מימד שאף שורת עובדה לא מפנה אליה. המשמעות מעשית ומיידית: ויזואל שמציג מובילים יראה 11 שורות ולא 12, כי Power BI מסתיר ברירת-מחדל ערכי מימד בלי נתונים; COUNTROWS ( Dim_Carrier ) יחזיר 12 בעוד DISTINCTCOUNT ( Fact_Shipments[Carrier_ID] ) יחזיר 11; ובכל פונקציית חלון שנשענת על ALLSELECTED ( Dim_Carrier[Carrier_Name] ) תופיע שורה שתים-עשרה ריקה שתשבש דירוג, חציון ואחוז מצטבר אם לא תסננו אותה. שתי המלכודות הקטנות: עמודת Revenue_Per_KG_USD היא יחס ואסור לסכם אותה, ושורות Cancelled ו-Returned נושאות הכנסה שלא מומשה.
מילון סוגריים.Table[Column] = עמודה · [מדד] = סוגריים מרובעים בלי שם טבלה. לכל מדד: קליק ימני על Fact_Shipments בחלונית Data ← New measure ← הנוסחה ← Enter. השם חייב להיות בדיוק כפי שמופיע בתרגיל, אחרת המדדים שבנויים עליו לא ימצאו אותו.
מבנה המטלה
חלק 1
14 מדדי DAX
עשרה מדדי בסיס — שני SUM, שני DISTINCTCOUNT, DIVIDE, שני CALCULATE, ALL, IF ושני SWITCH — ושלוש פונקציות חלון: RANK, INDEX ו-WINDOW. ועוד תרגיל אחד שבו לא כותבים מדד אלא מסבירים למה תשובה נאיבית שגויה.
חלק 2
שני עמודי דשבורד
מגש KPI, גרף קו מוחלק, סלייסר בעמוד שני, טבלת פירוט, Top N, Matrix, גרף משולב, דונאט מול עמודות, small multiples, פיזור ועמוד פוליש.
חלק 3
עיצוב מותנה ותובנה
שתי דרכים לצבוע לפי רמת רווחיות — Field value מול Rules — ושאלת סיכום אחת: מיהו המוביל שמוביל בהכנסות ואינו הרווחי.
שבעת הקשרים במודל
מהמימד
אל טבלת העובדות
סוג
Dim_Date[Date_ID]
Fact_Shipments[Ship_Date_ID]
1:Many · Single
Dim_Customer[Customer_ID]
Fact_Shipments[Customer_ID]
1:Many · Single
Dim_Carrier[Carrier_ID]
Fact_Shipments[Carrier_ID]
1:Many · Single
Dim_Route[Route_ID]
Fact_Shipments[Route_ID]
1:Many · Single
Dim_Service_Level[Service_Level_ID]
Fact_Shipments[Service_Level_ID]
1:Many · Single
Dim_Warehouse[Warehouse_ID]
Fact_Shipments[Warehouse_ID]
1:Many · Single
Dim_Cargo_Type[Cargo_Type_ID]
Fact_Shipments[Cargo_Type_ID]
1:Many · Single
כל המספרים בעמודים הבאים אומתו ב-pandas מול הקובץ
1.1 · Total Freight Revenue — מדד הבסיס
צרו מדד בשם Total Freight Revenue שמסכם את Fact_Shipments[Freight_Revenue_USD]. עצבו עם מפריד אלפים ושתי ספרות.
Total Freight Revenue =
SUM (
Fact_Shipments[Freight_Revenue_USD]
)
יצירהקליק ימני על Fact_Shipments ← New measure
עיצובבלשונית Measure tools בחרו Decimal number ו-2 ספרות
בדיקהגררו לקארד ריק כדי לוודא שהמספר מופיע
שימו לב לפני שממשיכים: המספר הזה כולל את כל ארבעת הסטטוסים — גם Cancelled וגם Returned. זו הכנסה רשומה, לא הכנסה שמומשה. בתרגיל 1.6 נצמצם אותה, ותראו בדיוק כמה נשר.
תוצאה: 8,466,765.26 דולר — מספר העוגן של כל המטלה.
1.2 · Total Weight Shipped — עמודה שנייה, לא אותה עמודה
צרו מדד בשם Total Weight Shipped שמסכם את Fact_Shipments[Weight_KG]. ספרה עשרונית אחת.
Total Weight Shipped =
SUM ( Fact_Shipments[Weight_KG] )
למה דווקא העמודה הזאת: בטבלת העובדות יש גם Volume_M3, וגם היא אדיטיבית לגמרי. ההבדל הוא מה שהמדד הבא יעשה איתה — משקל הוא המכנה שמקובל בענף לתמחור שילוח, ולכן הוא זה שיזין את Revenue per KG בתרגיל 1.5.
תוצאה: 26,825,847.8 ק"ג.
1.3 · Active Customers — ספירה ייחודית ראשונה
צרו מדד בשם Active Customers שסופר לקוחות ייחודיים על בסיס Fact_Shipments[Customer_ID].
Active Customers =
DISTINCTCOUNT (
Fact_Shipments[Customer_ID]
)
למה לא COUNT:COUNT ( Customer_ID ) היה מחזיר 28,400 — הוא סופר שורות שיש בהן ערך, לא ערכים ייחודיים. כל לקוח שלח בממוצע 157.8 משלוחים בשנתיים, ולכן הפער עצום.
ולמה לא לספור את המימד:COUNTROWS ( Dim_Customer ) יחזיר גם הוא 180, כי במקרה של הלקוחות כל שורת מימד באמת מופיעה בעובדות. בתרגיל 1.12 תראו מימד שבו זה בדיוק לא נכון.
תוצאה: 180 לקוחות פעילים.
1.4 · Routes Used — ספירה ייחודית שנייה, עמודה אחרת
צרו מדד בשם Routes Used שסופר נתיבים ייחודיים על בסיס Fact_Shipments[Route_ID].
Routes Used =
DISTINCTCOUNT (
Fact_Shipments[Route_ID]
)
ההבדל משני המדדים הקודמים: שני מדדי הסכימה עבדו על שתי עמודות מידה שונות, ושני מדדי הספירה עובדים על שני מפתחות זרים שונים. זו לא חזרה — כל אחד מהארבעה נוגע בעמודה אחרת בטבלת העובדות, ולכן כל אחד מהם מגיב אחרת לסינון.
תוצאה: 60 נתיבים בשימוש, מתוך 60 ב-Dim_Route.
1.5 · Revenue per KG — עקרון הלגו
צרו מדד בשם Revenue per KG — אך ורק משני המדדים הקיימים, בלי סימן החלוקה / ובלי AVERAGE. עצבו לארבע ספרות.
Revenue per KG =
DIVIDE (
[Total Freight Revenue],
[Total Weight Shipped]
)
למה DIVIDE ולא /: אם המכנה יוצא אפס או ריק — ולקוח בלי משלוחים בהקשר מסוים בדיוק כזה — הסימן / מחזיר שגיאה שמכתימה את כל הויזואל, בעוד DIVIDE מחזיר ריק בשקט.
ולמה משני מדדים ולא מעמודות: כשהמדד בנוי משני מדדים קיימים, הוא מתחשב בהקשר הסינון בכל תא בנפרד ומחשב מחדש את המונה ואת המכנה. בתרגיל 1.15 נראה בדיוק מה קורה כשמנסים לקצר את הדרך.
תוצאה: 0.3156 דולר לק"ג (8,466,765.26 חלקי 26,825,847.8).
1.6 · Delivered Revenue — CALCULATE הראשון
צרו מדד בשם Delivered Revenue שמחזיר את ההכנסה של משלוחים בסטטוס Delivered בלבד, בעזרת CALCULATE עם פילטר בוליאני אחד.
מה בדיוק CALCULATE עושה כאן: הוא לא מסנן את המדד — הוא משנה את הקשר הסינון שבתוכו המדד מחושב. הפילטר Fact_Shipments[Shipment_Status] = "Delivered" הוא קיצור ל-FILTER ( ALL ( ... ) , ... ), כלומר הוא מחליף כל סינון סטטוס שכבר קיים בויזואל. אם תשימו את המדד הזה בטבלה שמפולחת לפי סטטוס, כל השורות יראו את אותו מספר.
תוצאה: 7,444,128.27 דולר. הפער מול מדד הבסיס — 1,022,636.99 דולר, שהם 12.08% הכנסה רשומה שלא מומשה.
1.7 · On Time Delivered Revenue — שני תנאים עם &&
צרו מדד בשם On Time Delivered Revenue שמחזיר את ההכנסה של משלוחים שגם נמסרו וגם הגיעו בזמן: Shipment_Status = "Delivered"וגםOn_Time_Status = "On_Time". חייבים להשתמש ב-&& בתוך תנאי אחד, לא בשני פילטרים נפרדים.
On Time Delivered Revenue =
VAR Ok =
FILTER (
Fact_Shipments,
Fact_Shipments[Shipment_Status]
= "Delivered"
&& Fact_Shipments[On_Time_Status]
= "On_Time"
)
RETURN
CALCULATE ( [Total Freight Revenue], Ok )
למה FILTER ולא שני פילטרים בוליאניים: שני פילטרים נפרדים ב-CALCULATE מצטלבים ומחזירים כאן בדיוק את אותה תוצאה — אבל התרגיל מבקש תנאי מרוכב אחד, וזה מה ש-&& נותן. ההבדל האמיתי מתגלה כשרוצים או במקום וגם: את || אי אפשר לבטא בשני פילטרים נפרדים, ורק FILTER יאפשר זאת.
המחיר של FILTER: הוא סורק את טבלת העובדות שורה-שורה. על 28,400 שורות זה לא מורגש, על עשרה מיליון זה כן. הכלל: פילטר בוליאני כשאפשר, FILTER כשחייבים.
תוצאה: 5,159,284.25 דולר — 69.31% מההכנסה שנמסרה.
1.8 · Pct of Grand Total — ALL על שני מימדים
צרו מדד בשם Pct of Grand Total שמחזיר את חלקו של כל תא מתוך סך הכל, כשהמכנה מנוטרל מסינון של שני מימדים בבת אחת — Dim_Carrier ו-Dim_Service_Level. עצבו כאחוז.
Pct of Grand Total =
VAR Grand =
CALCULATE (
[Total Freight Revenue],
ALL ( Dim_Carrier ),
ALL ( Dim_Service_Level )
)
RETURN
DIVIDE (
[Total Freight Revenue],
Grand
)
למה ALL על הטבלה ולא על העמודה:ALL ( Dim_Carrier ) מנטרל את כל עמודות המימד בבת אחת — גם Carrier_Name וגם Carrier_Mode וגם Contract_Tier. אם תכתבו ALL ( Dim_Carrier[Carrier_Name] ) וב-Matrix תשימו את סוג המוביל בשורות, המכנה עדיין יסתנן לפי הסוג והאחוזים לא יסתכמו ל-100.
Matrix מוביל × רמת שירות — בדיקת שפיות
תא
הכנסה בדולר
אחוז מסך הכל
Northwind Freight × Express
346,752.47
4.0955%
Northwind Freight — כל השורה
1,655,574.35
19.5538%
סך כל התאים
8,466,765.26
100.00%
הבדיקה שסוגרת את התרגיל: הפעילו סיכומי שורות ועמודות ב-Matrix. אם התא התחתון-הימני מציג 100.00% בדיוק — המכנה נכון. אם הוא מציג משהו אחר, ALL לא מכסה את כל מה שנמצא בויזואל.
תוצאה: התא Northwind Freight × Express = 4.0955%; סך כל התאים 100.00%.
1.9 · Revenue vs Prev Month — IF מול התקופה הקודמת
צרו מדד בשם Revenue vs Prev Month שמחזיר את המחרוזת Up אם ההכנסה בחודש הנוכחי גדולה או שווה להכנסה בחודש הקודם, ואחרת Down. השתמשו בשני משתני VAR.
Revenue vs Prev Month =
VAR Cur = [Total Freight Revenue]
VAR Prev =
CALCULATE (
[Total Freight Revenue],
DATEADD (
Dim_Date[Full_Date],
-1,
MONTH
)
)
RETURN
IF ( Cur >= Prev, "Up", "Down" )
למה זה עובד רק אחרי Mark as date table:DATEADD היא פונקציית מודיעין-זמן, והיא דורשת טבלת תאריכים רציפה ומסומנת. Dim_Date מכילה 731 ימים רצופים בלי חור אחד — זה לא מקרי, זו הדרישה.
ולמה לא לחסר מהחודש הקודם ידנית:Month_Number - 1 נשבר בינואר. DATEADD יודע לחצות שנה.
שתי בדיקות שכדאי להריץ
חודש
הכנסה
חודש קודם
תוצאת המדד
2025-12
437,472.12
433,142.51
Up
2025-02
225,297.76
249,097.61
Down
תוצאה: מתוך 23 השוואות חודש-מול-חודש בקובץ, 12 מחזירות Up. החודש החזק הוא 2025-10 עם 507,396.90 דולר, והחלש הוא 2025-02 עם 225,297.76.
1.10 · Margin Tier — SWITCH ( TRUE () )
צרו מדד בשם Margin Tier שמסווג כל מוביל לפי אחוז המרווח הגולמי שלו לשלוש רמות: Leader מ-20% ומעלה, Challenger מ-12% ומעלה, וכל השאר Laggard. השתמשו ב-SWITCH עם TRUE.
למה SWITCH ( TRUE () ) ולא IF מקונן: IF מקונן בשלוש רמות עדיין קריא, בשש הוא כבר לא. SWITCH עם TRUE שומר על טור אחד של תנאים שנבדקים מלמעלה למטה, והראשון שמתקיים מנצח — ולכן הסדר קריטי: אם תשימו את סף ה-12% ראשון, כל מוביל מעל 20% יסווג כ-Challenger ואף אחד לא יגיע ל-Leader.
הסיווג בפועל — 11 המובילים הפעילים
מוביל
הכנסה בדולר
מרווח %
רמה
Northwind Freight
1,655,570.42
20.30%
Leader
Rhine Express Group
1,467,050.34
22.88%
Leader
Baltic Haulage
1,037,060.51
13.75%
Challenger
Iberia Cargo Lines
874,699.14
16.35%
Challenger
Nordic Rail Freight
661,534.78
25.66%
Leader
Channel Sea Lines
646,970.08
27.93%
Leader
Skyway Air Cargo
526,805.38
12.25%
Challenger
Adriatic Transport
516,126.52
11.23%
Laggard
Alpine Rail Cargo
434,400.54
17.97%
Challenger
Atlantic Bulk Ships
378,313.23
29.55%
Leader
Meridian Air Freight
268,234.32
9.74%
Laggard
תוצאה: 5 Leader, 4 Challenger ו-2 Laggard. ברמת סך הכל המדד מחזיר Leader, כי המרווח הכולל הוא 19.44%.
1.11 · Tier Color — SWITCH על ערך
צרו מדד בשם Tier Color שמקבל את התוצאה של Margin Tier ומחזיר קוד צבע הקסה. זה SWITCH על ערך, לא SWITCH עם TRUE — שימו לב להבדל.
ההבדל בין שני ה-SWITCH: בתרגיל הקודם הארגומנט הראשון היה TRUE () וכל ענף היה ביטוי בוליאני שלם. כאן הארגומנט הראשון הוא ערך — [Margin Tier] — וכל ענף הוא ערך להשוואה. הצורה השנייה קצרה יותר וגם מהירה יותר, אבל היא עובדת רק כשמשווים ערך אחד לרשימת אפשרויות.
למה שלושה ענפים ולא ארבעה: הארגומנט האחרון בלי זוג הוא ברירת המחדל. בלעדיו, כל ערך לא צפוי היה מחזיר ריק והתא היה נצבע שקוף.
תוצאה: המדד מחזיר #132449 לחמשת ה-Leader, #F5C518 לארבעת ה-Challenger ו-#A9B4CC לשני ה-Laggard. בפרק III נחבר אותו לעיצוב מותנה.
1.12 · Carrier Rank by Shipments — RANK לפי כמות
צרו מדד בשם Carrier Rank by Shipments שמדרג את המובילים לפי מספר המשלוחים — לא לפי הכנסה. דירוג מדלג (SKIP), מהגבוה לנמוך, עם ORDERBY מפורש.
למה ALLSELECTED ולא ALL:ALL היה מתעלם גם מסלייסרים שהמשתמש בחר, והדירוג היה תמיד מול כל 12 המובילים. ALLSELECTED מנטרל רק את הסינון שהויזואל עצמו מייצר ומכבד את הסלייסרים — כך שאם המשתמש מסנן לשלושה מובילים, הדירוג רץ 1 עד 3.
וכאן נפגשים עם המלכודת.ALLSELECTED ( Dim_Carrier[Carrier_Name] ) מחזיר 12 שמות — כולל Danube Barge Union שאין לו אף שורת עובדה. COUNTROWS ( Fact_Shipments ) מחזיר עבורו ריק, וברירת המחדל של RANK (KEEP) דוחפת ריקים לסוף. לכן הדירוג האחרון בטבלה יהיה 12 ולא 11 — ואם תפעילו Show items with no data תראו אותו על המסך.
הדירוג המלא
דירוג
מוביל
משלוחים
1
Northwind Freight
5,507
2
Rhine Express Group
4,900
3
Baltic Haulage
3,517
4
Iberia Cargo Lines
2,958
5
Nordic Rail Freight
2,270
6
Channel Sea Lines
2,118
7
Skyway Air Cargo
1,784
8
Adriatic Transport
1,712
9
Alpine Rail Cargo
1,481
10
Atlantic Bulk Ships
1,253
11
Meridian Air Freight
900
12
Danube Barge Union
ריק
תוצאה: Northwind Freight במקום הראשון עם 5,507 משלוחים; Meridian Air Freight במקום 11; והמוביל היתום במקום 12 עם ערך ריק.
1.13 · Median Carrier Revenue — INDEX על ערך החציון
צרו מדד בשם Median Carrier Revenue שמחזיר את הכנסת המוביל החציוני — לא הממוצע ולא המוביל. השתמשו ב-INDEX עם ORDERBY עולה, וסננו קודם את המובילים בלי נתונים.
למה FILTER על NOT ISBLANK: בלי השורה הזאת COUNTROWS ( Carriers ) היה מחזיר 12 במקום 11, MidPos היה יוצא 6 מתוך 12 — וזה כבר לא החציון אלא הפריט השישי ברשימה שהראשון בה ריק. המלכודת של הקובץ מזיזה את התוצאה בשורה שלמה.
למה ROUNDUP ולא ROUND: ב-11 פריטים החציון הוא הפריט השישי — 11 חלקי 2 הוא 5.5, ורק עיגול כלפי מעלה נותן 6. עיגול רגיל היה נותן 6 גם כן, אבל ב-13 פריטים (6.5) הוא היה נותן 6 במקום 7.
מה INDEX מחזיר: לא מספר אלא שורה. לכן הוא יושב כארגומנט פילטר בתוך CALCULATE, ולא כערך שמחזירים ישירות.
תוצאה: 646,970.08 דולר — Channel Sea Lines, המקום ה-6 מתוך 11 במיון עולה. בדיקה עצמאית ב-pandas על אותם 11 ערכים נותנת 646,970.08 — זהה.
1.14 · Cumulative Pct of Revenue — WINDOW מצטבר באחוזים
צרו מדד בשם Cumulative Pct of Revenue שמחזיר את האחוז המצטבר מההכנסה, כשהמובילים מסודרים מהגדול לקטן. השתמשו ב-WINDOW מהשורה המוחלטת הראשונה ועד השורה הנוכחית.
לקרוא את ארבעת המספרים:1, ABS = התחל בשורה הראשונה של הרשימה כולה, ללא תלות במיקום הנוכחי. 0, REL = סיים בשורה הנוכחית (0 שורות ממנה). זה בדיוק ההגדרה של חלון מצטבר. אילו כתבתם -2, REL במקום 1, ABS, הייתם מקבלים חלון נגרר של שלוש שורות במקום צבירה.
למה שני VAR ולא אחד: המונה הוא סכום החלון והמכנה הוא סך הכל של אותה רשימה. שניהם משתמשים באותו ALLSELECTED — וזה מה שמבטיח שהאחוז האחרון יהיה בדיוק 100 ולא 99.7.
האחוז המצטבר, מהגדול לקטן
מוביל
הכנסה בדולר
מצטבר %
Northwind Freight
1,655,570.42
19.55%
Rhine Express Group
1,467,050.34
36.88%
Baltic Haulage
1,037,060.51
49.13%
Iberia Cargo Lines
874,699.14
59.46%
Nordic Rail Freight
661,534.78
67.27%
Channel Sea Lines
646,970.08
74.92%
Skyway Air Cargo
526,805.38
81.14%
Adriatic Transport
516,126.52
87.23%
Alpine Rail Cargo
434,400.54
92.36%
Atlantic Bulk Ships
378,313.23
96.83%
Meridian Air Freight
268,234.32
100.00%
תוצאה: שלושת המובילים הראשונים מחזיקים 49.13% מההכנסה, והשורה האחרונה מגיעה בדיוק ל-100.00%.
1.15 · תרגיל הסבר — למה הקיצור בעמודת היחס שגוי
בתרגיל הזה לא כותבים מדד. סטודנט הסתכל על Fact_Shipments[Revenue_Per_KG_USD], ראה שהיא כבר מחשבת הכנסה לק"ג בכל שורה, וכתב במקום התרגיל 1.5 את זה:
Naive Revenue per KG =
AVERAGE (
Fact_Shipments[Revenue_Per_KG_USD]
)
התוצאה שלו: 0.3815. התוצאה הנכונה מתרגיל 1.5: 0.3156. הפער הוא 20.9%. הסבירו במילים שלכם מדוע המדד שלו שגוי, ולא רק שונה. ענו לפני שפותחים.
התשובה: ממוצע של יחסים אינו היחס של הממוצעים.Revenue_Per_KG_USD היא עמודת יחס — מונה חלקי מכנה ברמת השורה. כשמחשבים עליה AVERAGE, כל משלוח מקבל משקל זהה: משלוח של 30 ק"ג משפיע על התוצאה בדיוק כמו משלוח של 20,000 ק"ג.
ולמה זה מטה כלפי מעלה דווקא: בקובץ הזה ההכנסה בנויה מרכיב קבוע לכל משלוח ועוד רכיב לפי משקל. משלוחים קטנים נושאים את אותו רכיב קבוע על מעט מאוד ק"ג, ולכן היחס שלהם גבוה מאוד. הם רבים במספר ומעטים במשקל — ולכן ממוצע פשוט, שסופר משלוחים, מנופח לעומת חישוב שמשקלל לפי ק"ג.
מתי בכל זאת מותר לסכם עמודה נגזרת: כש-SUM עליה שווה לנוסחה על הסכומים. Gross_Margin_USD עומדת במבחן — סכום ההפרשים שווה להפרש הסכומים, ולכן SUM ( Gross_Margin_USD ) תקין לגמרי. Revenue_Per_KG_USD נכשלת, וגם סכום שלה (10,834.60) הוא מספר חסר משמעות.
הכלל לזכור: חיבור וחיסור עוברים את הסכימה, כפל וחילוק לא. כל עמודה שהיא יחס, אחוז או ממוצע — נוגעים בה רק דרך מדד שמחשב מחדש מהמונה ומהמכנה.
אין כאן מדד לבדוק. הבדיקה היא שהסברתם את שני הדברים: שהמשקל בממוצע פשוט הוא מספר המשלוחים ולא מספר הק"ג, ושהמבחן הוא האם הסכימה עוברת דרך הפעולה.
2.1 · עמוד ראשון — רקע, כותרת ומגש KPI
בנו את שלד העמוד הראשון: רקע כהה, כותרת, ומגש של ארבעה מקומות ריקים לקארדים. עדיין בלי הקארדים עצמם — רק הפריסה.
כותרתInsert ← Text box ← "Freight Performance" ← 28pt ← לבן
מגשInsert ← Shapes ← Rectangle ← מלא #132449 ← פינות 12 ← רוחב מלא, גובה 140px
שם העמודקליק ימני על הלשונית ← Rename ← Overview
למה מגש ולא ארבעה רקעים נפרדים: ארבעה מלבנים נפרדים דורשים יישור ידני של ארבעה גבהים. מלבן אחד מאחורי ארבעה קארדים שקופים נשאר מיושר תמיד, וגם מייצר קו רציף שהעין קוראת כשורה אחת.
סדר השכבות:Format ← Selection pane. המגש חייב להיות מתחת לקארדים. אם קארד נעלם — הוא מאחורי המלבן, לא נמחק.
בסוף התרגיל: עמוד בשם Overview, רקע כהה, כותרת לבנה למעלה ומלבן כהה ריק ברוחב מלא. שום נתון עדיין.
2.2 · גרף קו מוחלק — ההכנסה החודשית
הוסיפו Line chart עם Dim_Date[Year_Month] בציר ו-Total Freight Revenue בערכים. החליקו את הקו, כבו את הסמנים, והוסיפו קו ממוצע.
ויזואלLine chart ← ציר: Year_Month ← ערכים: Total Freight Revenue
החלקהFormat ← Lines ← Shape ← Smooth line ← On
עוביLines ← Stroke width ← 3 ← צבע #F5C518
קו ממוצעAnalytics ← Average line ← Add ← מקווקו
צירY axis ← Display units ← Thousands
שיא ושפל בקובץ
חודש
הכנסה בדולר
2025-10 — השיא
507,396.90
2025-02 — השפל
225,297.76
2024-12
423,149.65
2025-12
437,472.12
מתי החלקה מטעה: קו מוחלק מצייר עקומה בין הנקודות, ולכן הוא ממציא ערכים שלא קיימים בין חודש לחודש. בסדרה חודשית זה מקובל כי המגמה חשובה מהנקודה. בסדרה עם קפיצה חדה — למשל שינוי מדיניות — ההחלקה תסתיר בדיוק את מה שרציתם להראות. שם כבו אותה.
שימו לב לעונתיות: ספטמבר עד דצמבר גבוהים בעקביות בשתי השנים, וינואר-פברואר נמוכים. זה מובנה בנתונים ולא רעש.
בסוף התרגיל: הקו מטפס לשיא של 507,396.90 ב-2025-10 ויורד ל-225,297.76 ב-2025-02.
2.3 · עמוד שני וסלייסר מסונכרן
צרו עמוד שני בשם Detail, הוסיפו סלייסר על Dim_Service_Level[Service_Level_Name], וסנכרנו אותו כך שיפעל על שני העמודים אבל יוצג רק באחד.
עמוד+ בתחתית ← Rename ← Detail
סלייסרSlicer ← שדה: Service_Level_Name
סגנוןFormat ← Slicer settings ← Style ← Tile
מיוןMore options ← Sort by ← Priority_Rank ← עולה
סנכרוןView ← Sync slicers ← סמנו Sync בשני העמודים, Visible רק ב-Detail
למה למיין לפי Priority_Rank ולא לפי שם: מיון אלפביתי ייתן Bulk, Economy, Express, Same_Day, Standard — סדר חסר משמעות. Priority_Rank נמצא במימד בדיוק בשביל זה, ונותן סדר מהיר-לאיטי.
מה סנכרון עושה ומה לא: הוא משתף את הבחירה בין עמודים, לא את הויזואל. אם תשנו עיצוב באחד — השני לא ישתנה. ואם תשכחו לסמן Sync בעמוד השני, הסלייסר יעבוד רק במקום שבו הוא מוצג.
חמש רמות השירות
רמה
הכנסה בדולר
משלוחים
מרווח %
Standard
3,520,041.24
12,086
18.44%
Express
1,818,986.44
5,345
25.62%
Economy
1,595,228.22
5,926
14.47%
Bulk
870,028.97
3,296
11.54%
Same_Day
662,480.39
1,747
30.21%
בסוף התרגיל: בחירת Express בעמוד Overview משנה גם את עמוד Detail, והסלייסר עצמו נראה רק ב-Detail.
2.4 · טבלת פירוט המובילים
בעמוד Detail בנו Table עם שם המוביל, ההכנסה, מספר המשלוחים, המרווח והרמה. חמישה מדדים או עמודות, לא יותר.
ויזואלTable ← שדות: Dim_Carrier[Carrier_Name], Total Freight Revenue, Carrier Rank by Shipments, Margin Tier
מיוןקליק על כותרת ההכנסה ← יורד
סה"כFormat ← Totals ← On
רוחב עמודהFormat ← Column headers ← Auto-size width ← Off
גרידGrid ← Horizontal gridlines ← On ← #1E2A44
מה תראו בשורת הסיכום: ההכנסה תסתכם ל-8,466,765.26 — נכון. אבל Margin Tier בשורת הסיכום יראה Leader, כי הוא מחושב מחדש על כל הנתונים ולא מסכם את ההערכות של השורות. זה לא באג — זה בדיוק מה שמדד אמור לעשות.
ומה לא תראו: את Danube Barge Union. הוא קיים במימד ואין לו נתונים, ולכן Power BI מסתיר אותו. כדי לראות אותו: קליק ימני על השדה בחלונית Columns ← Show items with no data.
הטבלה הצפויה
מוביל
הכנסה בדולר
דירוג
רמה
Northwind Freight
1,655,570.42
1
Leader
Rhine Express Group
1,467,050.34
2
Leader
Baltic Haulage
1,037,060.51
3
Challenger
Iberia Cargo Lines
874,699.14
4
Challenger
Nordic Rail Freight
661,534.78
5
Leader
Channel Sea Lines
646,970.08
6
Leader
Skyway Air Cargo
526,805.38
7
Challenger
Adriatic Transport
516,126.52
8
Laggard
Alpine Rail Cargo
434,400.54
9
Challenger
Atlantic Bulk Ships
378,313.23
10
Leader
Meridian Air Freight
268,234.32
11
Laggard
בסוף התרגיל: 11 שורות, ההכנסה מסתכמת ל-8,466,765.26.
2.5 · Top 10 — עשרת הלקוחות הגדולים
הוסיפו גרף עמודות אופקי של עשרת הלקוחות הגדולים לפי הכנסה. השתמשו ב-Top N בחלונית הפילטרים — לא במיון ידני.
ויזואלClustered bar chart ← ציר: Dim_Customer[Customer_Name] ← ערכים: Total Freight Revenue
פילטרFilters ← Customer_Name ← Filter type ← Top N
הגדרהShow items ← Top ← 10 ← By value ← Total Freight Revenue ← Apply filter
תוויותFormat ← Data labels ← On ← Display units ← Thousands
למה Top N ולא מיון: מיון מסדר את כל 180 הלקוחות ומראה את הראשונים שנכנסים למסך — מספר שמשתנה עם גודל הויזואל. Top N חותך באמת לעשרה, ומה שחשוב יותר: הוא מגיב לסלייסר. אם המשתמש יבחר Express, תקבלו את עשרת הגדולים ב-Express, לא את עשרת הגדולים הכלליים שבמקרה יש להם Express.
לחלופין במדד: אפשר להגיע לאותה תוצאה עם TOPN בתוך CALCULATE, וזה שימושי כשרוצים את הסכום של העשירייה כמספר בודד:
בדיקת השפיות של הפרק: התא התחתון-הימני חייב להראות 100.00%. אם הוא מראה מספר אחר — ה-ALL במדד לא מכסה את כל מה שנמצא בויזואל. זה בדיוק המבחן שתרגיל 1.8 בנה את המדד בשבילו.
למה Matrix ולא Table: Table שם את כל השדות בטור אחד. Matrix יוצר הצטלבות אמיתית של שני מימדים, וזה הויזואל היחיד שבו מדד עם ALL על שני מימדים מראה את כל מה שהוא יודע.
שלוש נקודות ביקורת
תא
ערך
Northwind Freight × Express
4.0955%
Northwind Freight — סיכום שורה
19.5538%
התא התחתון-הימני
100.00%
בסוף התרגיל: 11 שורות על 5 עמודות, והסיכום הכולל 100.00%.
2.7 · גרף משולב — עמודות מול קו על שני צירים
בנו Line and clustered column chart: המובילים בציר, ההכנסה בעמודות, ו-Revenue per KG בקו על הציר המשני.
ויזואלLine and clustered column chart
צירX axis ← Carrier_Name
עמודותColumn y-axis ← Total Freight Revenue
קוLine y-axis ← Revenue per KG
ציר משניFormat ← Y axis ← Secondary ← Show On
הכלל היחיד שחשוב כאן: שני צירים מותרים רק כששתי הסדרות במידות שונות. הכנסה בדולרים וגם יחס בדולר-לק"ג — לגיטימי. שתי סדרות דולריות על שני צירים שונים — מניפולציה ויזואלית, כי אפשר לגרום לכל סדרה להיראות גבוהה יותר רק בבחירת הסקאלה.
מה הגרף הזה מגלה: Northwind Freight הכי גבוה בעמודות, אבל הקו מעליו אינו הגבוה. זו בדיוק השאלה שתסגור את המטלה בתרגיל 3.3.
בסוף התרגיל: עמודות יורדות משמאל לימין, קו שאינו יורד איתן, ושני צירים מסומנים.
2.8 · דונאט מול עמודות — אותם נתונים, שתי קריאות
בנו Donut chart של ההכנסה לפי Corridor_Name, ולידו גרף עמודות של אותם נתונים בדיוק. השוו.
דונאטDonut chart ← מקרא: Corridor_Name ← ערכים: Total Freight Revenue
מתי דונאט עדיף: כשיש שלוש-ארבע קטגוריות והשאלה היא "כמה מהשלם". כאן Cross_Border_Europe תופס יותר משלושה רבעים, וזה נקרא מיד בדונאט.
ומתי הוא נכשל: ברגע שיש שבע קטגוריות ומעלה, או כששתי פרוסות קרובות בגודלן — העין לא יודעת להשוות זוויות. נסו לבנות דונאט של 11 המובילים ותראו למה. בעמודות ההשוואה מיידית.
בסוף התרגיל: שני ויזואלים עם אותם שלושה ערכים, Cross_Border_Europe על 81.61%.
2.9 · Small multiples — רשת קטנה במקום גרף עמוס
קחו את גרף העמודות של ההכנסה לפי Dim_Date[Quarter_Name] ופצלו אותו ל-small multiples לפי Dim_Service_Level[Service_Level_Name].
רשתFormat ← Small multiples ← Layout ← 3 שורות על 2 עמודות
ציר משותףY axis ← Shared axis On
ההחלטה שקובעת הכל: ציר משותף או לא. עם ציר משותף אפשר להשוות בין הפאנלים — ורואים מיד ש-Same_Day קטן פי חמישה מ-Standard. בלי ציר משותף כל פאנל נמתח לגובה מלא, כל אחד נראה גדול, וההשוואה בין פאנלים הופכת לשקר. ברירת המחדל היא ציר משותף, ורוב הזמן זה גם הנכון.
מתי לא להשתמש: כשיש יותר משמונה-תשעה פאנלים. אז כל פאנל קטן מכדי לקרוא, ועדיף Matrix.
בסוף התרגיל: חמישה פאנלים, ציר Y זהה בכולם, ופאנל Standard בולט בבירור מעל השאר.
2.10 · גרף פיזור — משקל מול הכנסה
בנו Scatter chart שבו כל נקודה היא מוביל: ציר X = Total Weight Shipped, ציר Y = Total Freight Revenue, גודל הבועה = מספר המשלוחים.
ויזואלScatter chart
פירוטValues ← Dim_Carrier[Carrier_Name]
ציריםX: Total Weight Shipped · Y: Total Freight Revenue
גודלSize ← Count of Shipment_ID
קו מגמהAnalytics ← Trend line ← Add
המלכודת של Scatter: אם שוכחים לשים שדה ב-Values, Power BI מצייר נקודה אחת — הסכום הכולל. זו הטעות הנפוצה ביותר בויזואל הזה, והיא נראית כמו באג.
מה קו המגמה מספר: ההכנסה עולה עם המשקל, אבל לא ביחס ישר — מובילים עם תמהיל אווירי מרוויחים יותר לק"ג. מוביל שיושב מעל הקו גובה מחיר גבוה לק"ג, מי שמתחתיו גובה פחות.
בסוף התרגיל: 11 בועות, לא אחת. אם יש בועה אחת — חסר שדה ב-Values.
2.11 · ניווט בין העמודים ופוליש אחרון
חברו את שני העמודים בכפתורי ניווט, יישרו הכל, וכבו את מה שלא צריך.
יישורסמנו ויזואלים ← Format ← Align ← Align top ← Distribute horizontally
כותרותלכל ויזואל: Format ← Title ← טקסט קצר באנגלית ← 12pt
ניקויכבו Shadow בכל הויזואלים, ותנו לכולם Border אחיד #1E2A44
סדר טאבView ← Selection ← Tab order ← סדרו לפי סדר הקריאה
הפוליש שהכי משתלם: יישור. שני ויזואלים שנמצאים במרחק שני פיקסלים זה מזה נראים רשלניים גם אם התוכן מושלם, והעין קולטת את זה לפני שהיא קוראת מספר אחד.
ומה שהכי נשכח:Tab order. משתמש מקלדת עובר בין ויזואלים בסדר שבו הם נוצרו, שהוא כמעט תמיד לא סדר הקריאה. שתי דקות עבודה.
בדיקה אחרונה לפני שמגישים:View ← Page view ← Actual size, ואז Fit to page. אם משהו קופץ — יש ויזואל שיוצא מהקנבס.
בסוף הפרק: שני עמודים מקושרים, כל הויזואלים מיושרים, כותרות אחידות וסדר טאב הגיוני.
3.1 · עיצוב מותנה לפי מדד צבע
צבעו את רקע התאים בטבלת המובילים לפי Tier Color, בשיטת Field value. ואז הוסיפו גם צבע טקסט כדי שיישאר קריא.
פתיחהבטבלת המובילים: Format ← Cell elements
בחירת סדרהApply settings to ← Total Freight Revenue
רקעBackground color ← On ← fx
שיטהFormat style ← Field value ← What field should we base this on ← Tier Color
טקסטחזרו על אותו מסלול ב-Font color עם המדד Tier Text Color
Tier Text Color =
SWITCH (
[Margin Tier],
"Leader", "#FFFFFF",
"Challenger", "#132449",
"#132449"
)
למה Field value ולא Rules: כאן ההיגיון כבר יושב במדד [Margin Tier], ושתי הסדרות — הרקע והטקסט — נשענות עליו. אם מחר הסף ישתנה מ-20% ל-22%, משנים מקום אחד בלבד והכל מתעדכן. עם Rules הייתם צריכים לתקן כל ויזואל בנפרד.
המדד חייב להחזיר מחרוזת הקסה תקינה.#132449 עובד; 132449 בלי הסולמית לא. אם התא נשאר לבן — זו הסיבה בתשעים אחוז מהמקרים.
מה ייצא על המסך
רמה
רקע
טקסט
מובילים
Leader
#132449
#FFFFFF
5
Challenger
#F5C518
#132449
4
Laggard
#A9B4CC
#132449
2
תוצאה: החלוקה על המסך היא 5 / 4 / 2.
3.2 · אותה חלוקה בדיוק, בשיטת Rules
הגיעו לאותה חלוקה בדיוק — אבל בלי מדד צבע. השתמשו ב-Rules על אחוז המרווח. המטרה: להוכיח לעצמכם ששתי הדרכים מייצרות תוצאה זהה, ולהבין מתי כל אחת עדיפה.
קודם צרו מדד עזר לפער מול היעד:
Margin Gap vs Target =
VAR TotMargin =
SUM (
Fact_Shipments[Gross_Margin_USD]
)
VAR Pct =
DIVIDE (
TotMargin,
[Total Freight Revenue]
)
RETURN Pct - 0.18
פתיחהCell elements ← Background color ← fx
שיטהFormat style ← Rules
בסיסWhat field should we base this on ← Margin Gap vs Target
כלל 1If value ≥ 0.02 ← #132449
כלל 2If value ≥ -0.06 ← #F5C518
כלל 3If value < -0.06 ← #A9B4CC
למה הספים נראים שונים: המדד מחזיר פער מול יעד של 18%, ולכן סף של 20% הופך ל-+0.02 וסף של 12% הופך ל--0.06. אותה חלוקה, נקודת ייחוס אחרת.
המלכודת של Rules:Percent מול Number בתפריט. אם תשאירו Percent, Power BI יפרש את הספים כאחוזון מהטווח ולא כערך — והחלוקה תצא אחרת לגמרי. בחרו Number.
מתי Rules עדיף בכל זאת: כשההיגיון שייך לויזואל אחד בלבד, כשצריך סקאלה רציפה במקום שלוש מדרגות, או כשאין רשות ליצור מדדים נוספים במודל.
תוצאה: אותה חלוקה בדיוק — 5 / 4 / 2. אם יצא אחרת, בדקו את Number מול Percent.
3.3 · שאלת הסיכום — המוביל שמוביל ואינו הרווחי
שאלת התובנה הסוגרת. Northwind Freight מוביל בהכנסות עם 1,655,570.42 דולר — 19.55% מכל ההכנסה בקובץ. Atlantic Bulk Ships מייצר 378,313.23 דולר בלבד. מי מהשניים שווה יותר לחברה, ומה תעשו עם התשובה? בנו את הויזואל שעונה על השאלה, כתבו שתי שורות מסקנה, ורק אז פתחו.
הויזואל שעונה: גרף פיזור שבו X הוא ההכנסה, Y הוא אחוז המרווח, וגודל הבועה הוא מספר המשלוחים. הוא מפריד מיד בין גודל לאיכות — מה שטבלה ממוינת לפי הכנסה לעולם לא תעשה.
שני קצוות אחד מול השני
מוביל
הכנסה בדולר
מרווח בדולר
מרווח %
Northwind Freight
1,655,570.42
336,144.47
20.30%
Atlantic Bulk Ships
378,313.23
111,779.12
29.55%
התשובה: שניהם, ולא באותה דרך. Northwind Freight מייצר 336,144.47 דולר מרווח מוחלט — יותר מכל מוביל אחר בקובץ — ולכן לוותר עליו יהיה הרסני גם אם אחוז המרווח שלו רק 20.30%. Atlantic Bulk Ships מייצר את המרווח היעיל ביותר בקובץ, 29.55%, אבל על בסיס קטן. מרווח באחוזים אומר כמה יעיל כל דולר; מרווח בדולרים אומר כמה כסף באמת נכנס. החלטה שנשענת על אחד מהם בלבד תמיד תהיה שגויה.
המסקנה המעשית: ההזדמנות אינה לבחור ביניהם אלא להזיז נפח אל Atlantic Bulk Ships — כל דולר שעובר אליו מייצר בערך 9.25 סנט מרווח נוסף מכל דולר הכנסה. השאלה שנשארת פתוחה היא למה הוא קטן: מגבלת קיבולת, כיסוי גיאוגרפי, או פשוט שאף אחד לא הסתכל.
ומי שבאמת צריך תשומת לב: Adriatic Transport ו-Meridian Air Freight — שני ה-Laggard. הם לא הקטנים ביותר, ובדיוק לכן הם עולים כסף: נפח משמעותי במרווח דק.
תוצאה: Northwind Freight מוביל במרווח המוחלט, Atlantic Bulk Ships מוביל באחוז, ושני ה-Laggard הם היעד לתמחור מחדש.
סיכום — כל התוצאות במקום אחד
טבלת אימות מרוכזת לכל 14 המדדים ולכל בדיקת שפיות במטלה. פתחו אותה רק אחרי שסיימתם — היא נותנת את כל התשובות.
כל התוצאות המאומתות במקום אחד
מדד
פונקציה
תוצאה מאומתת
Total Freight Revenue
SUM
8,466,765.26 דולר
Total Weight Shipped
SUM
26,825,847.8 ק"ג
Active Customers
DISTINCTCOUNT
180
Routes Used
DISTINCTCOUNT
60
Revenue per KG
DIVIDE
0.3156
Delivered Revenue
CALCULATE
7,444,128.27 דולר
On Time Delivered Revenue
CALCULATE + &&
5,159,284.25 דולר
Pct of Grand Total
ALL
4.0955% ל-Northwind Freight × Express · סך הכל 100.00%
Revenue vs Prev Month
IF
Up ב-2025-12 · Down ב-2025-02
Margin Tier
SWITCH ( TRUE () )
5 Leader · 4 Challenger · 2 Laggard
Tier Color
SWITCH
#132449 · #F5C518 · #A9B4CC
Carrier Rank by Shipments
RANK
Northwind Freight ראשון · Danube Barge Union במקום 12 עם ערך ריק
Median Carrier Revenue
INDEX
646,970.08 דולר — Channel Sea Lines
Cumulative Pct of Revenue
WINDOW
49.13% לשלושת הראשונים · 100.00% בשורה האחרונה
בדיקות שפיות נוספות
בדיקה
ערך
שורות בטבלת העובדות
28,400
מובילים במימד מול בעובדות
12 מול 11
המדד הנאיבי על עמודת היחס
0.3815 מול 0.3156 הנכון
הכנסה שלא מומשה
1,022,636.99 דולר
מרווח גולמי כולל
1,646,331.51 דולר · 19.44%
שורות במרווח שלילי (מכוון)
1,911 שורות · -34,038.47 דולר
ימים ב-Dim_Date
731 רצופים
חודש השיא
2025-10 · 507,396.90
חודש השפל
2025-02 · 225,297.76
אם כל 14 המדדים אצלכם מחזירים בדיוק את הערכים האלה — המודל נבנה נכון והמטלה הושלמה.
אפשר לנווט גם בכפתורים שבראש המסך, בחצי המקלדת, ובטלפון בהחלקת אצבע