BelajarVBA 003 - Scope seri 2

Coretan Mr. Kid
Perubahan yang besar diawali oleh setitik kebaikan penuh keikhlasan dan kebaikan yang setitik itu sering dianggap sepele kecuali bagi yang berpikir

Pembahasan tentang scope seri 2 ini adalah lanjutan dari seri 1. Bahasan adalah tentang keyword Public dan Friend serta cara sederhana dalam menata scope.


Public

Scope level project

Keyword Public dapat digunakan untuk deklarasi variabel ataupun prosedur. Deklarasi dengan Public akan memiliki scope level Project ketika dilihat dari sudut pandang bahwa VBAProject tersebut tidak membutuhkan kemampuan VBAProject lain. Pembahasan kita awali dengan menggunakan sudut pandang ini terlebih dulu.

File BelajarVBA001.xlsm akan kita gunakan untuk memudahkan dalam memahaminya keyword Public ini. Buka file BelajarVBA001.xlsm dan tambahkan (Insert) 2 buah Code Module, sehingga pada folder Modules akan ada Module4 dan Module5. Contoh penggunaan keyword Public adalah sebagai berikut :
  • Aktifkan Module4 dan tulis script berikut, dimulai dari area general declaration :
     'variabel dengan keyword Public
     Public dtTglBelajar As Date

     'prosedur dengan keyword Public
     Public Sub TentangPublic()
         'lihat isi variabel dtTglBelajar
         MsgBox "Nilai awal dtTglBelajar adalah " & dtTglBelajar
   
         'isi variabel dtTglBelajar dengan tanggal
         '22 Juni 2013 (Kopdar#1 BeExcel)
         dtTglBelajar = "2013-06-22"
   
         'lihat isi variabel dtTglBelajar
         MsgBox "Nilai sekarang dtTglBelajar adalah " & dtTglBelajar
     End Sub

  • Saat ini, variabel dtTglBelajar dan prosedur TentangPublic akan memiliki scope level Project. Keduanya bisa digunakan dimana saja didalam VBAProject secara langsung dan secara lugas. Prosedur TentangPublic adalah contoh prosedur Public yang ada dimodule yang sama dengan variabel dtTglBelajar. Prosedur TentangPublic dapat dijalankan tanpa error.
  • Sekarang, kita buat prosedur di Module5 yang berisi kode program untuk menjalankan prosedur TentangPublic dan pemakaian variabel dtTglBelajar yang ada di Module4. Prosedur yang ditulis di Module5 tersebut adalah :
     Public Sub PanggilTentangPublicModule4()
         'jalankan prosedur tentangpublic yang ada di Module4
         TentangPublic
   
         'isi variabel dtTglBelajar yang ada di Module4
         'dengan nilai tanggal hari ini
         dtTglBelajar = Date
   
         'tampilkan pesan nilai dtTglBelajar
         MsgBox "Nilai baru dtTglBelajar adalah " & dtTglBelajar
   
         'isi variabel dtTglBelajar yang ada di Module4
         'dengan nilai tanggal dan waktu saat ini
         dtTglBelajar = Now
   
         'tampilkan pesan nilai dtTglBelajar
         MsgBox "Nilai baru dtTglBelajar " & _
             "disertai waktu adalah " & dtTglBelajar
     End Sub

  • Prosedur Public bernama PanggilTentangPublicModule4 memiliki scope level project. Isi prosedur ini adalah kode-kode program yang membentuk suatu proses untuk menggunakan variabel dan prosedur public yang ada di Module4.

Scope level project dalam object module

