Ana içeriğe geç
Kesit Power BI
İleri · Uzman DAX

Uzman kalıplar: devam eden olaylar, karşılaştırılabilir dönem, döviz çevirme ve farklı taneciklikte bütçe

Açık siparişleri doğru saymak (boş teslim tarihi, yaşlandırma, günlük ortalama), müşteri düzeyinde karşılaştırılabilir dönem ve hayatta kalan yanlılığı, işlem kuru / dönem sonu kuru / sabit kur ayrımı ve eksik kur, aylık hedefi güne dağıtmak ve taneciklik koruması.

Uygulamada aç, 10 alıştırmayı çözÜcretsiz, hesap gerekmez, kurulum yok.

Bu sayfa dersin okuma sürümüdür. Metin bir kutuyu çalıştırmanı ya da adıma geçmeni söylüyorsa dersi uygulamada aç.

“İleri iş kalıpları” dersinde Top N + Diğer, sepet analizi, ürün düzeyinde LFL ve aylık kurla dönüşümün iskeletini kurdun; Measure Lab’de [Yoldaki Sipariş] kalıbını gördün. Bu ders o kalıpları üretime taşıyor: gerçek verinin kenar durumları, aynı sorunun iki farklı doğru tanımı ve raporu sessizce bozan tanecik farkları. Her bölümde önce mevcut çözümün nerede yanlış sayı verdiğini motorla göreceğiz.

1 · Devam eden olaylar: açık siparişleri doğru saymak

Lojistik müdürü yılbaşı sabahı soruyor: “31 Aralık 2024 akşamı depoda kaç açık sipariş vardı?” Measure Lab’deki [Yoldaki Sipariş], ay satırlarında 2024 boyunca 1 ile 5 arasında değerler veriyor. Aralık 2024 satırı ise BLANK.

Sebep veride: Aralık’ın son günlerinde verilmiş 6 sipariş (10 satır) hâlâ “Kargoda” ve TeslimTarihi boş. Kalıp Satislar[TeslimTarihi] > Gun koşulunu kullanıyor; DAX’ta BLANK bir tarihle karşılaştırılınca sıfır gibi davranır ve koşul yanlış olur. Yani “henüz teslim edilmemiş” siparişler, tam da sayılması gerekenler, dışarıda kalıyor. Öte yandan iptal edilen 121 satırın da teslim tarihi boş; onları açık saymamalıyız.

Açık Sipariş =
VAR Gun = MAX(Tarih[Tarih])
RETURN
    CALCULATE(
        DISTINCTCOUNT(Satislar[SiparisNo]),
        REMOVEFILTERS(Tarih),
        Satislar[Tarih] <= Gun,
        Satislar[Durum] <> "İptal",
        FILTER(
            ALL(Satislar[TeslimTarihi]),
            ISBLANK(Satislar[TeslimTarihi]) || Satislar[TeslimTarihi] > Gun
        )
    )
Ay sonu[Yoldaki Sipariş][Açık Sipariş]
2024-1055
2024-1133
2024-12BLANK6

Geçmiş aylar aynı, çünkü o siparişlerin teslim tarihi artık dolu. Hata yalnızca en güncel dönemde, yani yöneticinin en çok baktığı yerde görünür. Devam eden olay kalıbının genel kuralı: bitiş tarihi boşsa olay hâlâ sürüyordur; iptal gibi “hiç başlamamış” durumları ayrıca dışla.

Aynı kalıptan türeyen üç soru

SoruDeğişiklik31.12.2024
Açık sipariş tutarıDISTINCTCOUNT yerine SUM(Satislar[Tutar])11.063 ₺
3 günden uzun açık (yaşlandırma)Satislar[Tarih] <= Gun - 32 sipariş
Ay içinde ortalama günlük açık siparişAVERAGEX(VALUES(Tarih[Tarih]), [Açık Sipariş])Aralık: 6,2 · en yüksek gün: 10

Ay sonu değeri (6) ile ayın günlük ortalaması (6,2) ve zirvesi (10) farklı kararlar doğurur: ay sonu bilanço içindir, ortalama kapasite planı içindir, zirve ise vardiya planı içindir. Raporda hangisini gösterdiğini başlıkta yaz.

Performans: dinamik ölçü mü, fotoğraf tablosu mu?

