Ana içeriğe geç
Kesit Power BI
İleri · Zaman Zekâsı

Özel takvimler: mali yıl, hafta tabanlı ve 4-4-5 takvimlerle zaman zekâsı

Temmuz başlangıçlı mali yıl, ISO hafta ve hafta tabanlı yıl, perakende 4-4-5 takvimi, 364 gün geriye hafta karşılaştırması, hazır zaman zekâsı fonksiyonlarının bozulduğu yerler, sütun tabanlı özel zaman zekâsı ve önizlemedeki takvim tabanlı zaman zekâsı.

Uygulamada aç, 12 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ç.

“Zaman zekâsı” ve “Gelişmiş zaman hesapları” derslerinde her şey ocakta başlayan Gregoryen takvimle çalıştı. Şirketlerde bu nadiren yeterlidir. Finans ekibi yılı temmuzda başlatır, mağaza ekibi haftayla yaşar, satın alma ekibi 4-4-5 dönemleriyle plan yapar. Bu derste aynı Tarih tablosunu üç takvime çevirecek ve hazır fonksiyonların nerede yanlış sayı ürettiğini göreceksin.

Üç ekip, üç takvim

Anadolu Market’te pazartesi sabahı üç ayrı istek geliyor:

TakvimYıl nasıl başlar?En küçük birimHazır fonksiyonlar çalışır mı?
Gregoryen1 OcakGün → ayEvet
Kaydırılmış Gregoryen (mali yıl)Sabit bir tarih (1 Temmuz)Gün → ayBüyük ölçüde evet, yıl sonu parametresiyle
Hafta tabanlı (ISO, 4-4-5)Bir pazartesi; tarihi her yıl değişirGün → hafta → dönemHayır; aylar ve yıllar tutmaz

Modeldeki Tarih[HaftaNo] ISO 8601 hafta numarası, Tarih[GunNo] haftanın günüdür (1 = Pazartesi).

Mali yıl: Temmuz başlangıçlı yıl

Hazır yol: yıl sonu parametresi

DATESYTD ve TOTALYTD, isteğe bağlı bir yıl sonu tarihi (year_end_date) alır. Microsoft Learn’e göre bu bir metin sabitidir, yıl kısmı yok sayılır ve biçimi raporu oluşturan istemcinin yerel ayarına bağlıdır: bir makinede "6-30", diğerinde "30-6" olabilir. Varsayılan 31 Aralık’tır.

Mali YTD (hazır) =
TOTALYTD([Net Satış], Tarih[Tarih], "6-30")

Mali YTD (DATESYTD) =
CALCULATE([Net Satış], DATESYTD(Tarih[Tarih], "6-30"))
Playground’da deneİki ölçü de Mart 2024 için 401.796,75 ₺ döner; takvim yılı YTD’si 155.390,75 ₺’dir. Yine de yıl sonu dizesi bölgesel ayara bağlı olduğu için ekip modellerinde aşağıdaki açık kalıp daha güvenlidir; her iki yerde de aynı sonucu verir.

Sütun ve tarih aritmetiğiyle aynı hesap

Mali YTD =
VAR son = MAX(Tarih[Tarih])
VAR bas = IF(MONTH(son) >= 7, DATE(YEAR(son), 7, 1), DATE(YEAR(son) - 1, 7, 1))
RETURN CALCULATE([Net Satış], DATESBETWEEN(Tarih[Tarih], bas, son))

Mali YTD GY =
CALCULATE([Mali YTD], SAMEPERIODLASTYEAR(Tarih[Tarih]))

Motor görünen dönemin son gününü (son) okur, mali yılın ilk gününü (bas) hesaplar, sonra DATESBETWEEN Tarih[Tarih] filtresini bu aralıkla değiştirir; işaretli tarih tablosunda Yıl ve Ay filtreleri de kalkar. Sonuçlar:

SatırTakvim YTDMali YTDMali YTD GY
Mart 2024155.390,75401.796,75 (Tem 2023–Mar 2024)169.796,10 (Tem 2022–Mar 2023)
Temmuz 2024—60.948,00 (yeni mali yılın ilk ayı)—

Tam mali yıllar: MY2023 256.705,75; MY2024 546.898,75; MY2025 henüz yarım, 446.572,95.

Mali yıl sütunları

Ölçülerin yanında rapor da mali yılı göstermeli. Tarih tablosuna üç sütun eklenir. Aşağıdaki sorgu bu sütunları üretip her ayın ilk gününde gösterir:

