BelajarVBA 005 - Procedure seri 1


Coretan Mr. Kid


Harta akan terasa habis yang ada ditangan ketika dibagikan, sedangkan ilmu tidak pernah habis ketika dibagikan

Pada BelajarVBA 002 telah disinggung sedikit tentang prosedur, yaitu pengertian dan bentuk dasar sebuah prosedur. Pada pembahasan kali ini, akan kita jelajahi lebih jauh tentang seluk beluk prosedur. Mulai dari jenisnya hingga penggunaan prosedur yang dideklarasikan secara lengkap. Untuk memudahkan proses belajar, maka file BelajarVBA004.xlsm bisa menjadi media untuk mencoba secara langsung hal-hal yang dijabarkan dalam pembahasan kali ini. File BelajarVBA004.xlsm bisa diunduh disini. Pembahasan kali ini adalah seri pertama dari tiga seri pembahasan tentang prosedur.



Jenis Prosedur

Prosedur di dalam VBA ada 3 (tiga) jenis, yaitu :

Sub

Prosedur yang berisi proses kerja tanpa memberikan nilai balik hasil kerja. Jadi nama prosedur tidak menyimpan nilai apapun. Prosedur jenis sub yang dideklarasikan dengan keyword Public dan tanpa parameter input apapun dapat dijalankan melalui workbook window sebagai sesuatu yang sering disebut Macro.
Misalkan pada general module bernama mod02 diberi prosedur berikut ini :
   Public Sub LuasPakaiSub()
     Dim lPanjang As Long, lLebar As Long, lLuas As Long
     lPanjang = 5
     lLebar = 8
     lLuas = lPanjang * lLebar
   End Sub

Ketika prosedur sub bernama LuasPakaiSub dijalankan, maka variabel lPanjang akan diisi nilai 5, lLebar diisi nilai 8, dan Luas akan dihitung sebagai lPanjang * lLebar yang menghasilkan 5 * 8 = 40 yang disimpan dalam variabel lLuas. Nilai 40 ini tidak dapat disimpan dalam nama prosedur sub. Jadi prosedur sub tidak menghasilkan apapun selain sebuah kerja dan berlalu begitu saja setelah selesai kerja.
Proses untuk menjalankannya sebagai Macro adalah pada
     ribbon Developer -> group Code -> Macro
atau dengan menekan tombol ALT F8 bersamaan, yang dilanjutkan dengan memilih nama prosedur sub yang akan dijalankan dan diikuti menekan tombol Run yang ada dalam dialog window Macro yang ada.

Function

Prosedur yang berisi proses kerja yang menghasilkan suatu nilai balik hasil kerja. Nilai balik hasil kerja disimpan dalam nama prosedur. Prosedur function yang dideklarasikan dengan keyword Public dapat digunakan dalam cell seperti fungsi bawaan Excel.
Misalkan pada general module bernama mod02 diberi prosedur berikut ini :
   Public Function LuasPakaiFunction() As Long
     Dim lPanjang As Long, lLebar As Long
     lPanjang = 5
     lLebar = 8
     LuasPakaiFunction = lPanjang * lLebar
   End Function

Prosedur function menggunakan keyword Function dan disertai pernyataan As datatype tertentu seperti As Long. Pada prosedur sub menggunakan keyword Sub dan tidak ada penambahan apapun diakhir deklarasi.
Ketika prosedur function bernama LuasPakaiFunction dijalankan, maka variabel lPanjang akan diisi nilai 5, lLebar diisi nilai 8, dan Luas akan dihitung sebagai lPanjang * lLebar yang menghasilkan 5 * 8 = 40 yang disimpan dalam nama prosedur function, yaitu LuasPakaiFunction. Jadi nama prosedur function, yaitu LuasPakaiFunction akan berisi nilai 40. Jika hasil proses yang disimpan oleh nama prosedur function tersebut tidak segera disimpan ke sebuah variabel oleh kode program yang menjalankannya, maka nilai tersebut akan segera hilang.
Pemanggilan kembali LuasPakaiFunction akan berarti melakukan proses yang baru dan bukan mengambil nilai yang disimpan saat menjalankan prosedur tersebut sebelumnya. Oleh sebab itu, maka pemanggilan prosedur function sering digunakan sebagai salah satu sarana untuk mengisi nilai suatu variabel disebuah proses yang sedang dijalankan pada prosedur lain. Misalkan di general module mod03 diberi prosedur sub yang membutuhkan hasil kerja prosedur function di atas sebagai berikut :
   Public Sub ButuhHasilFunction()
     Dim lLuas As Long
     lLuas = LuasPakaiFunction
   End Sub