YolNe zaman?Bedel
Dinamik ölçü (yukarıdaki)Ay ya da gün düzeyinde, orta büyüklükte olguHer hücrede tarih filtresi yeniden kurulur; günlük ortalamada gün sayısı × sorgu
Günlük fotoğraf tablosu (Tarih × açık sipariş sayısı)Milyonlarca satır, günlük trend sık kullanılıyorYenilemede hesaplanır (Power Query ya da ambar); geçmişe dönük düzeltmelerde yeniden üretmek gerekir

StokGorunum tablosu da bir fotoğraf tablosudur; “Model tasarımı II” dersinde gördüğün gibi aylar boyunca toplanmaz, son değeri alınır. Açık sipariş de aynı türde, yarı toplanabilir bir ölçüdür: yıl satırında 12 ayın toplamı değil, yıl sonu değeri gösterilir.

2 · Karşılaştırılabilir dönem: hangi müşteriler “aynı”?

“İleri iş kalıpları” dersinde LFL’yi ürün kümesiyle kurdun: her iki dönemde de satılan ürünler. Aynı fikri müşteriye uyguladığında, ürün analizinde göze batmayan bir tuzak ortaya çıkar. Yönetim kurulu soruyor: “2024’teki %86 büyümenin ne kadarı yeni müşteriden, ne kadarı mevcut müşterinin daha çok harcamasından?”

TanımKüme2024 / 2023Büyüme
Tüm müşterilerHerkes747.066 / 400.870 ₺+%86,4
Etkinliğe göre (her iki yılda alan)64 müşteri—+%27,3
Kohorta göre (ilk siparişi 2023’ten önce)46 müşteri194.668 / 202.047 ₺−%3,7

İki “karşılaştırılabilir” tanım, işareti bile farklı iki sonuç veriyor. Etkinliğe dayalı tanım, 2024’te alışverişi bırakan müşterileri tanım gereği dışarıda bırakır: yalnızca “hayatta kalanlar” kalır. Bu hayatta kalan yanlılığı (survivorship bias) mevcut müşteri büyümesini olduğundan iyi gösterir. Kohort tanımı ise kümeyi dönem başında, sonuca bakmadan sabitler; kayıpları da içerir. Eski müşteri tabanı aslında küçülmüş; büyümenin tamamı yeni müşterilerden geliyor.

Eski Kohort Satışı =
VAR DonemBasi = MIN(Tarih[Tarih])
VAR KarsilastirmaBasi = EDATE(DonemBasi, -12)
VAR EskiMusteriler =
    CALCULATETABLE(
        VALUES(Musteriler[MusteriNo]),
        REMOVEFILTERS(Tarih),
        Musteriler[IlkSiparis] < KarsilastirmaBasi
    )
RETURN
    CALCULATE([Net Satış], EskiMusteriler)

Eski Kohort Satışı GY =
VAR DonemBasi = MIN(Tarih[Tarih])
VAR KarsilastirmaBasi = EDATE(DonemBasi, -12)
VAR EskiMusteriler =
    CALCULATETABLE(
        VALUES(Musteriler[MusteriNo]),
        REMOVEFILTERS(Tarih),
        Musteriler[IlkSiparis] < KarsilastirmaBasi
    )
RETURN
    CALCULATE([Net Satış], EskiMusteriler, SAMEPERIODLASTYEAR(Tarih[Tarih]))

Küme, karşılaştırma döneminin başına göre kurulur: 2024 satırında “ilk siparişi 1 Ocak 2023’ten önce olanlar”. Böylece aynı 46 müşteri iki yılda da ölçülür.

Kenar durumlar

Üretimde bayrakPerakendede karşılaştırılabilir mağaza listesi genelde iş kuralıyla (en az 13 ay açık, tadilat yok) belirlenir ve kaynakta ya da Power Query’de dönem başına bir bayrak sütunu olarak tutulur. Dinamik DAX kümesi keşif için iyidir; resmî raporda bayrak, denetlenebilir ve hızlıdır.

3 · Döviz çevirme: hangi kur, hangi sayı?

Ortaklara dolar bazlı rapor hazırlanıyor. Kur tablosu DovizKurlari ayda bir satır tutuyor (ayın ilk günü, USD ve EUR) ve Tarih’e bağlı değil. Aylık kurla satış dönüşümünü Measure Lab’deki [Satış (Seçili Para)] yapıyor. Uzman sorusu şu: her sayı aynı kurla mı çevrilir?

Sayı türüÖrnekDoğru kur
Akış (dönem boyunca oluşur)Satış, gider, satın almaİşlem tarihinin kuru (burada ay kuru); ay ay çevrilip toplanır
Bakiye (bir andaki fotoğraf)Stok değeri, açık sipariş tutarı, alacakDönem sonu kuru
Performans karşılaştırmasıBüyüme, hedef sapmasıSabit kur (iki dönem aynı kurla)