EVALUATE
ADDCOLUMNS(
    FILTER(Tarih, Tarih[Gun] = 1),
    "MaliYil", Tarih[Yil] + IF(Tarih[AyNo] >= 7, 1, 0),
    "MaliAyNo", MOD(Tarih[AyNo] + 5, 12) + 1,
    "MaliCeyrek", "MÇ" & (INT(MOD(Tarih[AyNo] + 5, 12) / 3) + 1)
)

ISO hafta ve hafta tabanlı yıl

ISO 8601’e göre hafta pazartesi başlar. Yılın ilk haftası, o yılın ilk perşembesini içeren haftadır. Bu yüzden bir yıl 52 ya da 53 hafta sürer. Yılın ilk birkaç günü önceki yılın son haftasına, son birkaç günü sonraki yılın ilk haftasına düşebilir. DAX’ta WEEKNUM(tarih, 21) ISO hafta numarasını verir.

Modelde bunu görmek kolay: 1–2 Ocak 2022’nin HaftaNo değeri 52, 30–31 Aralık 2024’ün değeri 1’dir.

Anti-kalıp: Yıl × HaftaNo

Mağaza müdürü bir matrise Tarih[Yil] ve Tarih[HaftaNo] koyuyor. 2024 / Hafta 1 hücresinde 27.516,05 görünüyor. Oysa ISO 2024’ün ilk haftası (1–7 Ocak) 16.728,05’tir. Aradaki 10.788,00, 30–31 Aralık 2024’e aittir. O iki gün ISO 2025’in ilk haftasıdır ama Gregoryen yıl 2024 olduğu için aynı hücreye girer. Yani hafta 1 iki ayrı haftanın toplamıdır.

EVALUATE
ROW(
    "Yanlis", CALCULATE([Net Satış], Tarih[Yil] = 2024, Tarih[HaftaNo] = 1),
    "Dogru", CALCULATE([Net Satış],
        FILTER(ALL(Tarih), YEAR(Tarih[Tarih] - Tarih[GunNo] + 4) = 2024 && Tarih[HaftaNo] = 1))
)

Çözüm, haftayla birlikte hafta tabanlı yılı da saklamaktır. Kural basit: bir günün ISO yılı, o haftanın perşembesinin yılıdır. Perşembe = Tarih - GunNo + 4. Haftanın başlangıcı = Tarih - GunNo + 1.

EVALUATE
ADDCOLUMNS(
    FILTER(Tarih, Tarih[Tarih] >= DATE(2024, 12, 28)),
    "ISOYil", YEAR(Tarih[Tarih] - Tarih[GunNo] + 4),
    "HaftaBaslangic", Tarih[Tarih] - Tarih[GunNo] + 1,
    "HaftaAnahtari", YEAR(Tarih[Tarih] - Tarih[GunNo] + 4) & "-H" & IF(Tarih[HaftaNo] < 10, "0", "") & Tarih[HaftaNo]
)

28–29 Aralık “2024-H52”, 30–31 Aralık “2025-H01” çıkar. Görselde ve dilimleyicide Yıl × HaftaNo yerine HaftaAnahtari (ya da ISOYil × HaftaNo) kullan.

Perakende 4-4-5 takvimi

Perakendede aylar karşılaştırılabilir değildir: bir ayda beş, diğerinde dört cumartesi olur. 4-4-5 takviminde yıl 52 haftadır, her çeyrek 13 haftadır ve çeyrek 4 + 4 + 5 haftalık üç döneme bölünür. Her dönem aynı gün başlar ve biter. 4-5-4 ve 5-4-4 de yaygındır.

Bedeli: Gregoryen yılla her yıl bir gün (artık yılda iki) kayma birikir ve 5–6 yılda bir 53. hafta eklenir. Bu haftanın hangi döneme gireceği bir iş kararıdır. 2026, 53 haftalık bir ISO yılıdır.

ISO haftayı perakende haftası olarak kabul edersek dönem numarası haftadan hesaplanır:

EVALUATE
VAR g =
    ADDCOLUMNS(
        FILTER(Tarih, YEAR(Tarih[Tarih] - Tarih[GunNo] + 4) = 2024),
        "Donem",
            VAR hw = Tarih[HaftaNo]
            VAR c = MIN(4, INT((hw - 1) / 13) + 1)
            VAR wq = hw - (c - 1) * 13
            RETURN (c - 1) * 3 + IF(wq <= 4, 1, IF(wq <= 8, 2, 3)),
        "S", [Net Satış]
    )
RETURN GROUPBY(g, [Donem], "SatisliGun", COUNTX(CURRENTGROUP(), [S]), "Satis", SUMX(CURRENTGROUP(), [S]))