Ketika prosedur sub bernama ButuhHasilFunction, maka variabel lLuas akan diisi oleh hasil proses di dalam prosedur function bernama LuasPakaiFunction. Dalam hal ini, nilai yang disimpan oleh variabel lLuas akan bernilai 40 karena hasil kerja prosedur function bernama LuasPakaiFunction menghasilkan nilai 40.
Jika prosedur function akan digunakan layaknya sebuah prosedur Sub, maka pemanggilannya adalah dengan menggunakan keyword Call, seperti Call LuasPakaiFunction. Nilai balik dari function tidak akan disimpan.
Prosedur function bernama LuasPakaiFunction juga dapat digunakan dalam cell karena deklarasi prosedur LuasPakaiFunction adalah menggunakan keyword Public. Misalkan saat berada dalam workbook window pada sheet Kerja dan di cell B5 diberi formula berbunyi :
     =LuasPakaiFunction()
Maka di cell B5 akan muncul hasil kerja fungsi LuasPakaiFunction yang berupa prosedur function bernama LuasPakaiFunction. Dalam hal ini, akan muncul nilai 40.

Property

Prosedur yang digunakan untuk mengisi nilai ke sebuah variabel atau mengambil nilai dari sebuah variabel. Umumnya jenis prosedur property digunakan secara intensif ketika membentuk sebuah custom class dalam Class Module. Jadi, pada dasarnya, prosedur jenis ini bisa digunakan dimana saja seperti halnya prosedur jenis Sub maupun Function.
Prosedur property terdiri dari :
  • Let : untuk memasukkan nilai kedalam variabel selain object dan kerjanya mirip dengan penggunaan jenis Sub
  • Set : untuk memasukkan nilai kedalam variabel object dan kerjanya mirip dengan penggunaan jenis sub
  • Get : untuk mengambil nilai dari suatu variabel dan kerjanya mirip dengan jenis Function
Pembahasan tentang property akan dilanjutkan setelah memahami Sub dan Function lebih detil.


Deklarasi Prosedur

Sebuah contoh deklarasi prosedur sub yang diletakkan pada sebuah general module (misal di mod04) adalah sebagai berikut :
   Public Sub DataMember _
               ( _
                    sNama As String _
                   ,ByVal lUmur As Long _
                   ,lAnak As Long _
                   ,ByRef sAlamat As String _
                   ,Optional ByVal sTelp As String _
                   ,Optional ByRef sEmail As String _
                   ,Optional bMember As Boolean =TRUE _
               )
     'kode program disini
   End Sub

Argumen

Setiap bentuk yang seperti suatu deklarasi variabel, misal sNama As String, disebut sebuah argumen. Prosedur bisa berisi banyak argumen. Contoh di atas berisi 7 argumen. Argumen terdiri dari nama argumen (misal sNama) dan datatype argumen (misal As String). Nama argumen bekerja layaknya variabel didalam prosedur tersebut (scope level local). Argumen adalah sesuatu yang harus disediakan oleh prosedur lain yang bermaksud memanggil prosedur berargumen ini, yang berupa sebuah nilai input parameter. Jadi, prosedur lain yang akan menggunakan prosedur DataMember di atas harus menyediakan nilai bagi setiap argumen yang harus dipenuhi.

Keyword Optional

Keyword Optional digunakan untuk menyatakan bahwa argumen tersebut boleh tidak disediakan nilainya. Penggunaan keyword Optional bisa disertai dengan penetapan nilai default bagi argumen tersebut ketika tidak disediakan nilainya ooeh prosedur pemanggil, seperti =TRUE pada Optional bMember As Boolean =TRUE. Setiap argumen dengan keyword optional dikumpulkan dan diletakkan pada bagian akhir daftar argumen, seperti jejeran argumen yang menggunakan keyword optional pada contoh diatas. Pada contoh di atas, bila argumen bMember tidak diberi nilai oleh prosedur pemanggil, maka akan diisi oleh nilai default menurut baris deklarasi tersebut, yaitu bernilai TRUE.

Keyword ByVal dan ByRef

