Bagikan melalui


Pendahuluan

Gambaran Umum

Microsoft Power Query menyediakan pengalaman "dapatkan data" yang kuat yang mencakup banyak fitur. Kemampuan inti Power Query adalah memfilter dan menggabungkan, yaitu, untuk "mash-up" data dari satu atau beberapa kumpulan kaya sumber data yang didukung. Setiap mashup data tersebut dinyatakan menggunakan bahasa rumus Power Query (secara informal dikenal sebagai "M"). Power Query menyematkan dokumen M dalam berbagai produk Microsoft, termasuk Excel, Power BI, Analysis Services, dan Dataverse, untuk mengaktifkan mashup data yang dapat diulang.

Dokumen ini menyediakan spesifikasi untuk M. Setelah pengenalan singkat yang bertujuan membangun beberapa intuisi pertama dan keakraban dengan bahasa, dokumen mencakup bahasa dengan tepat dalam beberapa langkah progresif:

  1. Struktur leksikal mendefinisikan kumpulan teks yang valid secara leksikal.

  2. Nilai, ekspresi, lingkungan dan variabel, pengidentifikasi, dan model evaluasi membentuk konsep dasar bahasa.

  3. Spesifikasi terperinci dari nilai, baik primitif maupun terstruktur, mendefinisikan domain target bahasa.

  4. Nilai memiliki jenis, sendiri jenis nilai khusus, yang keduanya mencirikan jenis nilai dasar dan membawa metadata tambahan yang khusus untuk bentuk nilai terstruktur.

  5. Kumpulan operator dalam M menentukan jenis ekspresi apa yang dapat dibentuk.

  6. Fungsi, jenis nilai khusus lainnya, menyediakan fondasi untuk pustaka standar yang kaya untuk M dan memungkinkan penambahan abstraksi baru.

  7. Kesalahan dapat terjadi saat menerapkan operator atau fungsi selama evaluasi ekspresi. Meskipun kesalahan bukan nilai, ada cara untuk menangani kesalahan yang memetakan kesalahan kembali ke nilai.

  8. Biarkan ekspresi memungkinkan pengenalan definisi tambahan yang digunakan untuk membangun ekspresi kompleks dalam langkah-langkah yang lebih kecil.

  9. Jika ekspresi mendukung evaluasi bersyarkat .

  10. Bagian menyediakan mekanisme modularitas sederhana. (Bagian belum dimanfaatkan oleh Power Query.)

  11. Akhirnya, tata bahasa terkonsolidasi mengumpulkan fragmen tata bahasa dari semua bagian lain dari dokumen ini ke dalam satu definisi lengkap.

Untuk teori bahasa komputer: bahasa rumus yang ditentukan dalam dokumen ini sebagian besar bahasa fungsional murni, berurutan lebih tinggi, ditik secara dinamis, sebagian malas.

Ekspresi dan nilai

Konstruksi pusat dalam M adalah ekspresi. Ekspresi dapat dievaluasi (dihitung), menghasilkan satu nilai.

Meskipun banyak nilai dapat ditulis secara harfiah sebagai ekspresi, nilai bukanlah ekspresi. Misalnya, ekspresi 1 mengevaluasi ke nilai 1; ekspresi 1+1 mengevaluasi ke nilai 2. Perbedaan ini halus, tetapi penting. Ekspresi adalah resep untuk evaluasi; nilai adalah hasil evaluasi.