MIN(4, …) 53. haftayı dördüncü çeyreğe, wq 14 olduğu için de son döneme (D12) koyar. 2024 perakende yılının sonuçlarından birkaçı: D1 (4 hafta) 43.545,85; D3 (5 hafta) 63.251,60; D12 (5 hafta) 105.592,25. Beş haftalık dönemi dört haftalıkla doğrudan karşılaştırma; haftalık ortalamaya bak.

Hafta bazlı karşılaştırma: 364 gün geri

Mağaza ekibinin sorusuna dönelim: ISO 2024’ün 10. haftası (4–10 Mart 2024) net satışı 23.869,65. Geçen yılın karşılığı ne?

YöntemKarşılaştırılan günlerSonuç
SAMEPERIODLASTYEAR4–10 Mart 2023 (Cumartesi–Cuma)7.998,30
DATEADD(Tarih[Tarih], -364, DAY)6–12 Mart 2023 (Pazartesi–Pazar)7.126,30

SAMEPERIODLASTYEAR takvim tarihini korur, haftanın gününü değil. “Zaman serisi analizi” dersindeki gün etkisi yüzünden farklı gün karışımlı iki pencereyi karşılaştırmak büyüme oranını bozar. 364 = 52 × 7 olduğu için DATEADD(…, -364, DAY) her günü haftanın aynı gününe taşır.

Satış GY Hafta Hizalı =
CALCULATE([Net Satış], DATEADD(Tarih[Tarih], -364, DAY))

Kenar durumlar

Hazır fonksiyonlar nerede bozulur?

FonksiyonMali yıl (kaydırılmış)Hafta tabanlı / 4-4-5
TOTALYTD, DATESYTDYıl sonu parametresiyle doğruYanlış: yıl başı sabit bir tarih değil
SAMEPERIODLASTYEAR, DATEADD(…, YEAR)Doğru (12 ay kaydırma)Haftanın günü kayar
TOTALMTD, PREVIOUSMONTHDoğru (aylar aynı)Yanlış: dönem ay değildir
PARALLELPERIOD(…, QUARTER)Takvim çeyreği döner, mali çeyrek değil13 haftalık çeyrek değil
STARTOFYEAR, ENDOFYEARYıl sonu parametresi alırGregoryen yıl sınırları

Hazır fonksiyonlar takvimi tarih aritmetiğiyle bilir; mantık sütunlarda yaşıyorsa (ISOYil, Donem, HaftaSira) bunu göremez.

Sütun tabanlı özel zaman zekâsı

Hazır fonksiyonların yerine üç adımlı bir kalıp kullanılır:

  1. Görünen bağlamdan konumu oku: MAX(Tarih[Tarih]), MAX(Tarih[HaftaSira]).
  2. Tarih tablosundaki filtreleri kaldır: REMOVEFILTERS(Tarih) ya da ALL(Tarih).
  3. Yeni dönemi sütunlarla tarif et: Tarih[ISOYil] = y && Tarih[Tarih] <= son.

Örneğin hafta başından bugüne (WTD) yalnızca tarih aritmetiğiyle yazılabilir:

Hafta Başından Satış =
VAR son = MAX(Tarih[Tarih])
VAR bas = son - WEEKDAY(son, 2) + 1
RETURN CALCULATE([Net Satış], DATESBETWEEN(Tarih[Tarih], bas, son))

Üretim modelinde ise sütunlar fiziksel olarak Tarih tablosunda (Power Query ya da kaynakta) bulunur. HaftaSira, ilk haftadan itibaren 1, 2, 3… diye artan bir sıradır. “Önceki hafta” için HaftaNo - 1 yeterli değildir, çünkü 1. haftanın öncesi 0 değil, geçen yılın 52. ya da 53. haftasıdır:

Önceki Hafta (sütunla) =
VAR s = MAX(Tarih[HaftaSira])
RETURN CALCULATE([Net Satış], REMOVEFILTERS(Tarih), Tarih[HaftaSira] = s - 1)

Perakende YTD (sütunla) =
VAR y = MAX(Tarih[ISOYil])
VAR son = MAX(Tarih[Tarih])
RETURN CALCULATE([Net Satış], REMOVEFILTERS(Tarih), Tarih[ISOYil] = y, Tarih[Tarih] <= son)
YolNe zaman?PerformansBakım
Tarih aritmetiği (DATESBETWEEN, DATEADD … DAY)Kural sabit gün sayısıyla anlatılabiliyorsaİyiKolay ama kural kodda gizli
FILTER(ALL(Tarih), ifade)Hızlı deneme, sütun eklenemiyorsaHer satırda ifade hesaplanır; büyük takvimde yavaşlarZor: aynı ifade her ölçüde tekrar eder
Fiziksel sütunlar + REMOVEFILTERSKalıcı model, ekip çalışmasıEn iyi: basit sütun filtreleri depolama motoruna giderKolay: kural tek yerde, Tarih tablosunda