Keyword ByVal dan ByRef adalah penunjuk cara penggunaan sesuatu yang diserahkan oleh prosedur pemanggil kepada prosedur berargumen yang dipanggil. ByRef adalah sebagai default, sehingga sNama As String dapat ditulis sebagai ByRef sNama As String.
Keyword ByVal berarti argumen akan diisi dengan salinan data. Prosedur berargumen di atas hanya akan mengubah salinan nilai dan nilai asli tidak akan berubah sama sekali. Contohnya adalah lUmur. Prosedur pemanggil memberikan nilai 17 untuk argumen lUmur milik prosedur DataMember. Proses dalam prosedur DataMember mengubah isi lUmur dari 17 menjadi 23. Maka prosedur pemanggil, yaitu yang menyerahkan nilai 17 kepada argumen lUmur milik prosedur DataMember, tetap berisi nilai 17.
Keyword ByRef berarti argumen akan diisi dengan wujud data tersebut secara langsung. Contohnya adalah sAlamat. Prosedur pemanggil memberikan nilai 'Batam' untuk sAlamat milik prosedur DataMember. Proses dalam prosedur DataMember mengubah isi nilai 'Batam' menjadi 'Jakarta'. Maka prosedur pemanggil, yaitu yang menyerahkan nilai 'Batam' kepada argumen sAlamat milik prosedur DataMember, akan mendapati bahwa isi dirinya telah berubah menjadi 'Jakarta'.

Cara memanggil prosedur berargumen

Prosedur yang memiliki argumen harus disediakan nilai data setiap argumen utamanya (tanpa Optional) agar bersedia bekerja. Misalkan akan memanggil prosedur sub berargumen seperti prosedur DataMember yang diletakkan pada general module bernama mod04 yang menjadi contoh di atas tadi. Pada general module bernama mod03 bisa diberi prosedur pemanggil seperti prosedur berikut ini :
   Public Sub PanggilBerargumen1()
     'diisi nilai konstan secara langsung untuk semua argumen
     DataMember "Kid", 17, 0, "Jakarta", _
                "021-12345678", "mr.nmkid@gmail.com", True
   End Sub

Nilai 'Kid' yang berdatatype String akan mengisi argumen sNama. Nilai 17 dan 0 yang berdatatype Long akan secara berurutan mengisi argumen lUmur dan lAnak. Nilai 'Jakarta' akan mengisi argumen sAlamat. Sedangkan nilai berdatatype string '021-12345678' dan 'mr.nmkid@gmail.com' akan mengisi argumen sTelp dan sEmail yang bersifat optional (bila ada atau bila dibutuhkan) secara berurutan. Nilai Boolean TRUE akan mengisi argumen bMember yang juga bersifat optional.
Saat mengetikkan spasi setelah nama prosedur DataMember, akan muncul tooltip info tentang nama prosedur beserta argumen yang dibutuhkan seperti gambar berikut ini :
Pada gambar tersebut tampak nama prosedur, yaitu DataMember, yang memiliki banyak argumen, mulai dari sNama yang harus dipenuhi sampai dengan bMember yang bersifat optional (bila ada atau bila dibutuhkan).
Tooltip info muncul karena item Auto Quick Info tercentang. Item ini dapat ditemukan pada Options (menu Tools -> Options) di tab Editor bagian Code Settings.

Cara memanggil prosedur DataMember dengan menggunakan keyword Call akan berbentuk seperti prosedur berikut :
   Public Sub PanggilBerargumen2()
     'diisi nilai konstan secara langsung untuk semua argumen
     'dengan menggunakan keyword Call
     Call DataMember("Kid", 17, 0, "Jakarta", _
                "021-12345678", "mr.nmkid@gmail.com", True)
   End Sub

Pengisian argumen pada prosedur PanggilBerargumen2 tetap berurutan seperti pada prosedur PanggilBerargumen1. Perbedaan cara pemanggilan prosedur DataMember antara yang menggunakan keyword Call (dalam PanggilBerargumen2) dengan yang tidak menggunakan keyword Call (dalam PanggilBerargumen1) adalah keberadaan keyword Call dan penggunaan tanda kurung. Pada pemanggilan dengan keyword Call dibutuhkan adanya tanda kurung yang melingkupi seluruh nilai argumen yang akan diserahkan ke prosedur yang dipanggil, yang dalam hal ini adalah prosedur DataMember.
Pada contoh pemanggilan di atas, argumen bMember diisi dengan nilai TRUE. Pada deklarasi prosedur DataMember, argumen bMember bersifat optional dan dinyatakan bahwa nilai default-nya adalah TRUE. Maka pemanggilan prosedur DataMember untuk nilai bMember yang juga bernilai TRUE dapat dikosongkan seperti prosedur PanggilBerargumen3 berikut :
   Public Sub PanggilBerargumen3()
     'diisi nilai konstan secara langsung
     'untuk bMember yang akan diisi TRUE
     'yang sesuai nilai default bMember

     DataMember "Kid", 17, 0, "Jakarta", _
                "021-12345678", "mr.nmkid@gmail.com"
   
     'diisi nilai konstan secara langsung
     'dengan menggunakan keyword Call
     'untuk bMember yang akan diisi TRUE
     'yang sesuai nilai default bMember

     Call DataMember("Kid", 17, 0, "Jakarta", _
                "021-12345678", "mr.nmkid@gmail.com")
   End Sub