Object module memiliki sifat tertutup yang sering disebut sebagai private module. Seluruh variabel dan prosedur yang ber-scope level Project atau yang menggunakan keyword Public di dalam private module, seperti dalam object module, tetap bisa digunakan dengan memanggil nama modulenya terlebih dulu. Contohnya seperti berikut ini :
  • Aktifkan object module bernama ThisWorkbook
  • Tulis script berikut ini, dimulai dari area general declaration :
     'variabel public dalam object module
     Public curOrder As Currency

     'prosedur public dalam object module
     Public Sub IsiOrder()
         curOrder = 1234567890
     End Sub

  • Variabel curOrder dan prosedur IsiOrder yang ada didalam module ThisWorkbook bisa digunakan oleh seluruh variabel atau prosedur yang ada dalam VBAProject tersebut, meskipun sifat object module bernama ThisWorkbook adalah sebagai private module.
  • Prosedur IsiOrder yang berisi kode untuk mengisi nilai ke dalam variabel curOrder dapat dijalankan dengan baik secara langsung dan secara lugas. Hal ini disebabkan karena prosedur IsiOrder dan variabel curOrder tinggal bersama-sama didalam module ThisWorkbook.
Prosedur yang ada diluar module ThisWorkbook bisa menggunakan prosedur IsiOrder atau variabel curOrder secara langsung, tetapi tidak secara lugas seperti prosedur yang ada didalam object module ThisWorkbook. Cara menggunakan prosedur IsiOrder atau variabel curOrder dalah dengan menyebut nama object modulenya terlebih dulu.
Contoh penggunaan prosedur atau variabel public yang ada di dalam sebuah object module adalah sebagai berikut :
  • Aktifkan Module5 dan buat prosedur berikut :
     Public Sub PanggilIsiOrderThisWorkbook()
         'lihat isi variabel curOrder yang ada di module ThisWorkbook
         MsgBox "Nilai Order awal adalah " & ThisWorkbook.curOrder
   
         'jalankan prosedur IsiOrder yang ada di module ThisWorkbook
         ThisWorkbook.IsiOrder
   
         'lihat isi variabel curOrder yang ada di module ThisWorkbook
         MsgBox "Nilai Order baru adalah " & ThisWorkbook.curOrder
   
         'isi nilai baru ke dalam variabel curOrder
         'yang ada di module ThisWorkbook
         ThisWorkbook.curOrder = 17
   
         'lihat isi variabel curOrder yang ada di module ThisWorkbook
         MsgBox "Nilai Order baru adalah " & ThisWorkbook.curOrder
     End Sub

  • Prosedur bernama PanggilIsiOrderThisWorkbook, yang ada di Module5, menggunakan variabel atau prosedur public yang ada dalam object module ThisWorkbook dengan cara memanggil nama object module-nya terlebih dulu. Variabel curOrder digunakan dengan cara ThisWorkbook.curOrder dan prosedur IsiOrder dijalankan dengan cara ThisWorkbook.IsiOrder.

Scope level global

Deklarasi dengan Public akan memiliki scope level Global ketika VBAProject tersebut membutuhkan kemampuan VBAProject lain. Makna scope level global didalam Excel VBA tidak sama seutuhnya dengan pengertian scope global pada bahasa pemrograman lain. Scope level global di dalam Excel VBA memiliki banyak syarat, antara lain adalah :
  1. VBAProject yang dibutuhkan harus terdaftar sebagai referensi
  2. Workbook tempat VBAProject yang dibutuhkan harus terbuka
  3. Workbook tempat VBAProjoct yang dibutuhkan tidak dapat ditutup selama VBAProject yang membutuhkan masih terbuka