Contoh berikut mengilustrasikan berbagai jenis nilai yang tersedia di M. Sebagai konvensi, nilai ditulis menggunakan bentuk harfiah di mana nilai tersebut akan muncul dalam ekspresi yang mengevaluasi hanya pada nilai tersebut. (Perhatikan bahwa // menunjukkan awal komentar yang berlanjut ke akhir baris.)

  • Nilai primitif adalah nilai bagian tunggal, seperti angka, logis, teks, atau null. Nilai null dapat digunakan untuk menunjukkan tidak adanya data apa pun.

    123                  // A number
    true                 // A logical
    "abc"                // A text
    null                 // null value
    
  • Nilai daftar adalah urutan nilai yang diurutkan. M mendukung daftar tak terbatas, tetapi jika ditulis sebagai harfiah, daftar memiliki panjang tetap. Karakter kurung kurawal { dan } menunjukkan awal dan akhir daftar.

    {123, true, "A"}     // list containing a number, a logical, and 
                          //     a text 
    {1, 2, 3}            // list of three numbers 
    
  • Catatan adalah sekumpulan bidang. Bidang adalah pasangan nama/nilai di mana nama adalah nilai teks yang unik dalam rekaman bidang. Sintaksis harfiah untuk nilai rekaman memungkinkan nama ditulis tanpa tanda kutip, formulir yang juga disebut sebagai pengidentifikasi. Berikut ini memperlihatkan rekaman yang berisi tiga bidang bernama "A", "B", dan "C", yang memiliki nilai 1, 2, dan 3.

    [ 
          A = 1,  
          B = 2,  
          C = 3 
    ]
    
  • Tabel adalah sekumpulan nilai yang diatur ke dalam kolom (yang diidentifikasi berdasarkan nama), dan baris. Tidak ada sintaks harfiah untuk membuat tabel, tetapi ada beberapa fungsi standar yang dapat digunakan untuk membuat tabel dari daftar atau rekaman.

    Contohnya:

    #table( {"A", "B"}, { {1, 2}, {3, 4} } ) 
    

    Ini membuat tabel bentuk berikut:

    Image of an example table in the M formula language.

  • Fungsi adalah nilai yang, ketika dipanggil dengan argumen, menghasilkan nilai baru. Fungsi ditulis dengan mencantumkan parameter fungsi dalam tanda kurung, diikuti dengan simbol =>masuk ke , diikuti dengan ekspresi yang menentukan fungsi. Ekspresi tersebut biasanya mengacu pada parameter (berdasarkan nama).

    (x, y) => (x + y) / 2`
    

Evaluasi

Model evaluasi bahasa M dimodelkan setelah model evaluasi yang biasanya ditemukan di spreadsheet, di mana urutan perhitungan dapat ditentukan berdasarkan dependensi antara rumus dalam sel.

Jika Anda telah menulis rumus dalam lembar bentang seperti Excel, Anda mungkin mengenali rumus di sebelah kiri menghasilkan nilai di sebelah kanan saat dihitung:

Image of the formulas on the right resulting in the values on the left.

Di M, bagian ekspresi dapat mereferensikan bagian lain dari ekspresi berdasarkan nama, dan proses evaluasi secara otomatis menentukan urutan penghitungan ekspresi yang direferensikan.

Anda dapat menggunakan rekaman untuk menghasilkan ekspresi yang setara dengan contoh spreadsheet sebelumnya. Saat menginisialisasi nilai bidang, Anda bisa merujuk ke bidang lain dalam rekaman dengan menggunakan nama bidang, sebagai berikut:

[  
    A1 = A2 * 2,  
    A2 = A3 + 1,  
    A3 = 1  
]

Ekspresi di atas setara dengan yang berikut ini (karena keduanya mengevaluasi ke nilai yang sama):

[  
    A1 = 4,  
    A2 = 2,  
    A3 = 1  
]

Rekaman dapat dimuat di dalam, atau ditumpuk, dalam rekaman lain. Anda dapat menggunakan operator pencarian ([]) untuk mengakses bidang rekaman berdasarkan nama. Misalnya, rekaman berikut ini memiliki bidang bernama Sales yang berisi rekaman, dan bidang bernama Total yang mengakses FirstHalf bidang Sales dan SecondHalf rekaman:

[  
    Sales = [ FirstHalf = 1000, SecondHalf = 1100 ], 
    Total = Sales[FirstHalf] + Sales[SecondHalf] 
]

Ekspresi di atas setara dengan yang berikut ini ketika dievaluasi:

[  
    Sales = [ FirstHalf = 1000, SecondHalf = 1100 ], 
    Total = 2100 
]

Rekaman juga dapat dimuat dalam daftar. Anda dapat menggunakan operator indeks posisi ({}) untuk mengakses item dalam daftar menurut indeks numeriknya. Nilai dalam daftar disebut menggunakan indeks berbasis nol dari awal daftar. Misalnya, indeks 0 dan 1 digunakan untuk mereferensikan item pertama dan kedua dalam daftar di bawah ini:

[ 
    Sales =  
        {  
            [  
                Year = 2007,  
                FirstHalf = 1000,  
                SecondHalf = 1100, 
                Total = FirstHalf + SecondHalf // 2100 
            ], 
            [  
                Year = 2008,  
                FirstHalf = 1200,  
                SecondHalf = 1300, 
                Total = FirstHalf + SecondHalf // 2500 
            ]  
        }, 
    TotalSales = Sales{0}[Total] + Sales{1}[Total] // 4600 
]

Ekspresi anggota daftar dan rekaman (serta biarkan ekspresi) dievaluasi menggunakan evaluasi malas, yang berarti bahwa mereka dievaluasi hanya sesuai kebutuhan. Semua ekspresi lain dievaluasi menggunakan evaluasi bersemangat, yang berarti bahwa ekspresi tersebut dievaluasi segera ketika ditemui selama proses evaluasi. Cara yang baik untuk memikirkan hal ini adalah dengan mengingat bahwa mengevaluasi ekspresi daftar atau rekaman mengembalikan nilai daftar atau rekaman yang mengingat bagaimana item daftar atau bidang rekamannya perlu dihitung, ketika diminta (oleh operator pencarian atau indeks).

Fungsi

Di M, fungsi adalah pemetaan dari sekumpulan nilai input ke satu nilai output. Fungsi ditulis dengan terlebih dahulu menamai sekumpulan nilai input yang diperlukan (parameter ke fungsi) dan kemudian memberikan ekspresi yang menghitung hasil fungsi menggunakan nilai input tersebut (isi fungsi) mengikuti simbol masuk ke (=>). Contohnya:

(x) => x + 1                    // function that adds one to a value 
(x, y) =>  x + y                // function that adds two values

Fungsi adalah nilai seperti angka atau nilai teks. Contoh berikut menunjukkan fungsi yang merupakan nilai bidang Tambahkan yang kemudian dipanggil, atau dijalankan, dari beberapa bidang lainnya. Saat fungsi dipanggil, sekumpulan nilai ditentukan yang secara logis digantikan untuk kumpulan nilai input yang diperlukan dalam ekspresi isi fungsi.

[ 
    Add = (x, y) => x + y,
    OnePlusOne = Add(1, 1),     // 2 
    OnePlusTwo = Add(1, 2)      // 3
]

Pustaka

M menyertakan sekumpulan definisi umum yang tersedia untuk digunakan dari ekspresi yang disebut pustaka standar, atau singkatnya hanya pustaka . Definisi ini terdiri dari sekumpulan nilai bernama. Nama nilai yang disediakan oleh pustaka tersedia untuk digunakan dalam ekspresi tanpa didefinisikan secara eksplisit oleh ekspresi. Contohnya:

Number.E                        // Euler's number e (2.7182...) 
Text.PositionOf("Hello", "ll")  // 2

Operators

M menyertakan sekumpulan operator yang dapat digunakan dalam ekspresi. Operator diterapkan ke operand untuk membentuk ekspresi simbolis. Misalnya, dalam ekspresi 1 + 2 angka 1 dan 2 merupakan operand dan operator adalah operator penambahan (+).

Arti operator dapat bervariasi tergantung pada jenis nilai operand-nya. Misalnya, operator plus dapat digunakan dengan jenis nilai lain selain angka:

1 + 2                   // numeric addition: 3 
#time(12,23,0) + #duration(0,0,2,0) 
                        // time arithmetic: #time(12,25,0)

Contoh lain operator dengan arti yang bergantung pada operand adalah operator kombinasi (&):

"A" & "BC"              // text concatenation: "ABC" 
{1} & {2, 3}            // list concatenation: {1, 2, 3} 
[ a = 1 ] & [ b = 2 ]   // record merge: [ a = 1, b = 2 ]

Perhatikan bahwa beberapa operator tidak mendukung semua kombinasi nilai. Contohnya:

1 + "2"  // error: adding number and text isn't supported

Ekspresi yang, ketika dievaluasi, mengalami kondisi operator yang tidak terdefinisi mengevaluasi kesalahan.

Metadata

Metadata adalah informasi tentang nilai yang terkait dengan nilai. Metadata direpresentasikan sebagai nilai rekaman, yang disebut rekaman metadata. Bidang rekaman metadata dapat digunakan untuk menyimpan metadata untuk nilai.

Setiap nilai memiliki catatan metadata. Jika nilai rekaman metadata belum ditentukan, rekaman metadata kosong (tidak memiliki bidang).

Catatan metadata menyediakan cara untuk mengaitkan informasi tambahan dengan segala jenis nilai dengan cara yang tidak mengganggu. Mengaitkan rekaman metadata dengan nilai tidak mengubah nilai atau perilakunya.

Nilai y catatan metadata dikaitkan dengan nilai x yang ada menggunakan sintaks x meta y. Misalnya, kode berikut mengaitkan rekaman metadata dengan bidang dan Tags dengan Rating nilai "Mozart"teks :

"Mozart" meta [ Rating = 5, Tags = {"Classical"} ]

Untuk nilai yang sudah membawa catatan metadata yang tidak kosong, hasil penerapan meta adalah dari komputasi penggabungan rekaman dari rekaman yang ada dan metadata baru. Misalnya, dua ekspresi berikut setara satu sama lain dan dengan ekspresi sebelumnya:

("Mozart" meta [ Rating = 5 ]) meta [ Tags = {"Classical"} ] 
"Mozart" meta ([ Rating = 5 ] & [ Tags = {"Classical"} ])

Rekaman metadata dapat diakses untuk nilai tertentu menggunakan fungsi Value.Metadata . Dalam contoh berikut, ekspresi di ComposerRating bidang mengakses rekaman metadata nilai di Composer bidang , lalu mengakses Rating bidang rekaman metadata.

[ 
    Composer = "Mozart" meta [ Rating = 5, Tags = {"Classical"} ], 
    ComposerRating = Value.Metadata(Composer)[Rating] // 5
]

Biarkan ekspresi

Banyak contoh yang ditampilkan sejauh ini telah menyertakan semua nilai harfiah ekspresi dalam hasil ekspresi. Ekspresi let memungkinkan sekumpulan nilai untuk dihitung, diberi nama, lalu digunakan dalam ekspresi berikutnya yang mengikuti in. Misalnya, dalam contoh data penjualan kami, Anda dapat melakukan:

let 
    Sales2007 =  
        [  
            Year = 2007,  
            FirstHalf = 1000,  
            SecondHalf = 1100, 
            Total = FirstHalf + SecondHalf // 2100 
        ], 
    Sales2008 =  
        [  
            Year = 2008,  
            FirstHalf = 1200,  
            SecondHalf = 1300, 
            Total = FirstHalf + SecondHalf // 2500 
        ] 
  in Sales2007[Total] + Sales2008[Total] // 4600

Hasil ekspresi di atas adalah nilai angka (4600) yang dihitung dari nilai yang terikat ke nama Sales2007 dan Sales2008.

Jika ekspresi

Ekspresi if memilih antara dua ekspresi berdasarkan kondisi logis. Contohnya:

if 2 > 1 then
    2 + 2
else  
    1 + 1

Ekspresi pertama (2 + 2) dipilih jika ekspresi logis (2 > 1) benar, dan ekspresi kedua (1 + 1) dipilih jika salah. Ekspresi yang dipilih (dalam hal 2 + 2ini ) dievaluasi dan menjadi hasil if ekspresi (4).

Kesalahan

Kesalahan adalah indikasi bahwa proses evaluasi ekspresi tidak dapat menghasilkan nilai.

Kesalahan dimunculkan oleh operator dan fungsi yang mengalami kondisi kesalahan atau dengan menggunakan ekspresi kesalahan. Kesalahan ditangani menggunakan try ekspresi . Ketika kesalahan dimunculkan, nilai ditentukan yang dapat digunakan untuk menunjukkan mengapa kesalahan terjadi.

let Sales = 
    [ 
        Revenue = 2000, 
        Units = 1000, 
        UnitPrice = if Units = 0 then error "No Units"
                    else Revenue / Units 
    ], 
    UnitPrice = try Number.ToText(Sales[UnitPrice])
in "Unit Price: " & 
    (if UnitPrice[HasError] then UnitPrice[Error][Message]
    else UnitPrice[Value])

Contoh di atas mengakses Sales[UnitPrice] bidang dan memformat nilai yang menghasilkan hasilnya:

"Unit Price: 2"

Units Jika bidang telah nol, maka UnitPrice bidang akan menimbulkan kesalahan, yang akan ditangani oleh try. Nilai yang dihasilkan kemudian akan menjadi:

"No Units"

try Ekspresi mengonversi nilai dan kesalahan yang tepat menjadi nilai rekaman yang menunjukkan apakah try ekspresi menangani kesalahan, atau tidak, dan nilai yang tepat atau rekaman kesalahan yang diekstraknya saat menangani kesalahan. Misalnya, pertimbangkan ekspresi berikut yang menimbulkan kesalahan lalu tangani segera:

try error "negative unit count"

Ekspresi ini mengevaluasi ke nilai rekaman berlapis berikut, menjelaskan [HasError]pencarian bidang , [Error], dan [Message] dalam contoh harga unit sebelumnya.

[ 
    HasError = true, 
    Error = 
        [ 
            Reason = "Expression.Error", 
            Message = "negative unit count", 
            Detail = null 
        ] 
]

Kasus umumnya adalah mengganti kesalahan dengan nilai default. Ekspresi try dapat digunakan dengan klausul opsional otherwise untuk mencapainya dalam bentuk ringkas:

try error "negative unit count" otherwise 42 
// 42