Jadi, nilai TRUE tidak perlu ditulis dalam pemanggilannya. Pada contoh di atas, bMember ada dibagian akhir deklarasi. Argumen yang bersifat optional lainnya, seperti sTelp, tidak ditentukan nilai default-nya. Maka nilai default dari argumen sTelp adalah nilai default dari datatype yang digunakan oleh sTelp. Karena sTelp menggunakan datatype String, maka nilai default-nya adalah NULLSTRING atau teks kosong.
Jika argumen sTelp yang bersifat optional tidak ingin diisi sesuatu atau ingin menggunakan nilai default dari argumen sTelp, maka pemanggilan prosedur DataMember akan menjadi seperti dalam prosedur PanggilBerargumen4 berikut ini :
   Public Sub PanggilBerargumen4()
     'diisi nilai konstan secara langsung
     'untuk bMember yang akan diisi TRUE
     'yang sesuai nilai default bMember
     'dan argumen sTelp akan diisi sesuai defaultnya

     DataMember "Kid", 17, 0, "Jakarta", , "mr.nmkid@gmail.com"
   
     'diisi nilai konstan secara langsung
     'dengan menggunakan keyword Call
     'untuk bMember yang akan diisi TRUE
     'yang sesuai nilai default bMember
     'dan argumen sTelp akan diisi sesuai defaultnya

     Call DataMember("Kid", 17, 0, "Jakarta", , "mr.nmkid@gmail.com")
   End Sub

Kehadiran sebuah item kosong antara nilai untuk argumen sAlamat (yang bernilai 'Jakarta') dengan nilai untuk argumen sEmail (yang bernilai 'mr.nmkid@gmail.com') menunjukkan bahwa argumen sTelp tidak disediakan nilainya oleh prosedur PanggilBerargumen4 yang menjadi prosedur pemanggil prosedur DataMember. Pemanggilan seperti di atas, baik dengan atau tanpa keyword Call, akan membuat argumen sTelp diisi dengan NULLSTRING yang menjadi nilai default.

Nama argumen dari prosedur yang dipanggil juga bisa dituliskan agar lebih mudah pembacaan kode programnya dilain waktu. Misal, cara pemanggilan prosedur PanggilBerargumen1 akan menyertakan nama-nama argumennya, maka akan seperti prosedur PanggilBerargumen5 berikut ini :
   Public Sub PanggilBerargumen5()
     'diisi nilai konstan secara langsung untuk semua argumen
     DataMember _
        sNama:="Kid" _
        , lUmur:=17 _
        , lAnak:=0 _
        , sAlamat:="Jakarta" _
        , sTelp:="021-12345678" _
        , sEmail:="mr.nmkid@gmail.com" _
        , bMember:=True
   End Sub

Pada contoh prosedur bernama PanggilBerargumen5 tampak bahwa nama argumen selalu diikuti dengan karakter titik dua dan sama dengan ( := ). Ketika ada nama argumen yang disertakan dalam pemanggilan, maka seluruh argumen setelah nama argumen pertama yang tertulis juga harus dituliskan. Pada contoh di atas, dikarenakan argumen sNama ditulis nama argumennya, yaitu berbunyi sNama:=, maka seluruh argumen setelah sNama harus menyertakan nama argumennya.
Jika argumen sNama dan lUmur tidak menyertakan nama argumennya, tetapi argumen lAnak menyertakan argumennya, maka argumen sAlamat sampai dengan bMember harus menyertakan nama argumennya jika akan diset nilainya. Contohnya seperti prosedur PanggilBerargumen6 berikut ini :
   Public Sub PanggilBerargumen6()
     'diisi nilai konstan secara langsung untuk semua argumen
     'Argumen sNama dan lUmur tidak menyertakan nama argumen
     'Argumen lAnak menyertakan nama argumen,
     'maka argumen sAlamat sampai bMember
     'harus menyertakan nama argumen

     DataMember "Kid", 17 _
        , lAnak:=0 _
        , sAlamat:="Jakarta" _
        , sTelp:="021-12345678" _
        , sEmail:="mr.nmkid@gmail.com" _
        , bMember:=True
   End Sub


