Cheat Sheet DAX Power BI: 45 Fungsi yang Paling Sering Dipakai
TL;DR
DAX punya lebih dari 250 fungsi, tapi kerjaan dashboard sehari-hari biasanya cuma butuh sekitar 45. Intinya ada di empat kelompok: agregasi (SUM, DIVIDE, DISTINCTCOUNT), pengubah konteks filter (CALCULATE, FILTER, ALL), penelusur relasi (RELATED, LOOKUPVALUE), dan time intelligence (TOTALYTD, SAMEPERIODLASTYEAR, DATEADD). CALCULATE yang paling penting dikuasai, soalnya hampir semua measure lanjutan dibangun dari dia.
Cheat sheet DAX ini isinya 45 fungsi yang paling sering muncul waktu bikin measure di Power BI, dikelompokkan biar kamu gampang nyari saat lagi ngerjain dashboard.
DAX punya lebih dari 250 fungsi menurut referensi resmi Microsoft. Tapi dari pengalaman ngerjain dashboard penjualan, laporan stok, dan monitoring kas, yang beneran kepakai berulang cuma sekitar 45.
Contoh di sini pakai dua tabel: Penjualan (transaksi harian toko_berkah) dan Produk (master barang), dihubungkan lewat kode_produk.
Fungsi agregasi dasar apa saja yang wajib dihafal?
Sepuluh fungsi ini yang paling sering jadi measure pertama di setiap laporan. Semuanya baca satu kolom lalu balikin satu angka, mengikuti filter yang lagi aktif di visual.
| Fungsi | Sintaks | Kegunaan |
|---|---|---|
| SUM | SUM(kolom) | Jumlahin isi satu kolom angka |
| AVERAGE | AVERAGE(kolom) | Rata-rata kolom angka, baris kosong dilewat |
| MIN | MIN(kolom) | Nilai terkecil |
| MAX | MAX(kolom) | Nilai terbesar |
| COUNT | COUNT(kolom) | Jumlah baris yang isinya angka |
| COUNTA | COUNTA(kolom) | Jumlah baris yang gak kosong, termasuk teks |
| COUNTROWS | COUNTROWS(tabel) | Jumlah baris satu tabel |
| DISTINCTCOUNT | DISTINCTCOUNT(kolom) | Jumlah nilai unik, misalnya pelanggan aktif |
| DIVIDE | DIVIDE(atas, bawah, [alt]) | Pembagian aman dari error bagi nol |
| SUMX | SUMX(tabel, ekspresi) | Hitung per baris dulu, baru dijumlahin |
Total Penjualan = SUM(Penjualan[nominal])
Omzet Kotor = SUMX(Penjualan, Penjualan[qty] * Penjualan[harga_satuan])
Margin % = DIVIDE([Laba Kotor], [Total Penjualan], 0)
DIVIDE itu bukan pilihan gaya. Operator garis miring bakal munculin error kalau penyebutnya nol, dan visual kamu langsung nampilin tanda seru merah.
Kapan pakai fungsi iterator berakhiran X?
Fungsi iterator jalan baris per baris di tabel yang kamu tunjuk, ngitung ekspresi di tiap baris, lalu ngagregasi hasilnya. Pakai ini setiap kali perhitungannya butuh dua kolom dikaliin atau dibandingin di level transaksi. Fungsi agregasi biasa gak bisa ngerjain itu.
| Fungsi | Sintaks | Kegunaan |
|---|---|---|
| AVERAGEX | AVERAGEX(tabel, ekspresi) | Rata-rata dari hasil hitungan per baris |
| MINX | MINX(tabel, ekspresi) | Nilai terkecil dari ekspresi per baris |
| MAXX | MAXX(tabel, ekspresi) | Nilai terbesar dari ekspresi per baris |
| COUNTX | COUNTX(tabel, ekspresi) | Hitung baris yang ekspresinya menghasilkan angka |
| CONCATENATEX | CONCATENATEX(tabel, ekspresi, pemisah) | Gabungin teks jadi satu string, buat judul dinamis |
Rata-rata Nilai Struk =
AVERAGEX(
VALUES(Penjualan[no_struk]),
CALCULATE(SUM(Penjualan[nominal]))
)
Judul Filter = CONCATENATEX(VALUES(Produk[kategori]), Produk[kategori], ", ")
Fungsi apa yang dipakai buat mengubah konteks filter?
Konteks filter adalah kumpulan filter yang lagi aktif waktu satu angka dihitung, datang dari slicer, baris tabel, atau visual. Kelompok fungsi ini yang bikin kamu bisa ngitung angka dengan filter beda dari yang lagi dipakai visual. CALCULATE jadi pintu masuknya.
| Fungsi | Sintaks | Kegunaan |
|---|---|---|
| CALCULATE | CALCULATE(ekspresi, filter1, ...) | Hitung ulang measure dengan filter yang kamu tentukan |
| FILTER | FILTER(tabel, kondisi) | Balikin tabel hasil saringan, dipakai di dalam CALCULATE |
| ALL | ALL(tabel atau kolom) | Buang semua filter, buat ngitung total keseluruhan |
| ALLEXCEPT | ALLEXCEPT(tabel, kolom...) | Buang semua filter kecuali kolom yang disebut |
| ALLSELECTED | ALLSELECTED(tabel) | Buang filter visual tapi hormati pilihan slicer |
| REMOVEFILTERS | REMOVEFILTERS(kolom) | Versi lebih jelas dari ALL khusus buat hapus filter |
| KEEPFILTERS | KEEPFILTERS(filter) | Tambah filter tanpa menimpa filter yang udah ada |
| VALUES | VALUES(kolom) | Daftar nilai unik yang lolos filter saat itu |
| DISTINCT | DISTINCT(kolom) | Mirip VALUES, tapi gak ikut sertakan baris kosong |
| SELECTEDVALUE | SELECTEDVALUE(kolom, [alt]) | Ambil satu nilai kalau slicer cuma milih satu |
Penjualan Sembako =
CALCULATE([Total Penjualan], Produk[kategori] = "Sembako")
Kontribusi Kategori % =
DIVIDE(
[Total Penjualan],
CALCULATE([Total Penjualan], ALL(Produk[kategori]))
)
Transaksi di Atas 500rb =
CALCULATE(
COUNTROWS(Penjualan),
FILTER(Penjualan, Penjualan[nominal] > 500000)
)
Kalau kamu cuma sempat hafal satu fungsi dari seluruh cheat sheet ini, hafalin CALCULATE. Hampir semua measure lanjutan dibangun dari dia.
Gimana cara ambil data dari tabel lain lewat relasi?
Lima fungsi ini nyambungin tabel yang udah punya relasi di model. RELATED narik satu nilai dari sisi banyak ke sisi satu, sementara RELATEDTABLE narik sekumpulan baris ke arah sebaliknya. LOOKUPVALUE jalan tanpa relasi sama sekali.
| Fungsi | Sintaks | Kegunaan |
|---|---|---|
| RELATED | RELATED(kolom) | Ambil satu nilai dari tabel di sisi satu relasi |
| RELATEDTABLE | RELATEDTABLE(tabel) | Ambil baris terkait dari tabel di sisi banyak |
| LOOKUPVALUE | LOOKUPVALUE(kolom_hasil, kolom_cari, nilai) | Cari nilai tanpa butuh relasi, mirip VLOOKUP |
| USERELATIONSHIP | USERELATIONSHIP(kol1, kol2) | Aktifkan relasi cadangan buat satu perhitungan |
| CROSSFILTER | CROSSFILTER(kol1, kol2, arah) | Ubah arah aliran filter sementara |
Laba Kotor =
SUMX(
Penjualan,
Penjualan[qty] * (Penjualan[harga_satuan] - RELATED(Produk[harga_pokok]))
)
Penjualan per Tanggal Kirim =
CALCULATE(
[Total Penjualan],
USERELATIONSHIP(Penjualan[tanggal_kirim], Kalender[tanggal])
)
Konsep dasar relasi antar tabel dan agregasinya bisa kamu cek lagi di halaman aggregate function kalau masih terasa asing.
Fungsi logika apa yang paling sering dipakai di measure?
Lima fungsi ini ngatur percabangan dan penanganan nilai kosong. SWITCH bikin rantai kondisi jadi jauh lebih enak dibaca dibanding IF bertingkat, terutama waktu kamu bikin kartu KPI yang berubah label sesuai ambang batas.
| Fungsi | Sintaks | Kegunaan |
|---|---|---|
| IF | IF(kondisi, hasil_benar, hasil_salah) | Percabangan dua arah |
| SWITCH | SWITCH(TRUE(), kondisi1, hasil1, ...) | Rantai kondisi bertingkat yang rapi |
| IFERROR | IFERROR(ekspresi, nilai_alternatif) | Tangkap error dan ganti dengan nilai aman |
| ISBLANK | ISBLANK(nilai) | Cek apakah hasilnya kosong |
| BLANK | BLANK() | Balikin nilai kosong, biar visual gak nampilin nol |
Status Target =
SWITCH(
TRUE(),
[Pencapaian %] >= 1, "Tercapai",
[Pencapaian %] >= 0.8, "Mendekati",
"Di bawah target"
)
Penjualan Bersih = IF(ISBLANK([Total Penjualan]), BLANK(), [Total Penjualan] - [Retur])
Pola yang sama juga ada di spreadsheet. Kalau kamu datang dari Excel, logika IF dan IFERROR di sana kerjanya mirip.
Fungsi time intelligence mana yang paling kepakai?
Enam fungsi ini yang nutup hampir semua kebutuhan perbandingan periode. Syaratnya satu: model kamu harus punya tabel tanggal lengkap tanpa tanggal bolong, dan tabel itu udah ditandai lewat menu Mark as date table.
| Fungsi | Sintaks | Kegunaan |
|---|---|---|
| CALENDAR | CALENDAR(awal, akhir) | Bikin tabel tanggal dari rentang yang kamu tentukan |
| TOTALYTD | TOTALYTD(ekspresi, tanggal) | Akumulasi dari awal tahun sampai tanggal aktif |
| DATESYTD | DATESYTD(tanggal) | Balikin daftar tanggal sejak awal tahun |
| SAMEPERIODLASTYEAR | SAMEPERIODLASTYEAR(tanggal) | Geser periode aktif mundur satu tahun |
| DATEADD | DATEADD(tanggal, jumlah, satuan) | Geser periode maju atau mundur sesuai satuan |
| DATESINPERIOD | DATESINPERIOD(tanggal, mulai, jumlah, satuan) | Rentang bergerak, misalnya 3 bulan terakhir |
Penjualan YTD = TOTALYTD([Total Penjualan], Kalender[tanggal])
Penjualan Tahun Lalu =
CALCULATE([Total Penjualan], SAMEPERIODLASTYEAR(Kalender[tanggal]))
Pertumbuhan YoY % =
DIVIDE([Total Penjualan] - [Penjualan Tahun Lalu], [Penjualan Tahun Lalu])
Rata-rata 3 Bulan Terakhir =
CALCULATE(
AVERAGEX(VALUES(Kalender[bulan]), [Total Penjualan]),
DATESINPERIOD(Kalender[tanggal], MAX(Kalender[tanggal]), -3, MONTH)
)
Fungsi apa buat ranking dan bikin tabel virtual?
Empat fungsi terakhir dipakai waktu kamu butuh peringkat atau tabel bantu di dalam measure. SUMMARIZE dan ADDCOLUMNS bikin tabel sementara yang cuma hidup selama perhitungan berjalan.
| Fungsi | Sintaks | Kegunaan |
|---|---|---|
| RANKX | RANKX(tabel, ekspresi, , urutan) | Kasih peringkat berdasarkan nilai measure |
| TOPN | TOPN(jumlah, tabel, ekspresi) | Ambil sekian baris teratas |
| SUMMARIZE | SUMMARIZE(tabel, kolom_grup, ...) | Kelompokkan baris jadi tabel ringkasan |
| ADDCOLUMNS | ADDCOLUMNS(tabel, nama, ekspresi) | Tambah kolom hitungan ke tabel virtual |
Peringkat Produk =
RANKX(ALL(Produk[nama_produk]), [Total Penjualan], , DESC)
Penjualan 10 Produk Teratas =
CALCULATE(
[Total Penjualan],
TOPN(10, ALL(Produk[nama_produk]), [Total Penjualan], DESC)
)
Sintaks resmi dan daftar lengkap seluruh fungsi bisa kamu cocokkan di DAX function reference Microsoft.
Contoh kasus: dashboard penjualan toko_berkah
Dataset ngulikdata untuk toko_berkah punya 11.407 baris transaksi selama 14 bulan, 1.842 pelanggan, dan 386 SKU aktif. Dashboard dasarnya cuma butuh tujuh measure.
Total Penjualan = SUM(Penjualan[nominal])
Jumlah Transaksi = DISTINCTCOUNT(Penjualan[no_struk])
Rata-rata Struk = DIVIDE([Total Penjualan], [Jumlah Transaksi])
Pelanggan Aktif = DISTINCTCOUNT(Penjualan[id_pelanggan])
Penjualan YTD = TOTALYTD([Total Penjualan], Kalender[tanggal])
Penjualan Tahun Lalu = CALCULATE([Total Penjualan], SAMEPERIODLASTYEAR(Kalender[tanggal]))
Pertumbuhan YoY % = DIVIDE([Total Penjualan] - [Penjualan Tahun Lalu], [Penjualan Tahun Lalu])
Angka yang menarik dari model ini: rata-rata nilai struk 386 SKU itu Rp 612.000, tapi kalau 214 pelanggan grosir dikeluarkan, angkanya jatuh ke Rp 178.000. Selisih 3,4 kali lipat itu yang bikin satu kartu KPI "rata-rata transaksi" gampang bikin salah baca.
Solusinya bukan nambah measure, tapi nambah satu slicer tipe pelanggan di samping kartunya.
Kesalahan umum waktu nulis DAX
Pakai calculated column padahal butuh measure. Calculated column dihitung sekali saat refresh dan nyimpen hasil di tiap baris. Angka yang harus berubah ikut slicer wajib jadi measure.
Nulis FILTER buat kondisi sederhana. CALCULATE([Total], FILTER(Produk, Produk[kategori]="Sembako")) lebih lambat dari CALCULATE([Total], Produk[kategori]="Sembako"). Pakai FILTER cuma kalau kondisinya melibatkan measure.
Tabel tanggal bolong. Kalau bulan Februari gak ada penjualan dan kamu gak punya tabel kalender terpisah, semua fungsi time intelligence bakal ngasih hasil ngaco.
Nested IF lima tingkat. Ganti ke SWITCH(TRUE(), ...) begitu kondisinya lebih dari dua. Lebih gampang dibaca dan lebih gampang diperbaiki tiga bulan kemudian.
Lupa VAR. Kalau satu measure manggil measure lain tiga kali, simpan di variabel dulu pakai VAR dan RETURN. Hasilnya sama, waktu hitungnya lebih pendek.
FAQ
Apa bedanya SUM dan SUMX di DAX?
SUM jumlahin satu kolom apa adanya. SUMX jalan baris per baris, ngitung ekspresi dulu di tiap baris, baru dijumlahin. Kalau kamu butuh harga dikali kuantitas per transaksi, pakai SUMX soalnya perkaliannya harus terjadi di level baris. SUM gak bisa ngerjain itu karena dia cuma baca satu kolom jadi.
Kenapa CALCULATE dibilang fungsi paling penting di DAX?
CALCULATE satu-satunya fungsi yang bisa ganti konteks filter sebelum ngitung. Semua measure kayak penjualan tahun lalu, kontribusi per kategori, atau angka yang abaikan slicer, dibangun pakai dia. Fungsi lain kayak ALL dan FILTER praktis cuma jadi bahan yang dimasukin ke argumen CALCULATE.
Kapan harus pakai DIVIDE dibanding operator garis miring?
Selalu pakai DIVIDE buat pembagian di measure. Operator garis miring bakal balikin error kalau penyebutnya nol, dan itu bikin visual kamu nampilin tanda seru. DIVIDE otomatis balikin blank saat penyebutnya nol, atau nilai lain kalau kamu isi argumen ketiga. Perhitungan margin dan growth wajib pakai ini.
Apa fungsi time intelligence butuh tabel tanggal khusus?
Butuh. Fungsi kayak TOTALYTD, DATEADD, dan SAMEPERIODLASTYEAR minta tabel tanggal yang lengkap tanpa bolong dan udah ditandai lewat Mark as date table. Kalau kamu cuma andalin kolom tanggal di tabel transaksi, bulan yang gak ada penjualannya bakal hilang dan hasil perbandingan periodenya meleset.
Bedanya measure dan calculated column apa?
Calculated column dihitung sekali waktu data di-refresh dan nyimpen hasilnya di memori tiap baris. Measure dihitung ulang tiap kali visual digambar, sesuai filter yang lagi aktif. Buat angka yang berubah ikut slicer kayak total penjualan, pakai measure. Calculated column dipakai buat label atau kategori yang nempel permanen di baris.
Penutup
45 fungsi di atas nutup mayoritas kerjaan dashboard harian. Sisanya baru kamu cari saat ketemu kasus khusus.
Urutan belajar yang aku sarankan: kuasai agregasi dasar plus DIVIDE dulu, lalu CALCULATE bareng ALL dan FILTER, baru masuk time intelligence. Tiga tahap itu udah cukup buat bikin laporan penjualan yang layak dipresentasikan.
Simpan halaman ini buat rujukan cepat waktu lagi ngerjain measure. Kalau kamu lagi nyusun KPI buat dashboard pertamamu, tentuin dulu angka apa yang mau dipantau sebelum nulis satu baris DAX pun.
Mau praktek langsung? Mulai latihan SQL gratis
Latihan interaktif, langsung di browser.
Artikel terkait
Cara Membuat Dashboard di Google Sheets Tanpa Tools Tambahan
Dashboard penjualan yang rapi bisa kamu bikin cuma pakai Google Sheets, tanpa Looker Studio, tanpa add-on, tanpa bayar apa pun. Ini urutan 6 langkahnya, lengkap dengan rumusnya.
Dashboard vs Laporan: Bedanya dan Kapan Bikin yang Mana
Dashboard buat mantau angka yang berubah tiap hari. Laporan buat jawab satu pertanyaan sekali dan tuntas. Salah pilih, kerjaanmu kebuang.
KPI Keuangan: Metrik yang Dibaca CFO Setiap Bulan
Delapan KPI keuangan yang beneran dibuka CFO tiap bulan, rumusnya, dan cara nyusunnya jadi satu dashboard yang kebaca dalam 90 detik.