Untuk memahami hal ini, mari kita siapkan media belajarnya. Ikuti langkah berikut :
  • Mengubah nama VBAProject milik BelajarVBA001.xlsm menjadi VBP_Belajar001 dengan cara :
  1. klik kanan nama projectnya (VBAProject) di Project Explorer
  2. pilih VBAProject Properties
  3. muncul dialog window Project Properties
  4. ganti nama project menjadi VBP_Belajar001
  5. tekan OK
  • Insert 2 buah code module, sehingga terbentuk 2 buah module baru bernama Module6 dan Module7
  • Ganti nilai properti (Name) object Sheet1 dengan shtBelajar1, dan nilai properti Name menjadi Belajar_1
  1. klik Sheet1 di Project Explorer
  2. lihat Properties Window
  3. ganti seperti gambar berikut :
  • Ke Workbook window (tekan ALT F11) dan simpan workbook BelajarVBA001.xlsm
  • VBP_Belajar001 akan tampak seperti gambar berikut :
  • Buat workbook baru (tekan ALT F N)
  • Hapus semua sheet kecuali Sheet1
  • Simpan workbook di folder BelajarVBA dengan nama file BelajarVBA002.xlsm dan Save as type sebagai Excel Macro-Enabled Workbook (.xlsm)
  • ke VBE (tekan ALT F11)
  • Ubah nama VBAProject milik BelajarVBA002.xlsm menjadi VBP_Belajar002
  • Insert 1 buah code module pada VBP_Belajar002
  • Ganti nilai properti (Name) milik Module1 di VBP_Belajar002 menjadi mod002
  • VBP_Belajar002 akan tampak seperti gambar berikut :


  • Menjadikan VBP_Belajar1 sebagai salah satu referensi bagi VBP_Belajar002
  1. klik VBP_Belajar002 -> menu Tools -> References
  2. centang VBP_Belajar001 -> tekan OK

  • Simpan workbook BelajarVBA002.xlsm
  • VBP_Belajar002 akan tampak menjadi seperti gambar berikut :

Sampai disini, VBP_Belajar002 membutuhkan VBP_Belajar001. Workbook BelajarVBA001.xlsm tidak dapat ditutup selama workbook BelajarVBA002.xlsm masih terbuka. Jika membuka workbook BelajarVBA002.xlsm, maka workbook BelajarVBA001.xlsm akan ikut terbuka.

Pada dasarnya, pada kondisi ini, seluruh variabel ataupun prosedur di dalam VBP_Belajar001 dapat diakses oleh VBP_Belajar002. Hal inilah yang disebut scope level global dalam Excel VBA. Scope level global dalam Excel VBA tidak utuh sama dengan pengertian scope global pada bahasa pemrograman lain karena VBP_Belajar001 tidak dapat mengakses apapun dari VBP_Belajar002, karena untuk bisa mengakses VBAProject lain membutuhkan proses penambahan referensi. VBP_Belajar001 tidak dapat menambahkan VBP_Belajar002 sebagai referensi karena VBP_Belajar001 sudah menjadi referensi bagi VBP_Belajar002.

Kita akan mencoba untuk memahami apa maksud sudut pandang tentang keyword Public bisa menghasilkan scope level global.

Tahap 1. Mengakses Module6 di VBP_Belajar001
  • Aktifkan Module6 di VBP_Belajar001 dan isi dengan script berikut :
     Public sVarPublicDiMod6 As String

     Public Sub ProcPublicDiMod6()
         MsgBox "Pesan dari prosedur public di Module6 " & _
                 "yang ada di VBP_Belajar001"
     End Sub

  • Variabel dan prosedur dengan keyword public tersebut pasti bisa diakses oleh seluruh prosedur di VBP_Belajar001 karena menggunakan keyword Public.
  • Aktifkan mod002 di VBP_Belajar002 dan tulis prosedur berikut :
     Public Sub PenggunaVBP_Belajar001_Module6()
         'mengisi variabel yang ada di Module6 VBP_Belajar001
         VBP_Belajar001.sVarPublicDiMod6 = "Tahap 1"
   
         'menjalankan prosedur yang ada di Module6 VBP_Belajar001
         VBP_Belajar001.ProcPublicDiMod6
     End Sub

  • Prosedur PenggunaVBP_Belajar001_Module6 yang ada di VBP_Belajar002 pada module mod002 dapat berjalan dengan baik. Hal inilah yang menjadi salah satu alasan untuk menggolongkan keyword Public bisa menghasilkan scope level global. Seluruh variabel atau prosedur dengan keyword public yang ada di Module6 pada VBP_Belajar001 bisa diakses secara langsung oleh module mod002 yang ada di VBP_Belajar002, layaknya mod002 ada di dalam VBP_Belajar001.