Penyertaan nama argumen akan terasa manfaatnya ketika berhubungan dengan argumen-argumen yang bersifat optional yang tidak seluruhnya akan diisi nilai. Pada contoh prosedur DataMember, penyertaan argumen akan terasa ketika akan mengisi argumen sTelp sampai bMember. Misalkan saja seperti pemanggilan prosedur DataMember seperti contoh prosedur PanggilBerargumen4 yang hanya akan mengisi argumen bersifat optional bernama sEmail saja. Ketika menyertakan nama argumen, maka prosedur PanggilBerargumen4 bisa diubah seperti prosedur PanggilBerargumen7 berikut ini :
   Public Sub PanggilBerargumen7()
     'argumen optional yang diisi hanya sEmail saja
     DataMember "Kid", 17, 0, "Jakarta" _
            , sEmail:="mr.nmkid@gmail.com"

     'argumen optional yang diisi hanya sEmail saja
     'dengan keyword Call

     Call DataMember("Kid", 17, 0, "Jakarta" _
            , sEmail:="mr.nmkid@gmail.com")
   End Sub

Pada prosedur PanggilBerargumen7 tampak bahwa argumen sNama sampai dengan argumen sAlamat yang harus dipenuhi (bukan bersifat optional) ditulis tanpa menyertakan nama argumen. Sedangkan pada satu-satunya argumen bersifat optional yang akan diisi, yaitu argumen bernama sEmail, disertai dengan nama argumennya. Dengan cara ini, maka tidak diperlukan adanya ruang kosong antara nilai 'Jakarta' (untuk argumen sAlamat) dengan nilai 'mr.nmkid@gmail.com' (untuk argumen optional sEmail).
Hal ini akan terasa manfaatnya ketika jumlah argumen optionalnya sangat banyak seperti contohnya pada pemanggilan prosedur sub Sort yang menjadi sebuah methods (kemampuan kerja) dari object range. Prosedur Sort memiliki banyak sekali argumen. Pada prosedur Sort, seluruh argumen bersifat Optional. Misalkan akan melakukan sort terhadap area A1:C5 yang memiliki header pada area A1:C1 berdasar kolom B secara Ascending. Kegiatan ini akan memerlukan nilai input parameter untuk argumen berupa :
  • kolom kunci sort, yaitu kolom B yang diwakili oleh Range("b1") sebagai pengisi argumen Key1
  • cara mengurutkan secara Ascending yang menjadi nilai default dari argumen Order1, sehingga bisa dikosongkan saja
  • informasi tentang keberadaan header untuk argumen bernama Header yang memiliki nilai default xlNo, yang akan diisi dengan nilai xlYes karena area A1:C5 memiliki header di area A1:C1.
Contoh prosedur untuk proses ini akan seperti gambar berikut :
Dari gambar di atas tampak bahwa prosedur sort memiliki argumen dari Key1 sampai dengan DataOption3 yang bersifat optional dan beberapa diantara argumen tersebut telah ditetapkan nilai defaultnya. Untuk proses sort pada kasus ini cukup mengisi argumen Key1 dan argumen Header saja. Argumen Order1 diabaikan karena nilai defaultnya sudah sesuai dengan kebutuhan, yaitu secara Ascending. Argumen Key2 sampai dengan Order3 diabaikan karena tidak dibutuhkan. Begitu juga dengan argumen OrderCustom sampai dengan DataOption3 yang diabaikan karena tidak dibutuhkan.
Penyertaan nama argumen bisa memberi banyak manfaat, antara lain adalah :
  • Kemudahan untuk tetap fokus pada penyediaan nilai-nilai argumen yang dibutuhkan saja
  • Meringkaskan baris kode program, terutama pada kasus-kasus yang berinteraksi dengan prosedur yang memiliki banyak argumen bersifat optional
  • Kemudahan dalam membaca kode program dilain waktu oleh programmer lain

Dari uraian di atas semestinya sudah bisa mulai terbayang tentang adanya potensi untuk membuat sebuah proses dalam sebuah prosedur atau serangkaian prosedur yang bisa digunakan berulang-ulang oleh banyak prosedur kerja. Contohnya seperti prosedur sort yang bisa digunakan oleh banyak kegiatan sort tanpa harus selalu menulis algoritma proses perulangan (loop) untuk mengurutkan data.