“DAX optimizasyonu” dersinde gördüğün gibi basit sütun eşitlikleri depolama motorunda çözülür; satır satır ifade hesaplayan FILTER formül motoruna iş bırakır.

REMOVEFILTERS’ı unutmaTarih[Tarih] üzerine filtre koyan hazır fonksiyonlar, işaretli tarih tablosunda diğer Tarih filtrelerini kendiliğinden kaldırır. Sütun filtresi (Tarih[ISOYil]) bunu yapmaz. REMOVEFILTERS(Tarih) olmadan, rapordaki Gregoryen Yıl = 2024 dilimleyicisi 2025-H01’in 30–31 Aralık günleriyle kesişir ve hafta yarım görünür.

Test: Her özel ölçüyü DAX sorgu görünümünde bilinen bir haftayla (2024-H10 = 23.869,65) ve yılın ilk/son haftasıyla dene.

Takvim tabanlı zaman zekâsı (önizleme)

Power BI 2025’te bu sorunu doğrudan çözen bir özellik getirdi: takvim tabanlı zaman zekâsı (calendar-based time intelligence). Tarih tablosunda bir ya da birkaç takvim tanımlarsın; zaman zekâsı fonksiyonlarına tarih sütunu yerine takvimin adını verirsin. Microsoft Learn sayfası özelliği Ekim 2026 itibarıyla hâlâ önizleme olarak etiketliyor.

Nasıl açılır, nasıl tanımlanır?

  1. Dosya → Seçenekler ve ayarlar → Seçenekler → Önizleme özellikleri altında “Enhanced DAX Time Intelligence” seçeneğini işaretle ve Desktop’ı yeniden başlat.
  2. Tarih tablosuna sağ tıkla → Takvim seçenekleri (Calendar options) → Yeni takvim.
  3. Kategori ekle ile sütunları kategorilere bağla: Yıl, Çeyrek, Ay, Hafta, Tarih ve “yılın haftası”, “haftanın günü” gibi kısmi kategoriler. Her kategorinin bir birincil sütunu, isteğe bağlı ilişkili sütunları olur. “Tam” (complete) kategoriler bir dönemi tek başına tanımlar (2024-H10); “kısmi” kategoriler tanımlamaz (H10).
table Tarih
    calendar 'Perakende 445'
        calendarColumnGroup = year
            primaryColumn: ISOYil
        calendarColumnGroup = month
            primaryColumn: DonemAnahtari
        calendarColumnGroup = week
            primaryColumn: HaftaAnahtari
        calendarColumnGroup = date
            primaryColumn: Tarih
Perakende YTD = TOTALYTD([Net Satış], 'Perakende 445')
Perakende WTD = TOTALWTD([Net Satış], 'Perakende 445')
Perakende GY  = CALCULATE([Net Satış], DATEADD('Perakende 445', -1, YEAR))

Böylece TOTALWTD gibi hafta fonksiyonları kullanılabilir, “geçen yıl” takvimin kendi yılına göre hesaplanır. DATEADD ve SAMEPERIODLASTYEAR “sabit” fonksiyonlardır: yalnızca yana doğru kaydırır. Diğerleri esnektir. Bir takvim sütununa bağlam koymak, o kategorinin üstündeki ve altındaki kategorilerdeki bağlamı temizler.

KlasikTakvim tabanlı (önizleme)
Takvim türüGregoryen ya da kaydırılmış GregoryenHer türlü takvim
Hafta hesaplarıYokVar
YazımSAMEPERIODLASTYEAR(Tarih[Tarih])TOTALYTD([Net Satış], 'Mali')

Sınırlamalar (Learn’e göre)

Bu uygulamadaTarayıcıdaki motor takvim tanımlarını desteklemiyor; bu bölümdeki bloklar bu yüzden çalıştırılamaz. Alıştırmalar sütun tabanlı kalıpla yapılır.

Üretim kararı: Önizleme özelliği kurumsal bir modelde ana yol olmamalı. Bugün sütun tabanlı kalıbı kur; ISOYil, HaftaAnahtari, DonemAnahtari gibi sütunları zaten hazırlamış olacağın için özellik genel kullanıma geçtiğinde takvim tanımına taşımak kolaylaşır.

Kontrol listesi

Alıştırmalara geç (12)