Tahap 2. Mengakses object module shtBelajar1 di VBP_Belajar001
  • Aktifkan shtBelajar1 di VBP_Belajar001 dan isi dengan script berikut :
     Public Sub ProcPublicDiSheet()
         MsgBox "Pesan dari prosedur public di sheet shtBelajar1 " & _
                 "yang ada di VBP_Belajar001"
     End Sub

  • Object module memiliki sifat yang tertutup sebagai sebuah private module. Module shtBelajar1 yang ada di VBP_Belajar001 termasuk jenis object module.
  • Aktifkan mod002 di VBP_Belajar002 dan tulis prosedur berikut :
     Public Sub PenggunaVBP_Belajar001_Sheet()
         'menjalankan prosedur yang ada di sheet shtBelajar1 VBP_Belajar001
         VBP_Belajar001.shtBelajar1.ProcPublicDiSheet
     End Sub

  • Prosedur PenggunaVBP_Belajar001_Sheet dapat dijalankan dengan baik. Karena shtBelajar1 termasuk object module, maka cara mengakses prosedur yang ada harus didahului dengan nama object module-nya.
  • Meskipun shtBelajar1 termasuk object module yang termasuk private module, tetapi bukan berarti object module dari Microsoft Excel Objects tidak bisa diakses secara global.

Tahap 3. Mengakses object module UserForm1 di VBP_Belajar001
  • Aktifkan code window UserForm1 yang ada di VBP_Belajar001 dengan cara klik kanan lalu pilih View Code.
  • Tulis script berikut :
     Public Sub ProcPublicDiUserForm1()
         MsgBox "Pesan dari prosedur public di UserForm1 " & _
                 "yang ada di VBP_Belajar001"
     End Sub

  • Object module UserForm1 yang ada di VBP_Belajar001 termasuk object module yang benar-benar sebagai private module. Jika prosedur ini dijalankan, maka akan menghasilkan error akibat tidak dikenalnya member bernama UserForm1 dalam VBP_Belajar001. Padahal prosedur atau variabel yang dideklarasikan menggunakan keyword public dalam UserForm1 di VBP_Belajar001 bisa digunakan oleh module lain yang ada di VBP_Belajar001.

Tahap 4. Membuat code module menjadi private module
Code module pada dasarnya adalah public module. Oleh sebab itu seluruh variabel atau prosedur yang dideklarasikan dengan keyword public akan dapat diakses secara langsung.
Code module bisa diubah menjadi sebuah private module yang karakteristiknya seperti object module UserForm1 alias private module yang sama sekali tidak dapat diakses secara global. Untuk mengubah code module menjadi private module adalah dengan menambahkan Option Private Module pada baris-baris awal area general declaration.
  • Aktifkan Module7 di VBP_Belajar001
  • Dibawah baris berbunyi Option Explicit, tambahkan baris berikut :
     Option Private Module
  • Kemudian tulis juga prosedur contoh berikut ini :
     Public Sub ProcPublicDiMod7()
         MsgBox "Pesan dari prosedur public di Module7 " & _
                 "yang ada di VBP_Belajar001"
     End Sub

  • Dengan kehadiran baris Option Private Module, maka Module7 di VBP_Belajar001 telah berubah menjadi sebuah private module yang tidak dapat diakses secara global atau tidak dapat diakses oleh VBAProject selain VBP_Belajar001.
  • Aktifkan mod002 di VBP_Belajar002 dan tulis prosedur berikut :
     Public Sub PenggunaVBP_Belajar001_Module7()
         'menjalankan prosedur yang ada di Module7 VBP_Belajar001
         'yang sudah diberi Option Private Module
         VBP_Belajar001.ProcPublicDiMod7
     End Sub

  • Jika prosedur PenggunaVBP_Belajar001_Module7 dijalankan, maka akan menghasilkan error akibat tidak dikenalnya member bernama ProcPublicDiMod7. Seperti halnya UserForm1, seluruh variabel dan prosedur di Module7 yang ada di VBP_Belajar001 ini bisa digunakan oleh modeul lain yang ada di VBP_Belajar001 meskipun Module7 telah diberi Option Private Module.
  • Opsi berupa Option Private Module hanya bisa digunakan pada Code Module saja.