Akış ve bakiye

2024 net satışı 747.066 ₺. Aylık kurlarla 22.614 $; tüm yılı Aralık kuruyla (35,00) çevirirsen 21.345 $; yıl ortalama kuruyla (32,78) 22.788 $. Akış için doğru olan ilkidir. Stok değeri ise yıl sonu fotoğrafıdır: 163.465 ₺, dönem sonu kuruyla 4.670 $. Ortalama kurla çevirmek 4.986 $ verir ve bilançoda olmayan bir değeri raporlar.

Stok Değeri (USD, Dönem Sonu) =
VAR SonAyBasi = EOMONTH(MAX(Tarih[Tarih]), -1) + 1
VAR Kur =
    LOOKUPVALUE(DovizKurlari[Kur], DovizKurlari[Tarih], SonAyBasi, DovizKurlari[ParaBirimi], "USD")
RETURN
    DIVIDE([Stok Değeri], Kur)

Sabit kur: büyümenin ne kadarı kurdan?

Dolar bazında 2024 büyümesi 22.614 / 16.613 → +%36,1. TL bazında +%86,4. Hangisi “gerçek” performans? İkisini ayırmak için 2024’ün her ayını, 2023’ün aynı ayının kuruyla çevir:

Satış USD (GY Kuruyla) =
SUMX(
    VALUES(Tarih[YilAy]),
    VAR GecenYilAyBasi = EDATE(DATEVALUE(Tarih[YilAy] & "-01"), -12)
    VAR Kur =
        LOOKUPVALUE(DovizKurlari[Kur], DovizKurlari[Tarih], GecenYilAyBasi, DovizKurlari[ParaBirimi], "USD")
    RETURN DIVIDE([Net Satış], Kur)
)

2024 sabit kurla 31.204 $; 2023’e göre +%87,8. Yani iş hacmi neredeyse ikiye katlanmış, TL’nin değer kaybı dolar büyümesini %36’ya indirmiş. Kur etkisi: 22.614 − 31.204 = −8.590 $. Bu ayrıştırma, “dolar büyümesi düşük, ekip başarısız” yanlış sonucunu önler.

Eksik kur: sessiz kayıp

Yukarıdaki ölçü 2022 satırında BLANK verir; kur tablosunda 2021 yok. Asıl tehlike toplam satırında: 54.948 $, 2022’yi hiç içermiyor ve hiçbir uyarı yok. Üretimde iki koruma kur:

Kuru Eksik Ay =
COUNTROWS(
    FILTER(
        VALUES(Tarih[YilAy]),
        ISBLANK(
            LOOKUPVALUE(DovizKurlari[Kur], DovizKurlari[Tarih], EDATE(DATEVALUE(Tarih[YilAy] & "-01"), -12), DovizKurlari[ParaBirimi], "USD")
        )
    )
)

2022 satırında 12, diğer yıllarda BLANK döner. Toplam satırında da 12: rapor kullanıcısına “bu toplamın 12 ayı eksik” demenin tek yolu budur.

4 · Farklı taneciklikte bütçe: aylık hedefi güne dağıtmak

Satış direktörü haftalık toplantı için “haftalık satış ve hedef” tablosu istiyor. Hedefler ay düzeyinde ve her ayın hedefi ayın 1. gününe yazılı. Hafta kırılımında [Hedef] şöyle görünür:

2024 haftasıNet satış[Hedef]Günlük dağıtım
1 (1–7 Ocak, 30–31 Aralık)27.516 ₺48.500 ₺16.655 ₺
26.921 ₺BLANK10.952 ₺
5 (29 Ocak–4 Şubat)5.682 ₺46.000 ₺11.038 ₺

Ayın 1’ini içeren hafta ayın bütün hedefini alıyor, diğer haftalar hedefsiz. Aynı sorun ay içi “bugüne kadar” raporunda daha da tehlikeli: 1–15 Aralık 2024 satışı 60.134 ₺, [Hedef] 88.400 ₺ gösteriyor ve ekip “%68’deyiz” diye alarm veriyor. Günlük dağıtımla hedef 42.774 ₺, gerçekleşme %141. 2–31 Aralık seçilirse hedef BLANK olur.

