Söz dizimi
CALCULATE( <ifade>, <filtre1>, <filtre2>, ... )
CALCULATE, ifadeyi değiştirilmiş bir filtre bağlamında hesaplar. Filtre bağımsız değişkenleri mevcut bağlamın üzerine yazılır, sonra ifade çalışır.
Filtre eklemek
Web Satışı = CALCULATE([Toplam Satış], Satislar[Kanal] = "Web")
Bu ölçüyü kategoriye göre bir tabloya koyarsan her kategorinin yalnızca web satışını görürsün. Kategori filtresi korunur, kanal filtresi eklenir.
Filtrenin üzerine yazmak
Dilimleyicide “Mobil” seçili olsa bile [Web Satışı] web satışını gösterir. Çünkü Satislar[Kanal] = "Web" filtresi, aynı sütundaki mevcut filtrenin yerine geçer. Mevcut filtreyi korumak istersen KEEPFILTERS kullanırsın:
Web Satışı (seçimle) = CALCULATE([Toplam Satış], KEEPFILTERS(Satislar[Kanal] = "Web"))
Bu sürümde dilimleyicide “Mobil” seçiliyse sonuç boş olur, çünkü iki filtre kesişir.
Birden çok koşul
Mobil Elektronik = CALCULATE(
[Toplam Satış],
Satislar[Kanal] = "Mobil",
Urunler[Kategori] = "Elektronik"
)
Kitap ve Spor = CALCULATE([Toplam Satış], Urunler[Kategori] IN {"Kitap", "Spor"})
İptal Dışı = CALCULATE([Toplam Satış], Satislar[Durum] <> "İptal")
Ayrı bağımsız değişkenler VE ile birleşir. Aynı sütunda VEYA için IN { } ya da || kullanılır.
Filtre kaldırmak
Tüm Kategoriler = CALCULATE([Toplam Satış], ALL(Urunler)) Pay % = DIVIDE([Toplam Satış], [Tüm Kategoriler])
ALL (ya da daha okunur adıyla REMOVEFILTERS) bir tablo ya da sütundaki filtreleri kaldırır. Payda her hücrede genel toplamı verir; böylece pay hesaplanır. Bir sonraki derste ayrıntısıyla göreceğiz.
Satislar[Kanal] = "Web") aslında FILTER(ALL(Satislar[Kanal]), Satislar[Kanal] = "Web") tablosunun kısa yazımıdır. Bu yüzden mevcut kanal filtresinin üzerine yazar.Filtre argümanı aslında bir tablodur
CALCULATE([Net Satış], Kategoriler[Kategori] = "Elektronik") yazdığında DAX bunu şuna çevirir:
Elektronik Satış = CALCULATE([Net Satış], FILTER(ALL(Kategoriler[Kategori]), Kategoriler[Kategori] = "Elektronik"))
İçteki ALL, kategori sütunundaki dış filtreyi kaldırır. Bu yüzden ölçüyü Kategoriler[Kategori] eksenli bir matrise koyduğunda her satırda Elektronik’in satışı (339.304 ₺) görünür: Giyim satırında da, Kitap satırında da. Bu bir hata değil, “filtreyi değiştir” davranışıdır.
Dış filtreyi silmek yerine onunla kesiştirmek istiyorsan KEEPFILTERS kullan:
Elektronik Satış (kesişim) = CALCULATE([Net Satış], KEEPFILTERS(Kategoriler[Kategori] = "Elektronik"))
Bu sürüm Elektronik satırında 339.304 ₺, diğer kategorilerde BLANK döndürür; görsel de yalnızca Elektronik satırını gösterir.
Sütun filtresi mi, tablo filtresi mi?
FILTER(Urunler, Urunler[Fiyat] > 1000) bütün Urunler tablosunu filtre olarak verir; tablo, o anki bağlamda görünen satırlarla ve tüm sütunlarıyla gelir. Urunler[Fiyat] > 1000 ise yalnızca Fiyat sütununu filtreler. Bu örnekte iki yazım aynı sonucu verir, ama tablo filtresi daha yavaştır ve filtre bağlamındaki diğer Urunler sütunlarını da sabitler. Önce sütun filtresini dene; tablo filtresine yalnızca koşul birden çok tablodan sütun ya da bir ölçü içerdiğinde ihtiyaç duyarsın.
Filtre bağımsız değişkeninin türleri
CALCULATE’in ilk bağımsız değişkeninden sonra yazdığın her şey ya bir tablo ya da bir düzenleyicidir. Boolean ifade bile perde arkasında tabloya çevrilir. Hangi türü yazdığını bilmek, sonucun neden öyle çıktığını açıklar:
| Tür | Örnek | Etkisi |
|---|---|---|
| Boolean (sütun koşulu) | Satislar[Kanal] = "Web" | O sütundaki dış filtrenin yerine geçer |
| Tablo ifadesi | FILTER(Satislar, …), VALUES(…), bir tablo değişkeni | Tablonun satırları ve tüm sütunları filtre olur |
| Kaldırıcı | REMOVEFILTERS(Urunler), ALL(Satislar[Kanal]) | Filtreyi siler, yerine bir şey koymaz |
| Düzenleyici | KEEPFILTERS, USERELATIONSHIP, CROSSFILTER | Filtrenin nasıl birleşeceğini ya da ilişkinin nasıl çalışacağını değiştirir |
Boolean filtrenin üç sınırı
1. İçinde ölçü olamaz
Hatalı = CALCULATE([Net Satış], [Net Satış] > 1000)
Boolean filtre bir sütunun değerlerini süzer; ölçünün “sütunu” yoktur. Koşul bir ölçüye dayanıyorsa önce hangi satırlar üzerinde test edileceğini seçmen gerekir: FILTER(VALUES(Urunler[Urun]), [Net Satış] > 1000).
2. Tek bir tablonun sütunlarını kullanabilir
Kampanya ekibinin sorusu: “Web kanalından gelen ya da Kitap kategorisindeki satışlar ne kadar?” İlk deneme genellikle iki ayrı bağımsız değişkendir:
Web ve Kitap (yanlış soru) = CALCULATE([Net Satış], Satislar[Kanal] = "Web", Urunler[Kategori] = "Kitap")
Ayrı bağımsız değişkenler VE ile birleşir: sonuç 57.545 ₺, yani yalnızca web’den satılan kitaplar. Satislar[Kanal] = "Web" || Urunler[Kategori] = "Kitap" yazmak ise hata verir, çünkü koşul iki tabloya yayılıyor. Doğru yol, koşulu satır satır test eden bir tablo filtresidir:
Web veya Kitap =
CALCULATE(
[Net Satış],
FILTER(Satislar, Satislar[Kanal] = "Web" || RELATED(Urunler[Kategori]) = "Kitap")
)
Sonuç 551.668 ₺. Sağlamasını yap: web 457.331 ₺ + kitap 151.882 ₺ − ikisinin kesişimi 57.545 ₺ = 551.668 ₺. Aynı tablodaki iki sütunla VEYA kurmak ise boolean filtreyle mümkündür: Satislar[Indirim] > 0 || Satislar[Kanal] = "Mağaza" geçerli bir filtredir.
3. Aynı sütuna iki koşul VE olur
CALCULATE([Net Satış], Satislar[Kanal] = "Web", Satislar[Kanal] = "Mobil") BLANK döndürür. Bir satır aynı anda hem Web hem Mobil olamaz. İki kanalı birlikte istiyorsan tek koşul yaz: Satislar[Kanal] IN {"Web", "Mobil"}.
Filtre bağımsız değişkeni dış bağlamda hesaplanır
Operasyon müdürü yıllık tabloda “her yılın son günündeki ciro” sütununu istiyor:
Takvimin Son Günü = CALCULATE([Net Satış], Tarih[Tarih] = MAX(Tarih[Tarih])) Satışın Son Günü = CALCULATE([Net Satış], Satislar[Tarih] = MAX(Satislar[Tarih]))
MAX, CALCULATE filtreyi değiştirmeden önce, hücrenin kendi bağlamında hesaplanır. Yıl satırında MAX(Tarih[Tarih]) 31 Aralık’tır. 2022 ve 2023’te 31 Aralık’ta hiç satış olmadığı için ilk ölçü bu yıllarda BLANK döner; 2024’te 1.047 ₺ verir. İkinci ölçü satış olan son günü arar: 2022’de 2.871,95 ₺, 2023’te 1.216,40 ₺. Hangisi doğru? Soru “takvimin son günü” mü, “son işlem günü” mü? Bunu ölçü adında açıkça yaz.
Boolean filtre mi, FILTER(Satislar, …) mı?
İkisi çoğu zaman aynı sayıyı verir. Fark, dışarıda aynı sütuna bir filtre olduğunda ortaya çıkar. Satırlarda Satislar[Kanal] olan bir tabloda üç yazımı karşılaştır:
| Yazım | Mağaza satırı | Mobil satırı | Web satırı | Neden? |
|---|---|---|---|---|
Satislar[Kanal] = "Web" | 457.331 | 457.331 | 457.331 | İçteki ALL(Satislar[Kanal]) satır filtresinin yerine geçer |
FILTER(Satislar, Satislar[Kanal] = "Web") | (boş) | (boş) | 457.331 | FILTER yalnızca görünen satırları dolaşır; dış filtre korunur |
FILTER(ALL(Satislar), Satislar[Kanal] = "Web") | 457.331 | 457.331 | 457.331 | Tüm tablo filtresizleşir; kategori, tarih filtreleri de gider |
Üçüncü yazım en tehlikelisidir. Satırlarda kategori olan bir tabloda her satırda 457.331 ₺ görürsün, çünkü ALL(Satislar) genişletilmiş tablo üzerinden kategori filtresini de siler (bir sonraki derste). İkinci yazım dış filtreyi korur, ama bütün Satislar tablosunu dolaştığı için büyük modelde yavaştır. Dış filtreyle kesişim istiyorsan aynı sonucu daha ucuza KEEPFILTERS(Satislar[Kanal] = "Web") verir.
||, &&). Birden çok tabloya mı yayılıyor ya da ölçü mü içeriyor? FILTER yaz ve dolaşılan tabloyu olabildiğince küçük seç (VALUES(Urunler[Urun]) gibi). Dış filtreyi silmek değil kesiştirmek mi istiyorsun? KEEPFILTERS ekle.