Beberapa hal yang dapat disimpulkan dari cerita diatas adalah :
  1. Deklarasi dengan keyword Public bisa dikatakan pada dasarnya memiliki scope level global.
  2. Deklarasi dengan keyword Public menghasilkan scope level Project ketika tidak bekerja sama saling terkait dengan VBAProject lain.
  3. Deklarasi dengan keyword Public menghasilkan scope level Project ketika module yang menjadi wadahnya adalah module private seutuhnya.
  4. Object module dari Microsoft Excel Objects tidak sepenuhnya bersifat private. Variabel atau prosedur yang dideklarasikan public didalamnya harus diakses layaknya object module yang benar-benar bersifat sebagai private module, yaitu dengan menyebut object module-nya terlebih dulu.
  5. Object module UserForm termasuk object module yang sepenuhnya bersifat private module. Bisa jadi karena class pembangunnya memang mendefinisikan bahwa object yang terbentuk benar-benar sebuah private module.
  6. Code module pada dasarnya memiliki sifat sebagai public module.
  7. Code module bisa diubah menjadi bersifat private module menggunakan Option Private Module.


Friend
Pada pembahasan tentang keyword Public dibagian tentang scope level global telah diketahui bahwa object module seperti Sheet atau ThisWorkbook tetap dapat diakses secara global secara langsung. Hal ini akan mengakibatkan seluruh variabel atau prosedur yang dideklarasikan dengan keyword Public akan dapat diakses secara global juga.

Kadangkala beberapa variabel atau prosedur dalam object module seperti sheet ini ingin tetap dijaga agar hanya ber-scope level project saja. Deklarasi dengan keyword Friend digunakan untuk hal seperti ini. Jadi, keyword Friend hanya bisa digunakan pada object module dan tidak bisa digunakan di dalam code module. Keyword Friend menghasilkan scope level Project.

Untuk mendapatkan gambaran yang lebih nyata, coba lakukan hal berikut :
  • Aktifkan sheet shtBelajar1 yang ada di VBP_Belajar001 dan tulis prosedur berikut :
     Friend Sub ProcFriendDiSheet()
         MsgBox "Pesan dari prosedur friend di sheet shtBelajar1 " & _
                 "yang ada di VBP_Belajar001"
     End Sub

  • Penggunaan keyword Friend dalam deklarasi prosedur ProcFriendDiSheet akan menyebabkan prosedur tersebut memiliki scope level project.
  • Aktifkan mod002 di VBP_Belajar002 dan tulis prosedur berikut :
     Public Sub PenggunaVBP_Belajar001_Sheet_ProcFriend()
         'menjalankan prosedur yang ada di sheet shtBelajar1 VBP_Belajar001
         'yang dideklarasikan dengan keyword Friend
         VBP_Belajar001.shtBelajar1.ProcFriendDiSheet
     End Sub

  • Prosedur PenggunaVBP_Belajar001_Sheet_ProcFriend akan menghasilkan error jika dijalankan. Error tersebut berupa tidak dikenalinya member bernama ProcFriendDiSheet didalam sheet shtBelajar1.