Hedef (Günlük Dağıtım) =
SUMX(
    VALUES(Tarih[YilAy]),
    VAR Ay = Tarih[YilAy]
    VAR AyHedefi = CALCULATE([Hedef], REMOVEFILTERS(Tarih), Tarih[YilAy] = Ay)
    VAR AyGunSayisi = CALCULATE(COUNTROWS(Tarih), REMOVEFILTERS(Tarih), Tarih[YilAy] = Ay)
    VAR GorunenGun = CALCULATE(COUNTROWS(Tarih))
    RETURN DIVIDE(AyHedefi * GorunenGun, AyGunSayisi)
)

Her görünen ay için: ayın tam hedefi × (görünen gün / ayın gün sayısı). GorunenGun, bağlam geçişiyle o ayın görünen günlerini sayar; hafta 1’de Ocak için 7, Aralık için 2. Ay ve yıl satırlarında sonuç [Hedef] ile birebir aynıdır (2024: 763.200 ₺), yani ölçü mevcut raporları bozmaz.

Anti-kalıp: VAR yerine VALUESTarih[YilAy] = Ay yerine VALUES(Tarih[YilAy]) yazarsan, “Genişletilmiş tablolar” dersinde gördüğün gibi filtre argümanı dış bağlamda hesaplanır ve hafta 1’de iki ayı birden döndürür. Sonuç 16.655 ₺ yerine 19.873 ₺ olur. Ay, çeyrek ve yıl satırlarında ise iki sürüm aynı sayıyı verir; hata yalnızca ay sınırını kesen kırılımlarda görünür. Testte mutlaka hafta ve “1–15 Aralık” gibi kısmi bir aralık dene.

Üç strateji

StratejiNe yapar?Ne zaman?
Dağıt (yukarıdaki)Ay hedefini görünen günlere orantılarHaftalık ve ay içi takip isteniyorsa
GizleGörünen gün sayısı, görünen ayların tam gün sayısına eşit değilse BLANKHedef ancak ay düzeyinde anlamlıysa; yanlış sayı göstermektense boş
Önceden dağıtPower Query’de ya da ambarda gün düzeyinde hedef tablosuBüyük model, ağırlıklı dağıtım (iş günü, mevsimsellik)
Hedef (Yalnızca Tam Ay) =
VAR GorunenGun = COUNTROWS(Tarih)
VAR TamAyGun = CALCULATE(COUNTROWS(Tarih), REMOVEFILTERS(Tarih), VALUES(Tarih[YilAy]))
RETURN IF(GorunenGun = TamAyGun, [Hedef])

Burada VALUES doğru kullanım: ölçü iteratör içinde değil, dış bağlamda tek bir kez hesaplanıyor. Eşit dağıtım bir varsayımdır: hafta sonu satışı yüksek bir perakendecide günlere eşit pay vermek hafta içini hep “geride” gösterir. “Zaman serisi analizi” dersindeki haftanın günü endeksiyle ağırlıklandırmak bir sonraki adımdır; bu durumda önceden dağıtılmış gün tablosu daha bakımı kolay olur. Aynı kalıp GiderButce için de geçerlidir: gider bütçesi gider türü × ay düzeyinde, günlük dağıtım ölçüsü gider türü kırılımında [Gider Bütçe] ile aynı sayıyı verir.

Uzman kalıp kontrol listesi

  1. Bitiş tarihi boş olabilir mi? Devam eden olaylarda boş bitiş “sürüyor” demektir; iptal gibi başlamamış durumları ayrıca dışla.
  2. Ölçü toplanabilir mi? Açık sipariş ve stok gibi bakiyeler yıl boyunca toplanmaz; dönem sonu ya da ortalama göster, hangisi olduğunu başlığa yaz.
  3. Karşılaştırılabilir küme sonuca bakmadan mı seçildi? Etkinliğe dayalı küme hayatta kalan yanlılığı taşır.
  4. Sayı akış mı, bakiye mi? Akış işlem kuruyla, bakiye dönem sonu kuruyla; büyüme yorumu sabit kurla.
  5. Kur eksik mi? Kontrol ölçüsü toplam satırında da uyarmalı.
  6. Bütçe hangi tanecikte? Ay sınırını kesen her kırılımda (hafta, tarih aralığı) hedefin ne gösterdiğini test et; dağıt, gizle ya da önceden dağıt.
  7. Belgele: Her uzman ölçünün açıklamasına tanımı, kenar durumu ve test edilen kırılımları yaz. Bu ölçüler ekipte en çok “neden bu sayı?” sorusu alanlardır.
Alıştırmalara geç (10)