Insya Allah pembahasan prosedur pada seri kedua adalah tentang ByRef dan ByVal serta pemanfaatan scope untuk membuat sebuah rangkaian proses lebih bersifat modular. Pemahaman tentang scope, variabel, dan prosedur berargumen akan lebih intensif dibahas dan digunakan.


7 komentar:

  1. Pertamax Kembali diamankan !

    BalasHapus
  2. Buka comment tapi mau nanya mr. Kid, apakah keberadaan argumen bisa digantikan dengan deklarasi variabel?

    BalasHapus
    Balasan
    1. :)

      Argumen dalam deklarasi prosedur ditulis seperti deklarasi variabel tanpa menyertakan scope. Penulisan argumen tersebut bisa disertai statement lain seperti ByVal atau ByRef atau Optional, sedang deklarasi variabel tidak ada.
      Scope dari sebuah argumen adalah lokal pada prosedur tersebut. Artinya, seakan-akan setara dengan variabel yang dideklarasikan dengan Dim dalam prosedur tersebut. Jadi argumen bisa menghasilkan sebuah variabel ber-scope lokal dalam prosedur yang bisa menerima nilai dari luar prosedur.

      Beberapa kegunaan argumen bisa digantikan oleh variabel yang dideklarasikan ber-scope module ke atas. Sayangnya, variabel yang dideklarasikan ber-scope module ke atas tidak hilang ketika sebuah prosedur selesai di proses. Salah satu kegunaan argumen adalah memudahkan proses recursive. Proses recursive adalah proses yang dilakukan oleh sebuah prosedur yang didalamnya ada sebuah baris yang memanggil dirinya sendiri untuk memproses suatu nilai baru hasil proses dirinya yang sebelumnya.

      Moga-moga celotehan diatas ndak membuat bingung.

      Hapus
  3. mau nanya Mr.Kid agak nyimpang dikit ga apa-apa tapi ya..
    misal di sebuah workbook dengan nama "asek-asek" pada ribbon tab saya kasih tab baru dengan nama Tab1>group1>button1, nah yang saya inginkan jika button1 tersbut saya klik makan akan keluar jendela browser dengan alamat http://b-excel.blogspot.com
    kira-kira seperti apa scriptnya untuk si button1 tersebut jika saya punya script vba macro sbb?
    Option Explicit
    Private pWebAddress As String
    Public Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, _
    ByVal lpOperation As String, ByVal lpFile As String, _
    ByVal lpParameters As String, ByVal lpDirectory As String, _
    ByVal nShowCmd As Long) As Long

    Public Sub NewShell(cmdLine As String, lngWindowHndl As Long)
    ShellExecute lngWindowHndl, "open", cmdLine, "", "", 1
    End Sub

    Public Sub WebPage()
    pWebAddress = "http://b-excel.blogspot.com"
    Call NewShell(pWebAddress, 3)
    End Sub

    saya udah coba pakai Ribbon designer tapi tidak jadi.

    BalasHapus
    Balasan
    1. Jalan-jalan kesini :
      https://groups.yahoo.com/neo/groups/belajar-excel/conversations/messages/31569

      Hapus
  4. haya bisa kagum tanpa bisa mengerti, coba ada penjelasan video beserta contaoh filenya..
    mungkin bisa dikit ngudeng..

    BalasHapus
    Balasan
    1. hehehe...

      oh jadi butuh video berisi bacaan di atas yang disuarakan ya... moga-moga kelak ada waktu untuk membuat rekaman suaranya ya...

      contoh file yang bisa digunakan untuk praktek sendiri (alias bahan file mentah sebagai lahan ujicoba sendiri) sudah disediakan melalui link unduh yang ada dalam bacaan. Silakan unduh file tersebut.

      Contoh file jadinya, ada di seri selanjutnya sebelum memulai pembahasan seri selanjutnya tersebut. Beberapa seri malah sudah disertakan melalui link yang ada sebelum berpindah ke seri selanjutnya.

      Jadi, contoh file untuk bahan praktek seri tersebut ada dalam link unduh sebelum materi seri tersebut.
      Contoh file jadinya ada di link unduh seri berikutnya atau dibeberapa seri ada di link unduh sebelum berpindah ke seri berikutnya.

      Wassalam,
      Kid.

      Hapus