Menata Scope
Penataan scope pada dasarnya adalah memilih keyword yang sesuai agar didapatkan scope level yang juga sesuai dengan jenis prosesnya. Cara sederhana dalam menata scope pada umumnya adalah sebagai berikut :
  1. Variabel yang hanya digunakan dalam sebuah prosedur dan tidak perlu menyimpan nilai untuk digunakan dalam prosedur lainnya diatur untuk memiliki scope level procedure dengan menggunakan keyword Dim. Contohnya adalah variabel-variabel untuk proses perulangan (loop).
  2. Variabel atau prosedur yang digunakan oleh prosedur-prosedur yang ada dalam module tersebut saja dan tidak pernah digunakan oleh prosedur di module lainnya diatur untuk memiliki scope level module dengan menggunakan keyword Private. Contohnya adalah variabel penyimpan indeks option button yang dipilih user dalam sebuah userform. Dari sekian banyak option button yang menjadi pilihan dalam userform, hanya akan ada satu option button yang bernilai TRUE. Dengan menyimpannya dalam bentuk nomor indeks disuatu variabel, maka proses validasi input data sebelum proses save tidak membutuhkan pemeriksaan terhadap nilai setiap option button. Contoh lainnya adalah prosedur event dari suatu object module seperti userform atau sheet, karena event terjadi hanya pada module tersebut saja.
  3. Variabel atau prosedur yang akan secara aktif dapat digunakan oleh berbagai proses dalam program yang sedang dibangun diatur untuk memiliki scope level project atau global dengan menggunakan keyword Public.
  4. Ketika VBAProject dalam kondisi dapat dipergunakan oleh VBAProject lain, maka seluruh variabel atau prosedur yang hanya akan digunakan untuk proses secara lokal di dalam VBAProject tersebut diatur untuk memiliki scope level Project saja. Hal ini bisa diatur dengan berbagai cara, seperti penggunaan module yang diberi Option Private Module pada module-module berjenis Code Module, atau menggunakan keyword Friend pada object module seperti ThisWorkbook, Sheet, atau Chart.
  5. Khusus untuk object module berupa class module dan VBAProject akan dipergunakan oleh VBAProject lain, pengaturan tambahan pada properti bernama instancing maupun pemilihan penggunaan keyword friend akan membuat class tersebut bisa bersifat private ataupun public, sesuai kaidah class dalam Excel VBA.

Catatan
  • Deklarasi prosedur dalam VBA memiliki keyword default berupa Public. Jadi, jika sebuah prosedur tidak dinyatakan secara jelas keyword penentu scope level-nya, maka akan dinyatakan sebagai scope level yang menggunakan keyword Public. Meskipun ada kemudahan default seperti ini, sebaiknya tetap didisiplinkan untuk menuliskan keyword Public ketika akan mendeklarasikan suatu prosedur yang ingin dideklarasikan sebagai public atau sebagai prosedur yang memiliki scope level yang dihasilkan oleh keyword Public. Hal ini akan memudahkan pembacaan kode-kode program ketika sudah ada banyak prosedur dalam suatu module.
  • Mendeklarasikan variabel atau prosedur yang benar-benar bersifat global dalam Excel VBA tetap dimungkinkan. Jadi, seluruh VBAProject bisa menggunakan variabel atau prosedur tersebut tanpa perlu menambah referensi. Hal ini dapat dilakukan dengan bantuan fungsi-fungsi API (Application Programming Interface).

Sekian saja bahasan tentang scope yang sangat panjang ini (2 seri). Semoga bahasan ini bisa menjadi pijakan awal untuk membangun suatu aplikasi yang lebih baik. Minimal bisa menyusun suatu proses otomasi yang lebih baik. Harapannya, dengan bahasan ini, maka penataan scope level setiap variabel dan prosedur akan lebih sesuai kebutuhan setiap proses yang dibangun.

Insya Allah bahasan berikutnya adalah tentang DataType. Bahasan lain yang sangat jarang disentuh secara serius oleh para pembelajar VBA.


2 komentar:

  1. ijin copas ya....ni lagi semangat mau belajar, kelihatan menarik doakan berhasil

    makasih

    BalasHapus
    Balasan
    1. Silakan mas

      Semoga berhasil.
      Andai ada yang membingungkan, silakan ditanyakan ke milis Belajar-Excel.

      :)

      Hapus