Isilah masa sehat dengan kebaikan sebelum tiba masa sakit.
Pada pembahasan tentang combobox yang lalu, sumber data merujuk ke suatu area range yang diisikan ke dalam combobox dengan memanfaatkan properti ListFillRange (combobox di dalam worksheet) atau RowSource (combobox di dalam userform). Properti ListFillRange akan membuat daftar dalam combobox menjadi terikat erat dengan sumbernya, sehingga pengubahan isi daftar tanpa mengubah sumber data tidak dimungkinkan. Pengubahan bisa dilakukan bila yang diubah adalah nilai-nilai dalam sumber data.
Bahasan kali ini masih akan menggunakan data sumber untuk combobox list dari suatu range. Hanya saja, kali ini pengisian daftar combobox dilakukan tanpa properti ListFillRange atau RowSource, tetapi menggunakan methods AddItem ataupun properti List dari combbox. Hal ini akan membuat daftar menjadi lebih terbuka untuk diubah isinya. Kadang kala pengubahan isi daftar juga dibutuhkan pada beberapa kasus.
File yang akan digunakan adalah BelajarVBA102_02.xlsm. Data yang digunakan diletakkan pada sheet bernama 'populate' dengan nama object di dalam VBProject adalah Sheet2. Data tersebut seperti gambar berikut :
ComboBox list berisi satu kolom
Kali ini, pembahasan combobox akan memanfaat userform. Pada bahasan tentang combobox berisi satu kolom ini, akan menggunakan userform bernama frmNomor2 seperti gambar berikut :yang berisi object controls utama sebagai berikut :
- Combobox bernama cboProd : combobox dengan list berisi satu kolom yang dibaca dari sheet bernama populate (object Sheet2) pada range A2:A5.
- Textbox bernama txtListIndex : menampilkan nilai yang disimpan oleh properti ListIndex milik cboProd.
- Textbox bernama txtText : menampilkan nilai yang disimpan oleh properti Text milik cboProd.
- Textbox bernama txtValue : menampilkan nilai yang disimpan oleh properti Value milik cboProd.
- BoundColumn dan ColumnCount bernilai 1
- ColumnHeads bernilai FALSE
- ColumnWidths, ControlSource, RowSource, Text, Value dalam keadaan kosong
- ListWidth bernilai 0pt
- TextColumn bernilai -1
- Saat frmNomor2 dimuat ke memori komputer, maka dilakukan pengisian item-item daftar pilihan combobox, yang dilanjutkan dengan manampilkan frmNomor2 kepada user. Artinya, proses pengisian dilakukan saat frmNomor2 sedang diinisialisasi ke memori komputer. Jadi, proses pengisian item ke combobox llist dilakukan pada sebuah event milik userform frmNomor2, yaitu event Initialize.
- Ketika user mengubah pada combobox cboProd, maka akan dilakukan proses penulisan nilai-nilai yang disimpan oleh properti ListIndex, Text, dan Value dari cboProd ke :
- sheet bernama populate (Sheet2 di VBProject Explorer) pada range B13 sampai B15.
- textbox control terkait, yaitu txtListIndex, txtText, dan txtValue
- Saat userform frmNomor2 ditutup oleh user, maka dilakukan pembersihan isi range B13 sampai B15 yang ada di sheet bernama populate. Proses ini terjadi saat ada permintaan penutupan userform oleh user, yang akan memicu event milik userform yang bernama QueryClose. Jadi, proses pembersihan isi range tertentu tersebut diletakkan di dalam event QueryClose milik userform.
- Event Initialize milik userform frmNomor2
Diisi dengan proses pengisian daftar untuk combobox cboProd dengan langkah penyusunan sebagai berikut :- Membuat blok prosedur sub event Initialize milik userform frmNomor2 dengan cara :
- double click userform frmNomor2, sehingga muncul blok event Click milik userform frmNomor2
- pada combobox prosedur (sudut kanan atas area penulisan script) -> pilih Initialize
- letakkan cursor ke dalam blok prosedur sub event Initialize yang terbentuk
- Mendeklarasikan variabel yang dibutuhkan selama proses pengisian
Pengisian item list combobox cboProd bisa dilakukan dengan 2 (dua) cara, yaitu : (pilih salah satu)
- Memanfaatkan methods AddItem dengan cara melakukan loop terhadap setiap item sumber data. Sumber data yang berada di sheet populate (object Sheet2) pada range A2:A5 membutuhkan variabel loop bertipe Range. Maka perlu pendeklarasian variabel tersebut, yang misalnya diberi nama rngCurrent. Baris kode deklarasi tersebut berbunyi :
Dim rngCurrent As Range
- Memanfaatkan properti List dengan cara menyediakan array seluruh item dari sumber data. Berarti, sumber data yang ada di sheet populate (object Sheet2) pada range A2:A5 dibaca dan disimpan sebagai sebuah array. Area range sebenarnya adalah suatu array dan tipe data yang memungkinkan dengan mudah untuk menyimpan array dari suatu range adalah tipe Variant. Maka perlu pendeklarasian variabel bertipe variant, yang misalnya diberi nama vSumber. Baris kode deklarasi tersebut berbunyi :
Dim vSumber As Variant
- Memanfaatkan methods AddItem dengan cara melakukan loop terhadap setiap item sumber data. Sumber data yang berada di sheet populate (object Sheet2) pada range A2:A5 membutuhkan variabel loop bertipe Range. Maka perlu pendeklarasian variabel tersebut, yang misalnya diberi nama rngCurrent. Baris kode deklarasi tersebut berbunyi :
- Menyusun baris kode proses pengisian
Sumber data di sheet populate (Sheet2) pada range A2:A5.- Jika memilih menggunakan methods AddItem, maka dibutuhkan proses loop terhadap setiap item dalam range A2:A5. Di dalam proses loop tersebut diisi proses penambahan item ke list milik combobox dengan methods AddItem. Baris-baris kode proses ini adalah :
For Each rngCurrent In Sheet2.Range("a2:a5")
cboProd.AddItem rngCurrent.Value
Next rngCurrent - Jika memilih menggunakan properti List, maka dibutuhkan proses penyimpanan sumber data range A2:A5 menjadi array, yaitu ke dalam variabel vSumber. Kemudian array dalam variabel vSumber dimasukkan ke properti List. Baris-baris kode proses ini adalah :
vSumber = Sheet2.Range("a2:a5")
cboProd.List = vSumber
- Jika memilih menggunakan methods AddItem, maka dibutuhkan proses loop terhadap setiap item dalam range A2:A5. Di dalam proses loop tersebut diisi proses penambahan item ke list milik combobox dengan methods AddItem. Baris-baris kode proses ini adalah :
- Bentuk akhir prosedur sub event Initialize menjadi :
- Methods AddItem
Private Sub UserForm_Initialize()
Dim rngCurrent As Range
For Each rngCurrent In Sheet2.Range("a2:a5")
cboProd.AddItem rngCurrent.Value
Next rngCurrent
End Sub - Properti List
Private Sub UserForm_Initialize()
Dim vSumber As Variant
vSumber = Sheet2.Range("a2:a5")
cboProd.List = vSumber
End Sub
- Methods AddItem
- Membuat blok prosedur sub event Initialize milik userform frmNomor2 dengan cara :
- Event Change milik cboProd
Diisi dengan proses penulisan ke lokasi target dengan langkah penyusunan sebagai berikut :- Membentuk blok prosedur sub event Change milik cboProd dengan cara double click object control combobox cboProd yang ada di dalam userform frmNomor2 dan meletakkan cursor di dalam blok prosedur yang terbentuk
- Menulis nilai-nilai properti ListIndex, Text, dan Value secara berurutan ke :
- Sheet populate pada range B13 sampai B15 dengan baris-baris kode :
Sheet2.Range("b13").Value = cboProd.ListIndex
Sheet2.Range("b14").Value = cboProd.Text
Sheet2.Range("b15").Value = cboProd.Value - Object controls textbox txtListIndex, txtText, dan txtValue dengan baris-baris kode :
txtListIndex.Text = cboProd.ListIndex
txtText.Text = cboProd.Text
txtValue.Text = cboProd.Value
- Sheet populate pada range B13 sampai B15 dengan baris-baris kode :
- Bentuk akhir blok prosedur sub event Change milik cboProd :
Private Sub cboProd_Change()
Sheet2.Range("b13").Value = cboProd.ListIndex
Sheet2.Range("b14").Value = cboProd.Text
Sheet2.Range("b15").Value = cboProd.Value
txtListIndex.Text = cboProd.ListIndex
txtText.Text = cboProd.Text
txtValue.Text = cboProd.Value
End Sub
- Event QueryClose milik userform frmNomor2
Diisi dengan proses menghapus isi range B13 sampai B15 pada sheet bernama populate (object Sheet2), yang menjadi lokasi penulisan pada proses di dalam event Change milik cboProd. Langkah-langkah penyusunannya adalah sebagai berikut :- Membentuk blok prosedur sub event QueryClose milik userform frmNomor2 dengan cara :
- double click userform frmNomor2
- pada combobox daftar prosedur (pojok kanan atas area penulisan script) -> pilih QueryClose
- letakkan cursor di dalam blok prosedur yang terbentuk
- Menulis baris kode untuk menghapus isi range B13 sampai B15 di sheet populate (object Sheet2) yang berbunyi :
Sheet2.Range("b13:b15").ClearContents
- Bentuk akhir blok prosedur sub event QueryClose menjadi :
Private Sub UserForm_QueryClose( _
Cancel As Integer _
, CloseMode As Integer)
Sheet2.Range("b13:b15").ClearContents
End Sub
- Membentuk blok prosedur sub event QueryClose milik userform frmNomor2 dengan cara :
ComboBox list multi kolom hanya menampilkan satu kolom
Kali ini, dibuat sebuah userform yang diberi nama frmNomor3 yang mirip dengan userform frmNomor2. Perbedaannya adalah penambahan textbox bernama txtCol2 untuk menampilkan nilai dari kolom ke-3 list combobox. Properti BoundColumn di-set bernilai 2 dan properti TextColumn di-set bernilai 1. Sedangkan properti ColumnCount tetap bernilai 1 karena hanya akan menampilkan satu kolom saja. Sumber data untuk list combobox diambil dari sheet populate (object Sheet2) pada area range A2:C5 (3 kolom). Bentuk userform frmNomor3 seperti gambar berikut :> Proses pend-disable-an event pada userform
Kebutuhan untuk membaca nilai dari kolom list yang tidak ditunjuk oleh properti BoundColumn maupun TextColumn, seperti ingin mengambil nilai dari kolom list ke-3 [indeks kolom bernilai 2 = Column(2)] bisa memicu timbulnya error ketika nilai pada kolom yang dirujuk tersebut belum terdefinisikan. Contohnya adalah ingin mengambil nilai dari kolom ke-3, tetapi pada baris item tersebut baru 2 kolom saja yang didefinisikan.Error seperti ini sering terjadi ketika proses pengambilan nilai pada suatu kolom list dilakukan pada event Change milik combobox terkait (misal pada event Change milik cboProd). Artinya, dibutuhkan sebuah proses untuk mengabaikan kerja prosedur sub event change pada saat mengubah isi list, karena tidak ada pengaturan untuk men-disable event milik userform. Cara men-disable event di suatu userform dalam VBA dilakukan dengan menggunakan variabel ber-scope module yang diperiksa oleh setiap prosedur sub event yang tidak ingin dijalankan dengan alasan tertentu.
Pada contoh kasus ini, proses pada event Initialize userform frmNomor3 bisa memunculkan error, karena proses pengisian list combobox akan memicu event Change milik cboProd. Untuk men-disable event, maka dibuat sebuah variabel bernama bEventTidakBolehJalan dengan scope module. Baris kode deklarasi variabel ini diletakkan pada area General Declaration (di baris pertama area penulisan script atau setelah baris berbunyi Option Explicit). Baris kode tersebut berbunyi :
Private bEventTidakBolehJalan As Boolean
Pada event Change milik cboProd, yaitu dibaris pertama setelah baris deklarasi variabel diberi proses cek terhadap nilai variabel bEventTidakBolehJalan dengan bentuk baris kode :
If bEventTidakBolehJalan Then
Exit Sub
End If
yang berarti, jika variabel bEventTidakBolehJalan sedang bernilai TRUE, maka proses langsung keluar dari prosedur alias tidak ada proses dalam prosedur event tersebut yang dilakukan.
Cara menggunakannya, pada prosedur yang salah satu prosesnya bisa memicu si event Change milik cboProd untuk dijalankan, seperti pada event Initialize milik userform frmNomor3, diberi baris kode untuk mengubah nilai variabel bEventTidakBolehJalan menjadi TRUE. Penempatannya adalah tepat sebelum proses yang memicu berjalannya event Change milik cboProd. Pada kasus ini, berarti baris kode berbunyi :
bEventTidakBolehJalan = TRUE
diletakkan tepat sebelum proses pengisian item list cboProd di dalam prosedur sub event Initialize. Pada bagian akhir event Initialize, yaitu tepat sebelum keluar dari prosedur atau sebelum baris End Sub, diberi baris kode untuk mengembalikan nilai variabel bEventTidakBolehJalan menjadi FALSE. Baris kode tersebut berbunyi :
bEventTidakBolehJalan = FALSE
> Proses pengisian multi kolom list dengan methods AddItem
Cara mengisi multi kolom list menggunakan methods AddItem memerlukan sebuah variabel penyimpan indeks baris list yang akan ditambahkan. Misalkan variabel ini diberi nama lCboIndex. Maka pada event Initialize diberi penambahan deklarasi variabel tersebut. Maka baris deklarasi variabel pada event Initialize menjadi :Dim rngCurrent As Range, lCboIndex As Long
Kemudian nilai lCboIndex di-set dengan nilai awal indeks baris list yang base-0, yaitu dengan nilai 0 seperti dengan baris berbunyi :
lCboIndex = 0
Proses loop yang tadinya berbentuk :
For Each rngCurrent In Sheet2.Range("a2:a5")
cboProd.AddItem rngCurrent.Value
Next rngCurrent
diubah menjadi :
For Each rngCurrent In Sheet2.Range("a2:a5")
cboProd.AddItem rngCurrent.Value 'pembuat item baru
'pengisi kolom list ke-2 dan seterusnya
cboProd.List(lCboIndex, 1) = rngCurrent.Offset(0, 1).Value
cboProd.List(lCboIndex, 2) = rngCurrent.Offset(0, 2).Value
'set nilai indeks baris list berikutnya yang akan diisi
lCboIndex = lCboIndex + 1
Next rngCurrent
> Proses pengisian multi kolom list dengan properti List
Jika menggunakan properti List, maka yang diubah adalah rujukan range yang tadinya merujuk ke A2:A5 menjadi merujuk ke A2:C5 (lihat bagian yang di-merah).vSumber = Sheet2.Range("a2:c5")
> Penambahan baris penulisan pada event Change cboProd
Pengambilan nilai kolom ke-3 (indeks kolom ke-2) dapat dilakukan dengan properti Column maupun properti List seperti yang telah dijelaskan pada coretan tentang combobox sebelum ini. Penulisan ke sheet populate pada kasus multi kolom list ini dilakukan ke range H18:H21, sehingga baris kode bagian penulisan ke sheet populate menjadi :Sheet2.Range("h18").Value = cboProd.ListIndex
Sheet2.Range("h19").Value = cboProd.Text
Sheet2.Range("h20").Value = cboProd.Value
Sheet2.Range("h21").Value = cboProd.List(, 2) 'atau cboProd.Column(2)
Sedangkan pada penulisan ke textbox txtCol2 adalah dengan menambahkan baris kode :
txtCol2.Text = cboProd.List(, 2) 'atau cboProd.Column(2)
Hasil akhir penyusunan script untuk userform frmNomor3 dapat dilihat pada file BelajarVBA102_02.xlsm.
Tambah, ubah, dan hapus item list combobox
> menambah sebuah item ke list combobox
Misalkan ada sebuah combobox bernama cboProd. Penambahan item list dilakukan dengan menggunakan methods AddItem dengan susunan :cboProd.AddItem nilai_baru, [indeks_posisi_penambahan]
Jika ingin menambahkan pada baris baru adalah dengan mengabaikan bagian [indeks_posisi_penambahan] seperti :
cboProd.AddItem nilai_baru
Bagian nilai_baru adalah teks (bertipe String) yang akan menjadi nilai baru di kolom ke-1 (indeks kolom ke-0).
Contohnya adalah ingin menambahkan item baru 'X' di baris baru, maka baris kodenya adalah :
cboProd.AddItem "X"
Jika item baru 'Y' ingin ditambahkan pada baris ke-1 list (indeks baris ke-0), maka baris kodenya adalah :
cboProd.AddItem "Y", 0
Pada combobox dengan multi kolom list, maka bisa jadi dibutuhkan juga pengisian pada kolom ke-2 dan seterusnya (penambahan pada indeks kolom ke-1 dan seterusnya). Pengisian tersebut bisa dilakukan setelah ada penambahan item baru dengan methods AddItem di atas. Susunan penulisan item di kolom lain tersebut secara umum adalah :
cboProd.List(idxrow, idxcol) = nilai_kolom_baru
Misalkan ingin menambahkan item 'Z' pada baris baru dengan nilai kolom ke-2 bernilai 'Z01' dan nilai kolom ke-3 bernilai 'ZZ11P001', maka baris-baris kode penambahan tersebut adalah :
cboProd.AddItem "Z"
cboProd.List( cboProd.ListCount-1 , 1) = "Z01"
cboProd.List( cboProd.ListCount-1 , 2) = "ZZ11P001"
Properti ListCount dipergunakan untuk mendapatkan jumlah item dalam list. Karena properti ListIndex menggunakan base 0 (indeks baris item pertama bernilai 0), maka nilai properti ListCount - 1 adalah indeks baris item terakhir yang ada. Pada kasus di atas, berarti pada baris item 'Z' yang baru saja ditambahkan di baris baru.
Sedangkan jika ingin menyisipkan (menambah item pada baris tertentu) item 'M' pada baris ke-1 (indeks baris 0) dengan nilai kolom ke-2 bernilai 'M78' dan nilai kolom ke-3 bernilai 'KL98P113', maka baris-baris kode penambahan tersebut adalah :
cboProd.AddItem "M", 0
cboProd.List( 0 , 1) = "M78"
cboProd.List( 0 , 2) = "KL98P113"
Kadangkala, pemeriksaan posisi penyisipan perlu dilakukan, sehingga dapat dipastikan bahwa indeks baris penyisipan tidak lebih dari nilai properti ListCount. Nilai properti ListCount bisa diartikan juga sebagai indeks baris baru jika akan dilakukan penambahan data. Bentuk pemeriksaan tersebut adalah sebagai berikut :
'0 adalah indeks baris lokasi penyisipan dan bisa diganti dengan variabel tertentu
If cboProd.ListCount >= 0 Then
'proses penyisipan diletakkan disini
cboProd.AddItem "M", 0
cboProd.List( 0 , 1) = "M78"
cboProd.List( 0 , 2) = "KL98P113"
End If
> mengubah isi sebuah item yang ada di list combobox
Misalkan ada sebuah combobox bernama cboProd. Pengubahan isi sebuah kolom dalam list combobox dilakukan dengan memanfaatkan propeti List. Bentuk umum beris kodenya adalah :cboProd.List(idxrow, idxcol) = nilai_kolom_baru
dengan syarat bahwa idxrow (indeks baris yang akan diubah isinya) kurang dari jumlah item (nilai properti ListCount). Biasanya, bentuk diatas disertai pemeriksaan terhadap indeks baris yang akan diubah isinya. Bentuk lengkapnya menjadi :
'idxrow adalah indeks baris yang akan diubah isinya
If idxrow < cboProd.ListCount Then
cboProd.List(idxrow, idxcol) = nilai_kolom_baru
End If
Misalkan akan mengubah isi kolom ke-3 (indeks kolom ke-2) pada item di baris pertama (indeks baris ke-0) menjadi 'GJ71P123', maka baris kodenya adalah :
If 0 < cboProd.ListCount Then
cboProd.List(0, 2) = "GJ71P123"
End If
> menghapus isi list combobox
Misalkan ada sebuah combobox bernama cboProd. Jika akan menghapus seluruh isi list combobox, maka dapat menggunakan methods Clear. Baris kodenya adalah :cboProd.Clear
Jika yang akan dihapus adalah sebuah item di baris tertentu, maka dilakukan dengan menggunakan methods RemoveItem disertai indeks baris (base 0) yang akan dihapus. Bentuk umum baris kodenya adalah :
cboProd.RemoveItem indeks_baris_yang_dihapus
Biasanya, penghapusan sebuah baris item dilakukan setelah diperiksa bahwa baris yang akan dihapus ada didalam list. Artinya, indeks baris yang akan dihapus (indeks_baris_yang_dihapus) kurang dari jumlah item list (nilai properti ListCount). Jadi bentuk umum menghapus sebuah item list combobox yang disertai pemeriksaan keberadaan baris yang akan dihapus adalah :
If indeks_baris_yang_dihapus < cboProd.ListCount Then
cboProd.RemoveItem indeks_baris_yang_dihapus
End If
Misalkan ingin menghapus item di baris ke-4 (indeks baris ke-3), maka baris kodenya adalah :
If 3 < cboProd.ListCount Then
cboProd.RemoveItem 3
End If
Contoh tentang penerapan penambahan item, pengubahan isi, dan penghapusan item bisa dilihat di file BelajarVBA102_02.xlsm pada userform bernama frmNomor4 yang bisa diaktifkan melalui tombol di sheet bernama 'sisip_ubah_buang'. Pada userform tersebut juga disertakan contoh pemanfaatan event Click milik object control Label yang bisa menjadi alternatif sebuah tombol seperti object control CommandButton.
:)
Insya Allah pembahasan berikutnya tentang object control ListBox pada properti yang tidak dimiliki oleh ComboBox, yaitu properti MultiSelect. Selain itu, juga akan dibahas tentang object control Label, khususnya pada pemanfaatan properti Caption dan MultiLine. Object control textbox juga memiliki properti MultiLine, tetapi ada properti PasswordChar yang bisa digunakan untuk me-masking inputan user pada control tersebut. Event KeyDown acapkali terasa bermanfaat ketika digunakan oleh textbox, seperti membatasi inputan untuk numerik saja atau karakter tertentu saja dan sebagainya. Event KeyDown pada textbox juga akan dibahas disana.
Mr. Kid,
BalasHapusMau nanya mengenai proses pengisian multi kolom list dengan property list
setelah code :
vSumber = Sheet2.Range("a2:c5")
Bagaimana pengisiannya ke cboProd ?
Terima kasih
HK
Pengisian ke cboProd tetap caranya pak.
HapuscboProd.List = vSumber
Komentar ini telah dihapus oleh pengarang.
HapusSalam Kenal Master-master excel, salam kenal master Mr. Kid. Saya awam masalah Vba tapi saya ingin sekali memahami vba. Saat ini saya sedang menginput data nilai dalam dokumen induk nilai (legger), tapi nama mahasiswa dalam sumber data nilai dalam kertas tertulis acak, sehingga memperlambat dalam proses input. untuk mempermudah input tersebut saya ingin membuat form input data yang di dalamnya memuat pencarian nama mahasiswa, combobox nama mata kuliah dan kolom input nilai dari mata kuliah tersebut. Saya berharap para master dapat memberikan urutan kodenya sehingga form tersebut bisa diwujudkan. Terima kasih sebelumnya.
BalasHapusCoba ditanyakan ke Belajar-Excel (cara daftar dan cara posting bisa dilihat disini)
Hapushttps://groups.yahoo.com/neo/groups/belajar-excel/info
wallahh..cukup puyengg
BalasHapusMr Kid,
BalasHapusBagaimana cara mengurutkan data berdasarkan alphabetic pada combobox yang menggunakan rowsource?
Thanks..
Hai Wahyu,
HapusArea range rowsource di sort.
Bisa dengan manual sort jika tanpa VBA.
Andai area range rowsource merujuk ke suatu area di pivot table bagian Row Fields, maka pivot table bisa diset selalu dalam keadaan sorted sesuai kebutuhan setiap kali refresh pivot table.
Jika dengan VBA, dengan combobox bernama cboKid dan area range rowsource menggunakan nama range bernama lstKid yang ber-scope workbook, bunyi baris kodenya kira-kira begini : (misal sort key di kolom pertama)
with range("lstKid")
.sort .resize(1,1).offset(0,0),xlascending,header:=xlno,orientation:=xlsortcolumns
end with
Jika sort column key ada di kolom ke-2, ganti .offset(0,0) menjadi .offset(0,1)
Regards,
Kid
bagian di dalam blok with nya sebaris ya...
HapusKalau dibuat multi baris, bunyinya begini :
with range("lstKid")
.sort .resize(1,1).offset(0,0) _
,xlascending _
,header:=xlno _
,orientation:=xlsortcolumns
end with
blm bisa
BalasHapus