Object Recordset mengandung semua data yang Anda baca dari sebuah database atau yang Anda kirim kepadanya. Sebuah recordset terdiri atas beberapa baris dan kolom data. Setiap satu baris merupakan sebuah record, dan setiap satu kolom merupakan sebuah field di dalam record. Anda dapat mengakses hanya beberapa baris dan kolom data, dan dapat memanggil baris atau record yang aktif. Anda melakukan navigasi melalui sebuah Recordset dengan mengganti record yang aktif.
Object Recordset ADO lebih banyak memiliki kegunaan daripada Recordset di DAO dan RDO. Sebagai contoh, Anda dapat membuat sebuah object Recordset ADO sendiri tanpa harus melakukan koneksi ke sebuah database. Atau Anda dapat mengambil sebuah Recordset dari sebuah database, menutup connection, memodifikasi data di Recordset, dan akhirnya melakukan connection ulang ke semua hasil perubahan yang Anda lakukan ke server. (Perubahan dengan menggunakan "optimisticbatch" bisa terjadi di RDO tapi tidak di DAO). Anda bahkan dapat menyimpan sebuah Recordset ADO ke sebuah file, sehingga dapat mengambilnya lagi kemudian.
Object Recordset merupakan object yang "terkaya" di model object ADO bagian properties-nya. Lagi-lagi, kita akan mengelompokkan properties tersebut berdasarkan fungsinya daripada berdasarkan namanya.
Setting Source RecordsetProperty yang paling berarti di object Recordset adalah Source, yang menyimpan nama tabel, nama dari "stored procedure", atau teks dari query SQL yang digunakan untuk membangkitkan Recordset. Property ini dideklarasikan sebagai Variant, yang membolehkan Anda untuk meng-assign sebuah object Command kepadanya. Jika Anda meng-assign sebuah object Command pada property ini, dia akan mengembalikan isi dari property CommandText dari object Command, bukan sebuah referensi ke object Command itu sendiri. Property Source bersifat "read/write" untuk object Recordset yang tertutup, dan bersifat "read-only" setelah Recordset dibuka. Berikut ini contoh untuk property Source:
| Code:: |
'Edit konstanta ini untuk menyesuaikan dengan directori database Anda. Const DBPATH = "C:\Program Files\Microsoft Visual Studio\Vb98\NWind.mdb" Dim cn As New ADODB.Connection, rs As New ADODB.Recordset cn.Open "Provider=Microsoft.Jet.OLEDB.3.51;Data Source=" & DBPATH rs.Source = "Employees" rs.Open, cn |
Anda dapat membuat coding di atas lebih singkat jika Anda melewatkan nilai dari property sebagai argumen pertama dari method Open:
| Code:: |
rs.Open "Employees", cn |
Ketika Anda meng-assign sebuah object Command ADO ke property Source, Anda nanti dapat mengambil sebuah referensi ke object ini melalui property ActiveCommand.
Untuk membuka sebuah Recordset, Anda harus mempasangkannya dengan sebuah Connection yang sudah ada. Anda dapat membuat secara eksplisit object Connection ini dan meng-assign-kannya ke dalam property ActiveConncetion, atau Anda dapat membuatnya secara implisit dengan meng-assign-kan sebuah string connection ke dalam property ActiveConnection:
| Code:: |
'Sesuaikan direktori tempat database dengan direktori Anda. Const DBPATH = "C:Program Files\Microsoft Visual Studio\VB98\NWind.mdb" 'Cara pertama: Menggunakan object Connection secara eksplisit cn.Open "Provider=Microsoft.Jet.OLEDB.3.51;Data Source=" & DBPATH_ Set rs.ActiveConnection = cn rs.Source = "Employees" rs.Open 'Cara kedua: Menggunakan object Connection secara implisit rs.ActiveConnection = "Provider=Microsoft.Jet.OLEDB.3.51;" _ & "Data Source= " & DBPATH rs.Source = "Employees" rs.Open |
Ketika Anda membuat sebuah object Connection secara implisit, Anda dapat mereferensikannya nanti melalui property ActiveConnection (sebagai contoh, untuk mengakses Error collection milik Connection). Property ActiveConnection bersifat "read-only" setelah record telah dibuka atau ketika sebuah object Command telah di-assign ke property ActiveCommand.
Cara lainnya untuk memilih lokasi dari mana Recordset mengambil datanya adalah dengan menggunakan property Datasource dan DataMember. Sebagai contoh, Anda dapat menghubungkan sebuah object Recordset kepada sebuah control ADO dengan menggunakan statement berikut:
| Code:: |
Set rs.DataSource = Adodc1 |
Anda tidak perlu mengeset ke property lainnya, juga tidak perlu memanggil method Open (yang mana pada kenyatannya akan menimbulkan error). Jika datasource berupa sebuah object DataEnvironment, Anda juga perlu meng-assign sebuah string yang valid ke property DataMember; kalau tidak, sebuah error akan terjadi ketika Anda mengeset property DataSource.
Property State milik Recordset mengembalikan posisi (state) dari Recordset yang ada sebagai sekelompok bits yang dapat dicoba secara tersendiri:
| Value (Nilai) | Deskripsi |
| 0-adStateClosed | Recordset dalam keadaan tertutup. |
| 1-adStateOpen | Recordset dalam keadaan terbuka. |
| 2-adStateConnecting | Recordset sedang dalam keadaan terhubung (connecting). |
| 4-adStateExecuting | Recordset sedang mengeksekusi sebuah perintah (command). |
| 8-adStateFetching | Beberapa baris Recordset sedang diambil/dijemput. |
The last three values apply only when the Recordset object is executing an asynchronous method.
Tiga nilai terakhir dapat diterapkan hanya ketika object Recordset sedang mengeksekusi sebuah method Asynchronous.
Bekerja dengan Cursor
Sebuah kursor (cursor) adalah sekumpulan dari record yang mewakili hasil dari sebuah query. Cursors dapat mengandung data yang sebenarnya atau hanya penunjuk (pointers) ke record-record di database, tapi mekanisme pengambilan data bersifat transparan buat programmer. Anda dapat memilih cursor yang mana yang akan dibuat (pada client atau pada server workstation), tipe cursor, dan pilihan locking.
Property CursorLocation menggambarkan di mana cursor dibuat. Property ini dapat mempunyai satu dari dua nilai: "2-adUseServer" atau "3-adUseClient". Nilai dari property ini dapat diturunkan dari object Connection dan dapat diganti hanya untuk Recordset yang tertutup. Ketika Anda sedang bekerja dengan Provider OLE DB untuk ODBC Drivers dan untuk SQL Server, default cursor-nya adalah "forward-only" (hanya dapat maju) dan berada di server. (Tipe cursor ini juga lebih efisien). Anda perlu mengganti ke cursor yang "client-side" jika Anda akan membuat Recordset yang terpisah dan menggunakan strategi "optimistic batch update". Cursor "client-side" sering merupakan pilihan yang baik ketika Anda mempunyai sebuah control DataGrid atau control lainnya yang bersifat kompleks untuk menampilkan Recordset. Dalam semua hal, cursor "server-side" sering lebih suka digunakan karena menyediakan performansi yang lebih baik dan mendukung semua tipe cursor.
Property CursorType menggambarkan tipe dari cursor yang dibuat dan dapat berupa salah satu dari konstanta berikut: "0-adOpenForwardOnly", "1-adOpenKeyset", "2-adOpenDynamic", atau "3-adOpenStatic". Cursor "server-side" mendukung semua dari pilihan di atas, sedangkan cursor "client-side" hanya mendukung "3-adOpenStatic". Tapi jika Anda menggunakan sebuah setting yang berbeda untuk sebuah cursor "client-side", sebuah cursor static akan otomatis dibentuk tanpa menimbulkan error.
Sebuah cursor "forward-only" merupakan default untuk cursor yang "server-side" dan hanya tersedia untuk cursoer "server-side". Seperti yang telah disebutkan sebelumnya, tipe cursor ini adalah yang paling efisien, khususnya jika Anda mengeset LockType menjadi "adReadOnly" dan CacheSize sama dengan 1 (satu). Banyak programmer me-refer ke tipe terakhir dari cursor tipe ini sebagai sebuah "noncursor". Dalam "Hitchhiker's Guide to Visual Basic and SQL Server", William R. Vaughn mendefinisikan hal ini sebagai cursor "fire-hose", yang menitikberatkan betapa cepatnya cursor ini "memberikan" data ke aplikasi client. Anda tidak harus melakukan apapun khususnya dalam menggunakan cursor ini (atau noncursor) karena cursor ini merupakan default-nya ADO. Anda dapat melakukan navigasi pada Recordset yang "forward-only" hanya dengan menggunakan method MoveNext. Jika Anda ingin mendapatkan hasil yang terbaik untuk sebuah aplikasi yang membutuhkan pengubahan record, Anda harus melakukan semua update melalui perintah SQL atau "stored-procedures".
Cursors Dynamic terdiri dari sekumpulan bookmarks pada data sebenarnya di data source. Kapanpun client meminta sebuah record, ADO menggunakan bookmark untuk membaca nilai yang ada, yang berarti bahwa aplikasi selalu membaca nilai terakhir yang disimpan oleh user lain. Cursor dynamic secara otomatis di-update ketika user lainnya menambah atau menghapus sebuah record atau mengubah record apapun yang telah ada di Recordset. Bukan hal yang aneh, cursor-cursor ini adalah yang "termahal" penampilannya di jaringan dan lalu-lintas LAN karena kapanpun Anda memindahkan ke record lainnya, sebuah "perjalanan" ke server dibutuhkan untuk mengambil nilai yang ada. Anda dapat selalu meng-update data dan melakukan semua jenis method navigasi pada Recordset yang dinamik, termasuk menggunakan bookmark jika provider mendukungnya. Cursor tipe ini selalu tersedia hanya sebagai cursor "server-side".
Microsoft Jet Engine tidak mendukung cursor dynamic, jadi jika Anda mencoba untuk membuka cursor dynamic dengan Jet OLE DB Provider, Anda selalu mendapatkan sebuah "keyset".
Cursor keyset sama dengan cursor dynamic, tapi dia tidak termasuk record yang ditambahkan oleh user lainnya. (Perubahan yang dilakukan oleh user lainnya terhadap record di Recordset akan kelihatan). Anda dapat membaca dan memodifikasi semua record di cursor, tapi Anda mendapat sebuah error jika Anda mengakses sebuah record yang telah dihapus oleh user lain. Cursor keyset tersedia hanya sebagai cursor yang "server-side".
Cursor Static membuat sebuah snapshot lengkap yang dapat di-scroll dari semua record yang diidentifikasikan oleh property Source, dan mereka hanya tipe yang mungkin untuk cursor "client side". Karena sebuah cursor static merupakan hasil dari sebuah penyalinan data yang berasal dari database, perubahan yang dilakukan oleh user lainnya tidak kelihatan. Walaupun cursor ini kurang efisien daripada cursor yang "forward-only" dan meningkatkan tugas me-load pada komputer yang menggunakannya, performansinya bagus dan cursor ini merupakan pilihan yang baik, khususnya ketika Recordset tidak memiliki banyak record. Sebuah cursor static biasanya sangat baik untuk mengambil data dari sebuah "stored-procedure". Tergantung pada provider dan pada setting lainnya, Recordset ini dapat diupdate. Anda harus membuat cursor static pada "client-side" hanya ketika workstation client memiliki memory yang cukup.
Property MaxRecords mengeset sebuah batas jumlah record yang akan dikembalikan dalam Recordset ketika Anda bekerja dengan sebuah cursor. Nilai default-nya adalah 0 (nol), yang berarti bahwa semua record akan diambil. Property ini dapat diisi ketika Recordset sedang tertutup dan akan bersifat "read-only" ketika Recordset sedang terbuka.
Property CacheSize mengeset dan mengembalikan jumlah record yang disembunyikan ADO secara lokal ketika bekerja dengan cursor. Anda dapat menyesuaikan nilai dari property ini ke nilai yang cocok bagi aplikasi Anda, berkaitan dengan pertukaran memory untuk performansi. Anda dapat meng-assign sebuah nilai yang baru ke property ini kapanpun, tapi jika Recordset sedang terbuka, setting yang baru akan digunakan hanya ketika ADO mengisi tempat persembunyian lokal (local cache) itu, yaitu ketika Anda memindahkan pointer ke record yang ada untuk menunjuk ke sebuah record yang tidak berada pada cache.
Banyak programmer menyukai cursor, khususnya yang dynamic dan keyset, karena mereka sangat powerful dan serba-guna. Sayangnya, cursor sering merupakan pilihan yang terburuk bagi penampilan, sumber-daya, dan untuk ruang lingkup tertentu. Anda seharusnya menggunakan cursor hanya ketika bekerja dengan Recordset yang kecil atau ketika sedang menggunakan "bound-control". (Bound-control membutuhkan cursor untuk mendukung navigasi mundur dan maju). Ketika Anda menyediakan cursor, ingatlah untuk membangun property Source, jadi Anda mengurangi jumlah record yang diambil dan gunakan sebuah clause "WHERE" yang mengacu kepada satu atau lebih field yang di-indeks. Teknik yang efektif lainnya untuk meningkatkan performansi aplikasi Anda adalah dengan mengeksekusi sebuah method MoveLast untuk menghasilkan Recordset dengan cepat dan membebaskan penguncian apapun pada data source sedapat mungkin.
Bekerja dengan Persetujuan
Semua database yang digunakan oleh banyak user memakai beberapa tipe strategi penguncian. Penguncian perlu untuk mencegah user lainnya dari tindakan pengubahan pada record yang sama dan pada waktu yang bersamaan, yang mana mungkin akan mengakibatkan dalam ketidakkonsistenan database. Penguncian secara ekstrim sangat "mahal" dalam batas tertentu; ketika sebuah penguncian diterapkan pada sebuah record yang sedang dimodifikasi oleh seorang user, tidak ada user yang dapat mengakses record yang sama. Tergantung pada bagaimana Anda membuat aplikasi Anda, sebuah penguncian dapat menurunkan performansi dan juga dapat menyebabkan error jika Anda tidak menerapkan solusi yang baik dalam strategi penguncian.
Propery LockType menggambarkan tipe penguncian yang mana yang harus diterapkan pada data di dalam database. Property enumerated ini dapat di-assign ke salah satu nilai berikut: "1-adLockReadOnly", "2-adLockPessimistic", "3-adLockOptimistic", dan "4-adLockBatchOptimistic".
Nilai default untuk property ini adalah "adLockReadOnly:, yang akan membentuk Recordset yang tidak dapat diupdate. Ini adalah pilihan yang paling efisien karena tidak menerapkan sebuah penguncian penulisan pada data. Hal ini juga pilihan yang terbaik pada ruang lingkup yang pasti. Lagi-lagi, sebuah strategi yang baik adalah mempercayakan pada cursor "forward-only", "read-only" (default di ADO) ketika membaca data dan melakukan semua perubahan melalui SQL Statement atau "stored-procedures".
Ketika Anda sedang menggunakan penguncian "pessimistic", ADO mencoba mengunci record segera setelah Anda melakukan perubahan pada mode, dan akan terjadi ketika Anda memodifikasi sebuah field pada Recordset. Penguncian akan dibebaskan hanya ketika Anda membuat sebuah method Update atau memindahkan kursor ke record lainnya. Ketika sebuah record dikunci, tidak ada user yang dapat mengakses record tersebut untuk diubah, dan secara tegas mengurangi kemampuan dalam ruang lingkup aplikasi. Untuk alasan ini, Anda seharusnya tidak pernah menggunakan penguncian "pessimistic" ketika antar muka aplikasi Anda mengizinkan user bebas melakukan navigasi pada Recordset (kecuali Anda ingin membatasi semua user ketika siapapun dari mereka tidak menggunakan aplikasi!). Penguncian "pessimistic" tersedia hanya untuk cursor "server-side".
Penguncian "optimistic" lebih baik daripada penguncian "pessimistic", tapi hal ini membutuhkan lebih banyak perhatian dari programmer. Dengan penguncian "optimistic", ADO mengunci record aktif hanya ketika sedang diupdate, yang biasanya membutuhkan sedikit waktu.
Penguncian "optimistic batch" adalah sebuah mode yang khusus yang tersedia hanya untuk cursor static di "client-side". Dalam penguncian "optimistic batch", Anda mengambil semua data pada mesin client, dan membiarkan user membentuk semua perubahan yang perlu (termasuk penambahan dan penghapusan record), dan lalu menyimpan kembali semua perubahan dalam satu operasi saja. Jika Anda memutuskan untuk menggunakan cursor "client-side", penguncian "optimistic batch" adalah mode yang paling efisien karena dia dapat mengurangi lalu-lintas di jaringan. Walau bagaimanapun, Anda akan perlu mengimplementasikan sebuah strategi untuk menangani konflik yang terjadi (sebagai contoh, ketika dua user meng-update record yang sama).
Membaca dan Memodifikasi Nilai Field
Kegunaan terakhir dalam pembukaan sebuah Recordset adalah untuk membaca nilai dari baris dan kolom dan memungkinkan untuk mengubahnya. Recordset membolehkan Anda untuk membaca dan menulis nilai pada record yang aktif, jadi Anda tidak perlu melakukan navigasi di seluruh Recordset untuk mengakses semua record yang Anda inginkan.
Anda dapat membaca nilai dari field dari record yang aktif melalui Field collection. Anda dapat memilih field yang mana yang akan diakses dengan melewatkan sebuah indeks atau nama field:
| Code:: |
'Cetak nama dan nilai dari semua fields dalam Recordset. Dim i As IntegerFor i = 0 To rs.Fields.Count - 1 'Fields collection dimulai dari 0 (nol). Print rs.Fields(i).Name & " = " & rs.Fields(i).Value Next |
Anda juga dapat menggunakan statement "For Each" untuk melakukan perulangan pada seluruh field yang ada. Anda dapat menghilangkan property Value karena nilai ini adalah property default untuk object Field.
| Code:: |
Dim fld As ADODB.Field For Each fld In rs.Fields Print fld.Name & " = " & fld Next |
Tidak seperti DAO dan RDO, ADO tidak mendukung method Edit, dan Anda dapat memulai mengedit satu atau lebih field dari record yang aktif dengan cara meng-assign nilai baru ke object Field yang Anda inginkan untuk diganti. Lebih dari itu, Anda tidak perlu secara eksplisit menggunakan method Update karena ADO akan otomatis mengeksekusinya ke Anda ketika Anda menggerakkan cursor ke record lainnya di Recordset. Fitur-fitur inilah yang membuat struktur dari code lebih sederhana untuk membaca sekaligus mengupdate semua record di dalam Recordset:
| Code:: |
'Mengkonversi isi field LastName ke huruf besar. rs.MoveFirst Do Until rs.EOF rs("LastName") = UCase$(rs("LastName")) rs.MoveNext Loop |
Anda dapat memeriksa status pengeditan sebuah Recordset dengan meng-query property EditMode nya, yang akan mengembalikan salah satu dari nilai berikut ini:
| Value (Nilai) | Deskripsi |
| 0-adEditNone | Tidak ada pengeditan pada proses kemajuan yang ada. |
| 1-adEditInProgress | Satu atau lebih field telah dimodifikasi, tapi nilai yang baru belum disimpan. |
| 2-adEditAdd | Sebuah record baru telah ditambahkan, tapi belum disimpan ke database. |
| 3-adEditDelete | Record yang aktif telah dihapus. |
Kembali
Mengeset dan Mengambil Posisi di Recordset
Sejumlah property membantu Anda untuk memahami di posisi mana Anda berada dalam Recordset, jadi Anda dapat mengaktifkan atau menonaktifkan operasi tertentu atau mengeset bookmarks untuk dengan cepat kembali ke sebuah record yang telah Anda kunjungi sebelumnya. Property di dalam kelompok ini yang mungkin akan Anda gunakan lebih sering adalah EOF, yang akan mengembalikan "True" jika pointer menunjuk ke record aktif yang posisinya setelah akhir dari Recordset. Anda biasanya menggunakan property ini ketika melakukan perulangan (looping) pada semua record dalam suatu Recordset:
| Code:: |
'Menghitung semua karyawan yang digaji sebelum 1 Januari 1994. Dim count As Integer count = 0 rs.MoveFirstDo Until rs.EOF If rs("HireDate") < #1/1/1994# Then count = count + 1 rs.MoveNext Loop |
Property BOF sama dengan EOF. BOF mengembalikan "True" jika pointer record berada pada posisi sebelum awal dari Recordset. Hal ini sering penting sekali untuk mengetahui nilai property EOF dan BOF: ketika keduanya mengembalikan True, semua method Recordset dan property akan mengembalikan sebuah error karena tidak ada record. Sebagai contoh, Anda tidak dapat mengambil sebuah nilai Field jika record yang aktif berada sebelum awal atau setelah akhir dari sebuah Recordset. Jika kedua property BOF dan EOF bernilai "True", Recordset tersebut berarti kosong.
Property Bookmark dapat membuat Anda mengambil sebuah nilai bertipe Variant yang menandai pada record yang aktif; Anda dapat kembali lagi nanti ke record ini secara mudah, dengan meng-assign nilai yang sama ke property Bookmark, seperti yang ditunjukkan pada coding berikut:
| Code:: |
Dim mark As Variantmark = rs.Bookmark 'Ingat di mana Anda berada. rs.MoveLast 'Pindahkan pointer ke record terakhir. rs("HireDate") = #12/10/1994# 'Assign sebuah nilai baru ke field HireDate. rs.Bookmark = mark 'Lalu kembali lagi ke record yang ditandai. |
Bookmark ADO disimpan sebagai nilai bertipe "Double". Walaupun jika nilai mereka bertipe "Numerik", Anda seharusnya tidak mengasumsikan bahwa Anda dapat membandingkan mereka seperti jika mereka adalah angka. Operasi aritmetika yang cocok dengan bookmark adalah sebuah pemeriksaan apakah sama, seperti yang ditunjukkan pada coding berikut ini:
| Code:: |
'Cetak nama karyawan yang digaji pada tanggal yang sama 'atau lebih besar pada record dalam Recordset. Dim mark As Double, curHireDate As Date mark = rs.Bookmark: curHireDate = rs("HireDate") rs.MoveFirst Do Until rs.EOF If rs.Bookmark <> mark Then 'Tidak mempertimbangkan karyawan yang sudah ada. If rs("HireDate") >= curHireDate Then Print rs("LastName") End If rs.MoveNext Loop 'Pindahkan pointer record kembali ke record yang ada. rs.Bookmark = mark |
Belakangan, bookmark dapat dibandingkan untuk persamaan hanya jika mereka berasal dari object Recordset yang sama atau berasal dari Recordset yang di-clone. (Lihat penjelasan pada method Clone pada bagian selanjutnya. Dalam banyak hal, Anda tidak seharusnya membandingkan property Bookmark dari dua object Recordset yang nyata, walaupun jika mereka menunjuk kepada baris yang sama di database. Untuk informasi lebih jauh tentang perbandingan bookmarks, lihat pada deskripsi method CompareBookmarks di bagian "Navigating the Recordset" di bawah.
Property "read-only" yang bernama RecordCount mengembalikan jumlah record yang ada di suatu Recordset. Tergantung pada mesin database, provider, dan tipe dari Recordset, property ini dapat juga mengembalikan nilai -1 (minus satu). Property ini tidak didukung oleh Recordset yang "forward-only", sebagai contoh. Jika property ini didukung, pembacaan nilainya memaksa ADO membentuk sebuah method MoveLast secara implisit, jadi operasi ini dapat menambah banyak manfaat jika digunakan dengan Recordset yang besar.
Property AbsolutePosition mengeset atau mengembalikan nilai bertipe Long yang memberitahukan tentang posisi/nomor urut dari record yang aktif di dalam Recordset. (Record pertama mengembalikan 1; record terakhir mengembalikan RecordCount). Property ini juga dapat mengembalikan satu dari nilai berikut: "-1-adPosUnknown" untuk posisi yang tidak diketahui, "-2-adPosBOF" (untuk kondisi BOF), atau "-3-adPosEOF" (untuk kondisi EOF).
Anda seharusnya tidak pernah menggunakan property ini untuk mengambil jumlah record, atau, yang lebih buruk lagi, menggantikan property Bookmark, karena property AbsolutePosition bervariasi ketika record ditambahkan atau dihapus dari Recordset. Alasan utama untuk menggunakan property ini adalah ketika Anda akan menggunakan sebuah scroll-bar atau sebuah control Slider untuk memberitahukan dengan cepat kepada user akan pergerakan kursor di Recordset. Dalam hal ini, Anda harus mengeset nilai Min scroll-bar ke 1 dan nilai maksimal ke property rs.RecordCount kemudian menambahkan coding ini pada event procedure Change atau Scroll milik Scroll-bar tadi:
| Code:: |
Private Sub HScrollBar1_Change() On Error Resume Next rs.AbsolutePosition = HScrollBar1.Value End Sub |
Ingat bahwa nilai Max tidak boleh lebih tinggi dari 32.767; jika Anda ingin agar dapat mengatasi jumlah record di atas nilai tersebut, sebaiknya Anda menggunakan skala nilai ata dengan menggunakan control Slider.
Setiap Recordset dibagi ke dalam halaman-halaman (pages), dan setiap page dapat terdiri dari sejumlah record yang tetap (kecuali halaman terakhir, bisa hanya sebagian dari jumlah record yang tetap tadi). Property PageSize mengembalikan jumlah record di setiap page, sedangkan property PageCount mengembalikan jumlah halaman di Recordset. Property AbsolutePage mengeset atau mengembalikan nomor halaman dari record yang aktif. Property ini secara konsep sama dengan property AbsolutePosition (dan mendukung nilai yang sama untuk menandai kondisi yang tidak diketahui, BOF, dan EOF), tapi berfungsi dengan jumlah halaman menggantikan jumlah record. Hal ini berguna ketika Anda sedang mencoba menerapkan strategi untuk mengambil jumlah record yang sedang dibaca dari database.
Mengurutkan dan Menyaring Record
Anda dapat mengurutkan record di suatu Recordset dengan meng-assign sebuah daftar field ke dalam property Sort, seperti yang akan ditunjukkan pada contoh berikut:
| Code:: |
'Menyortir Recordset pada field LastName dan FirstName. rs.Sort = "LastName, FirstName" |
Nama field pertama adalah kunci utama dalam pengurutan, nama field yang kedua adalah kunci pengurutan yang kedua, dan seterusnya. Secara default, record yang diurutkan akan disortir secara urutan Ascending untuk kunci yang dipilih; walaupun demikian, Anda dapat memilih agar pengurutan record dilakukan secara Descending, dengan menggunakan kata DESC:
| Code:: |
'Urutkan secara descending pada field HireDate field. '(Pegawai yang digaji terakhir akan berada pada urutan teratas) rs.Sort = "HireDate DESC" |
Dokumentasi secara tidak tepat menyatakan bahwa Anda seharusnya menggunakan kata ASCENDING dan DESCENDING. Hal ini dapat menghasilkan error 3001. Error ini mungkin akan dapat diperbaiki pada versi ADO berikutnya.
Property ini tidak memberi dampak pada urutan dari record yang terdapat di data source, tapi akan memberi dampak pada record di Recordset. Anda dapat mengembalikan urutan yang sebenarnya dengan meng-assign sebuah string kosong ke property ini. Belajar dari pengalaman saya, method Sort berfungsi hanya pada cursor static di "client-side", dan akhirnya dengan OLE DB providers untuk ODBC, Microsoft Jet, dan SQL Server. Jika Anda mengurutkan pada field yang tidak diindeks, ADO membuat sebuah indeks sementara untuknya dan menghapus indeks tersebut ketika Recordset ditutup atau di-assign ke string kosong pada property Sort.
Anda dapat menyaring (filter) record-record di dalam sebuah Recordset dengan menggunakan property Filter. Anda dapat meng-assign tiga tipe dari nilai untuk property ini: Sebuah string query SQL, sebuah array dari bookmarks, atau sebuah konstanta yang menandai record yang mana yang seharusnya muncul pada Recordset. Cara yang paling sering digunakan untuk property ini adalah dengan meng-assign kepadanya sebuah string SQL. String ini sama dengan klause WHERE dari perintah SELECT, tapi Anda harus menghilangkan kata WHERE-nya. Beberapa contoh ditunjukkan di bawah ini:
| Code:: |
'Saring semua pegawai yang digaji sebelum tanggal 1 Januari 1994. rs.Filter = "HireDate >= #1/1/1994#" 'Termasuk hanya pegawai yang lahir sekitar tahun 1960. rs.Filter = "birthdate >= #1/1/1960# AND birthdate < #1/1/1970#" 'Saring pegawai yang hanya mempunyai nama akhir dimulai dengan huruf C. rs.Filter = "LastName LIKE 'C*'" |
Anda dapat menggunakan operator perbandingan (<, <=, >, >=, =, <>) dan operator LIKE, yang mendukung wildcard * dan %, tapi hanya pada akhir dari argumen string. Anda dapat menghubungkan statement menjadi lebih sederhana dengan menggunakan operator logika AND dan OR, tapi Anda tidak dapat membentuk operasi lainnya (seperti penggabungan string). Anda dapat mengelompokkan eksprsisi menjadi lebih sederhana dengan menggunakan tanda kurung. Jika sebuah nama field mengandung spasi, Anda harus mengapit nama field tersebut dengan tanda kurung siku ([]). Anda dapat menggunakan property Filter dalam hal ini dengan cursor di "server-side" jika provider mendukung filter; dalam hampir semua hal, Anda harus menggunakan cursor di "client-side". Karena ADO membentuk filter, Anda harus bergantung pada peraturan sintaks di ADO; sebagai contoh, nilai tanggal harus diapit karakter #, string harus ditutup dengan tanda petik tunggal (''), dan string yang mengandung string tunggal harus diapit oleh tanda petik ganda (""). (Berikut ini ada suatu tip: Gunakan fungsi Replace untuk menyiapkan string dengan cepat).
Jika Anda ingin mem-filter sekelompok record yang tidak dapat dispesifikasikan dengan menggunakan string SQL, Anda dapat melewatkan sebuah array dari bookmarks (array of bookmarks) pada property bookmarks:
| Code:: |
'Saring pegawai yang digaji ketika mereka berusia di atas 35. ReDim marks(1 To 100) As Variant Dim count As Long 'Siapkan array of bookmarks. (Asumsikan bahwa 100 bookmarks sudah cukup) Do Until rs.EOF If Year(rs("HireDate")) - Year(rs("BirthDate")) > 35 Then count = count + 1 marks(count) = rs.Bookmark End If rs.MoveNext Loop 'Paksa filter yang baru menggunakan array of bookmarks. ReDim Preserve marks(1 To count) As Variant rs.Filter = marks |
Akhirnya, Anda dapat meng-assign property Filter dengan salah satu dari konstanta berikut ini:
| Value (Nilai) | Deskripsi |
| 0-adFilterNone | Tidak ada pengeditan pada proses kemajuan yang ada. |
| 1-adFilterPendingRecords | Dalam mode UpdateBatch, tampilkan hanya record yang telah dimodifikasi tapi belum dikirim ke server. |
| 2-adFilterAffectedRecords | Tampilkan record yang telah dihapus (Delete) diresinkronkan (Resync) telah disimpan (UpdateBatch), atau yang telah dibatalkan (CancelBatch). |
| 3-adFilterFetchedRecords | Tampilkan hanya record yang disimpan di tempat penyimpanan (cache) lokal. |
| 5-adFilterConflictingRecords | Dalam mode UpdateBatch, tampilkan hanya record yang gagal disimpan ke server. |
Setting property Filter ke nilai "2-adFilterAffectedRecords" adalah satu-satunya cara untuk melihat record yang telah dihapus.
Property MarshalOption berdampak pada bagimana Anda mengirim kembali record-record ke server. Property ini dapat di-assign oleh dua nilai konstanta, yaitu: "0-adMarshalAll" (ADO mengirim semua record ke server, dan ini merupakan default-nya) atau "1-adMarshalModifiedOnly" (ADO mengirim hanya record-record yang telah dimodifikasi). Property ini tersedia hanya pada "client-side" ADO Recordset.
Properfty Status adalah sebuah nilai bit field yang mengembalikan status dari record aktif setelah sebuah operasi UpdateBatch dilakukan kepadanya atau operasi besar lainnya telah selesai dilaksanakan. Anda dapat mencoba bits secara terpisah dengan menggunakan property enumerasi yang ada pada tabel berikut ini.
| Konstanta | Value (Nilai) | Deskripsi |
| adRecOK | 0 | Record sukses diupdate (disimpan). |
| adRecNew | 1 | Record adalah record baru. |
| adRecModified | 2 | Record telah dimodifikasi (berubah). |
| adRecDeleted | 4 | Record telah dihapus. |
| adRecUnmodified | 8 | Record belum dimodifikasi. |
| adRecInvalid | &h50 | Record belum disimpan karena bookmark tidak valid. |
| adRecMultipleChanges | &h50 | Record belum disimpan karena akan berpengaruh terhadap banyak record. |
| adRecPendingChanges | &H80 | Record belum disimpan karena merefer kepada pembatalan insert. |
| adRecCanceled | &h500 | Record belum disimpan karena operasi dibatalkan. |
| adRecCanRelease | &h500 | Record belum disimpan karena record yang bertalian sedang dikunci. |
| adRecConcurrencyViolation | &H800 | Record belum disimpan karena optimistic concurrency sedang digunakan. |
| adRecIntegrityViolation | &h5000 | Record belum disimpan karena akan mengakibatkan adanya kendala dalam integritas data. |
| adRecMaxChangesExceeded | &h5000 | Record belum disimpan karena terlalu banyak pembatalan. |
| adRecObjectOpen | &h5000 | Record belum disimpan karena adanya konflik dengan sebuah object penyimpanan (file) yang sedang terbuka. |
| adRecOutOfMemory | &H8000 | Record belum disimpan karena adanya error kehabisan memory. |
| adRecPermissionDenied | &h50000 | Record belum disimpan karena hak user dibatasi. |
| adRecSchemaViolation | &h50000 | Record belum disimpan karena tidak cocok dengan struktur database. |
| adRecDBDeleted | &h50000 | Record telah dihapus dari database. |
Object Recordset mempunyai beberapa method. Lagi, kita akan menjelaskannya dengan mengelompokkan berdasarkan kegunaannya.
Jika Anda ingin membaca data dalam sebuah Recordset, Anda harus membukanya terlebih dulu, dengan menggunakan method Open:
| Code:: |
Open [Source], [ActiveConnection], [CursorType], [LockType], [Options] |
Argumen dari method Open mempunyai arti yang sama dengan nama property-nya: "Source" adalah nama sebuah tabel atau sebuah "stored-procedure", sebuah query SQL, atau sebuah referensi ke object ADO Command; "ActiveConnection" adalah referensi ke sebuah object ADO Connection atau sebuah ConnectionString yang menandakan provider dan data source; "CursorType" menspesifikasikan tipe yang mana cursor yang akan dibuat (forward-only, static, keyset, atau dynamic); dan "LockType" adalah tipe dari penguncian yang Anda inginkan (read-only, pessimistic, optimistic, atau optimistic batch). "Options" adalah satu-satunya argumen yang tidak mempunyai hubungan kepada sebuah property Recordset: Ini menjelaskan ke ADO bahwa Anda melewatkan dalam argumen Source dan dapat merupakan salah satu dari konstanta enumerasi berikut:
| Value (Nilai) | Deskripsi |
| 1-adCmdText | Teks query SQL. |
| 2-adCmdTable | Tabel milik database. |
| 4-adCmdStoredProc | Merupakan stored procedure. |
| 8-adCmdUnknown | Tidak dispesifikasikan; provider-lah yang akan memeriksa tipe yang sesuai atau yang cocok. |
| 256-adCmdFile | Sebuah Recordset yang bersifat tetap. |
| 512-adCmdTableDirect | Sebuah tabel database yang dibuka langsung. |
Walaupun secara umum provider dapat memahami source apa dari Recordset tanpa bantuan dari Anda, Anda dapat mempercepat method Open dengan meng-assign sebuah nilai yang benar pada argumen ini.
Semua argumen ini bersifat optional. Walau demikian, ADO tidak dapat membuka Recordset jika Anda tidak menyediakan informasi yang cukup. Sebagai contoh, Anda dapat menghapus argumen "Source" jika Anda telah meng-assign sebuah nilai ke dalam property Source, dan Anda dapat menghapus argumen ActiveConnection jika Anda telah meng-assign sebuah nilai ke dalam property ActiveConnection atau jika Anda menggunakan object ADO Command sebagai source dari Recordset ini (yang dalam hal ini argumen ActiveConnection diturunkan dari object Command). Jika Anda menghapus argumen yang ketiga atau yang keempat, secara default, method Open akan membuat sebuah cursor yang bertipe "forward-only", Recordset dengan penguncian record yang bertipe "read-only", yang merupakan tipe paling efisien yang didukung oleh ADO. Anda tidak dapat memilih posisi cursor dalam method Open, dan jika Anda akan membuat sebuah cursor di "client-side", Anda harus meng-assign konstanta "adUseClient" ke property "CursorLocation" sebelum membuka Recordset tersebut. Di bawah ini beberapa contoh yang akan menunjukkan method Open:
| Code:: |
'Sesuaikan dengan direktori di PC Anda. Const DBPATH = "C:\Program Files\Microsoft Visual Studio\VB98\NWind.mdb" 'Semua contoh ini menggunakan variabel berikut. Dim cn As New ADODB.Connection, rs As New ADODB.Recordset Dim connString As String, sql As String connString = "Provider=Microsoft.Jet.OLEDB.3.51;Data Source=" & DBPATH 'Buka Recordset dengan menggunakan object Connection yang ada. cn.Open connString rs.Open "Employees", cn, adOpenStatic, adLockReadOnly, adCmdTable 'Buka Recordset menggunakan sebuah object Connection yang dibuat saat run-time. 'Ini membuat cursor "forward-only", dan Recordset yang "read-only". rs.Open "Employees", connString, , , adCmdTable 'Setelah Recordset dibuka, Anda dapat meng-query properties 'dari object Connection secara implisit. Print "Current Connection String = " & rs.ActiveConnection.ConnectionString 'Pilih hanya pegawai yang dilahirkan pada sekitar tahun 1960 ke atas. sql = "SELECT * FROM Employees WHERE BirthDate >= #1/1/1960#" rs.Open sql, connString, , , adCmdText |
Anda juga dapat membuka sebuah Recordset yang sebelumnya telah disimpan ke sebuah file di disk menggunakan method Save: Dalam hal ini, argumen pertama dari method Open adalah nama lengkap file (beserta direktorinya), dan Anda harus melewatkan konstanta adCmdFile ke argumen "Options".
Argumen "Options" mendukung dua atau lebih konstanta untuk operasi "asynchronous". Nilai yang "16-adAsyncExecute" mengeksekusi query secara "asynchronously": Control langsung kembali ke aplikasi, dan ADO melanjutkan mengambil Recordset sampai tempat penyimpanan lokal (local cache) diisi dengan data. Nilai "32-adAsyncFetch" memberitahukan ADO bahwa setelah mengisi local cache dengan data, ADO seharusnya mengambil record-record yang sisa secara "asynchronously". Ketika semua record telah diambil, ADO menghasilkan sebuah event FetchComplete.
Anda dapat membatalkan operasi "asynchronous" kapanpun dengan membangkitkan sebuah method Cancel. Jika tidak ada operasi "asynchronous" dibatalkan, method ini tidak melakukan apapun dan tidak ada error yang ditimbulkan.
Ketika Anda telah selesai dengan sebuah Recordset, seharusnya Anda menutupnya dengan menggunakan method Close. Method ini tidak mempunyai argumen. ADO secara otomatis menutup sebuah Recordset ketika tidak ada variabel yang menunjuk kepadanya. Ketika sebuah Recordset ditutup, ADO membebaskan semua penguncian dan memory yang dialokasikan kepada cursor-nya (jika ada). Anda tidak dapat menutup sebuah Recordset jika sebuah operasi Edit sedang berlangsung (misalnya jika Anda telah memodifikasi nilai dari satu atau lebih field dan belum menyimpan perubahan). Anda dapat membuka kembali sebuah Recordset yang telah ditutup dengan menggunakan nilai yang sama atau yang lain untuk property Source, CursorType, MaxRecords, CursorLocation, dan LockType. (Property ini bersifat "read-only" ketika Recordset terbuka).
Anda dapat membuat sebuah Recordset dengan menggunakan method Clone untuk membuat sebuah salinan dari Recordset yang sudah ada:
| Code:: |
Dim rs2 As ADODB.Recordset Set rs2 = rs.Clone(LockType) |
Argumen optional "LockType" memberitahukan tipe penguncian mana yang Anda akan lakukan terhadap Recordset yang baru. Record yang di-cloned dapat dibuka hanya dengan tipe penguncian yang sama dengan record aslinya (dalam hal ini, Anda hanya menghapus argumen-nya) atau dalam mode "read-only" (Anda melewatkan konstanta "adLockReadOnly"). Meng-clone sebuah Recordset lebih efisien daripada membuat Recordset yang lain untuk data source yang sama. Modifikasi apapun terhadap nilai di suatu Recordset secara langsung kelihatan kepada semua hasil clone-nya tanpa memperhatikan tipe cursor mereka, tapi semua Recordset yang berada dalam satu kelompok dapat di-scroll dan ditutup terpisah satu dengan lainnya. Jika Anda memakai sebuah method Requery berlawanan dengan Recordset aslinya, clones-nya tidak akan sinkron lagi. (Lawannya tidak true, walaupun: jika Anda meng-Requery clones, mereka tetap di-sinkron-kan dengan Recordset aslinya). Ingatlah bahwa hanya Recordset yang didukung oleh Bookmarks yang dapat di-cloned dan Anda dapat membandingkan bookmarks yang didefinisikan dalam sebuah Recordset dan hasil clones-nya.
Me-Refresh Recordset
ADO menyediakan dua method untuk menghasilkan kembai sebuah Recordset tanpa harus menutup dan membuka ulang kembali. Method Requery mengeksekusi kembali query Recordset. Method ini khususnya beguna dengan query yang memiliki parameter berlawanan dengan SQL Server databae ketika Anda tidak sedang menggunakan sebuah object Command karena dia memberitahukan ADO untuk menggunakan kembali tempat penyimpanan yang menyimpan procedure yang dibuat oleh SQL Server ketika Recordset dibuka pertama kali. Method Requery mengabulkan pilihan "adAsyncExecute" untuk menjalankan query secara "asynchronously". Ketika query telah selesai, sebuah event RecordsetChangeComplete akan dibangkitkan. Method Requery membiarkan Anda mengeksekusi ulang query, tapi Anda tidak dapat memodifikasi property apapun yang membawa efek pada tipe cursor (CursorType, CursorLocation, LockType, dan sebagainya) karena property-property ini bersifat "read-only" ketika Recordset sedang terbuka. Untuk mengganti property-property ini, Anda harus menutup dahulu dan membuka kembali Recordset tersebut.
Method Resync me-refresh Recordset dari "underlying database" tanpa sebenarnya mengeksekusi kembali query tersebut. Sintaks-nya adalah sebagai berikut:
| Code:: |
Resync [AffectRecords], [ResyncValues] |
AffectRecords memberitahukan record yang mana seharusnya di-refresh dan dapat berupa salah satu dari konstanta berikut ini:
| Value (Nilai) | Deskripsi |
| 1-adAffectCurrent | Me-refresh record yang aktif saja. |
| 2-adAffectGroup | Me-refresh record-record yang memenuhi property Filter yang ada, yang seharusnya telah di-assign oleh salah satu dari konstanta enumerasi. |
| 3-adAffectAll | Me-refresh seluruh record (Default). |
Nilai ResyncValues dapat berupa salah satu nilai berikut ini:
| Value (Nilai) | Deskripsi |
| 1-adResyncUnderlyingValues | Membaca nilai-nilai yang terbaru dari database dan menempatkannya pada property UnderlyingValue dari object Field. |
| 2-adResyncAllValues | Membaca nilai-nilai yang terbaru dari database dan menempatkannya pada property object Field (Default). |
Efek dari kedua pilihan ini sangat berbeda: "adResyncUnderlyingValues" melindungi data yang lama dan tidak membatalkan perubahan; "adResyncAllValues" membatalkan perubahan (seperti jika sebuah method CancelBath telah dibangkitkan).
Karena method Resync tidak mengeksekusi ulang query yang ada, Anda tidak akan pernah melihat record baru ditambahkan oleh user lain pada saat itu. Method ini khususnya berguna dengan cursor "forward-only" atau "static" ketika Anda akan meyakinkan Anda sedang bekerja dengan nilai-nilai yang terbaru. Konflik apapun yang terjadi selama proses "resynchronization", sebagai contoh, user lain telah menghapus sebuah record, akan mengisi Error collection dengan satu atau lebih pesan peringatan. Ketika menggunakan cursor di "client-side", method ini tersedia hanya untuk Recordset yang dapat diupdate.
Untuk membaca nilai-nilai dari record yang ada, dengan mudah Anda mengambil Field collection seperti yang ditunjukkan di bawah:
| Code:: |
'Cetak nama awal dan akhir karyawan.Print rs.Fields("FirstName").Value, rs.Fields("LastName").Value |
Karena Field adalah property default untuk object Recordset, Anda dapat menghapusnya dan mengakses field dengan menggunakan namanya atau indeksnya. Sama dengan hal ini, Anda dapat menghapus property Value karena merupakan anggota (member) default-nya dari object Field:
| Code:: |
Print rs("FirstName"), rs("LastName") |
Anda menampilkan nilai dari semua field pada record yang ada dengan melakukan perulangan (loop) pada Field collections. Anda dapat menggunakan indeks Field dalam sebuah loop "For... Next" atau sebuah variabel object Field dalam loop "For Each ... Next":
| Code:: |
'Cara pertama, menggunakan looping biasa: "For ... Next" For i = 0 To rs.Fields.Count _ 1 Print rs.Fields(i).Name & " = " & rs(i) Next 'Cara kedua, menggunakan loop "For Each ... Next" Dim fld As ADODB.Field For Each fld In rs.Fields Print fld.Name & " = " & fld.Value Next |
ADO juga menawarkan cara-cara yang lebih efisien untuk mengambil data. Method GetRows mengembalikan sebuah array "dua-dimensi" yang bertipe Variant, di mana setiap kolom mewakili sebuah record di Recordset dan setiap baris mewakili sebuah field di record. Method ini mempunyai sintaks sebagai berikut:
| Code:: |
varArray = rs.GetRows([Rows], [Start], [Fields]) |
"Rows" adalah jumlah record yang akan Anda baca; gunakan -1 atau hapus argumen ini jika Anda ingin mengambil semua record dalam Recordset. "Start" adalah sebuah bookmark yang menandai record pertama dibaca; dan dapat juga berupa salah satu dari konstanta enumarasi: "0-adBookmarkCurrent" (record aktif), "1-adBookmarkFirst" (record pertama), atau "2-adBookmarkLast" (record terakhir).
"Fields" adalah sebuah array dari nama field yang menyajikan sejumlah data yang dibaca. Anda juga dapat memilih sebuah nama field, sebuah field yang diindeks, atau sebuah array dari field yang diindeks). Ketika Anda mengeset "Rows" ke sebuah nilai yang lebih kecil dari jumlah record di Recordset, record pertama yang tidak dapat dibaca berasal dari record yang aktif. Jika Anda menghapus argumen "Rows" atau mengesetnya menjadi "-1-adGetRowsRest" atau ke nilai yang lebih besar dari jumlah record yang tetap tidak dapat dibaca, method GetRows membaca semua record dan meninggalkan Recordset pada kondisi EOF, tanpa menimbulkan error.
Ketika memproses data di array Variant, Anda harus mengingat bahwa data yang disimpan dapat ditandai. Subscript pertama di array menandakan field Recordset (yang biasanya dikira sebagai sebuah kolom), dan subscript kedua menandai record Recordset (yang biasanya dikira sebagai sebuah baris). Berikut ini contoh yang memuat tiga field dari semua record di suatu Recordset:
| Code:: |
Dim values As Variant, fldIndex As Integer, recIndex As Integer values = rs.GetRows(, , Array("LastName", "FirstName", "BirthDate")) For recIndex = 0 To UBound(values, 2) For fldIndex = 0 To UBound(values) Print values(fldIndex, recIndex), Next Print Next |
Method GetRows biasanya dapat lebih cepat daripada sebuah loop secara eksplisit yang membaca satu record pada satu waktu, tapi jika Anda menggunakan method ini, Anda harus meyakinkan bahwa Recordset tidak mengandung terlalu banyak record; sebaliknya, Anda dapat dengan mudah mengisi semua physical memory dengan sebuah array Variant yang sangat besar. Untuk alasan yang sama, berhati-hatilah untuk tidak memasukkan field "Object Binary yang Besar" (BLOB=Binary Large Object) atau "Object Karakter yang Besar" (CLOB=Character Large Object) di dalam daftar field; jika Anda melakukan, aplikasi Anda akan menjadi bom, khususnya dengan Recordset yang lebih besar. Akhirnya, ingatlah bahwa array Variant akan dikembalikan oleh method ini berbasis nol; jumlah record yang dikembalikan adalah UBound(nilai,2)+1, dan jumlah field yang dikembalikan adalah UBound(nilai,1)+1.
Method GetString sama dengan GetRows, tapi GetString mengembalikan banyak record sebagai sebuah string tunggal. GetString mempunyai sintaks seperti berikut:
| Code:: |
GetString([Format], [NumRows], [ColDelimiter], [RowDelimiter], [NullExpr]) |
"Format" adalah format untuk hasil. GetString berpotensial mendukung lebih banyak format, tapi hanya format yang didukung adalah "2-adClipString", jadi Anda tidak benar-benar memilih pilihan apapun. NumRows adalah jumlah baris yang diambil. (Gunakan -1 atau hapus argumen ini untuk membaca semua record yang sisa). ColDelimiter adalah karakter pemisah untuk kolom. (Default-nya adalah karakter Tab). RowDelimiter adalah karakter pemisah untuk record. (Default-nya adalah enter). NullExpr adalah string yang biasa digunakan untuk field bernilai Null. (Default-nya adalah string kosong). Dokumentasi menyatakan bahwa tiga argumen terakhir dapat digunakan hanya jika Format="adClipString". Berikut sebuah contoh yang menggunakan method GetString untuk mengekspor data dalam sebuah file teks:
| Code:: |
Dim i As Long Open "datafile.txt" For Output As #1For i = 0 To rs.Fields.Count - 1 'Export nama field. If i > 0 Then Print #1, ";"; Print #1, rs.Fields(i).Name; Next Print #1, ""rs.MoveFirst 'Export data. Print #1, rs.GetString(, , ";", vbCrLf); 'Jangan tambahkan CR-LF tambahan di sini. Close #1 |
Method GetString tidak mengizinkan Anda untuk mengekspor hanya sebuah subset dari field, juga tidak mengizinkan Anda untuk memodifikasi urutan dari field yang diekspor. Jika Anda perlu kemampuan tambahan ini, Anda harus menggunakan method GetRows dan membangun hasil string-nya sendiri.
Navigasi Recordset
Ketika Anda membuka sebuah Recordset, penunjuk record akan berada pada record pertama, kecuali Recordset dalam keadaan kosong (di mana properties BOF dan EOF mengembalikan nilai True). Untuk membaca dan memodifikasi nilai di record lainnya, Anda harus membuat record tersebut sebagai record yang aktif, dan biasanya dilakukan dengan mengeksekusi salah satu dari method Movexxxx milik object Recordset. MoveFirst menggerakkan pointer ke record pertama di Recordset, MoveLast menggerakkan pointer ke record terakhir, MovePrevious menggerakkan pointer ke record sebelumnya, dan MoveNext menggerakkan pointer ke record berikutnya. Anda biasanya menyiapkan empat tombol bagi user untuk dapat melakukan navigasi Recordset. Ketika Anda mengeksekusi sebuah method MovePrevious dan BOF mengembalikan nilai True atau ketika Anda sedang mengeksekusi sebuah method MoveNext dan EOF mengembalikan nilai True, maka akan terjadi sebuah error; oleh karena itu Anda harus mengatasinya sebelum menuju record sebelum atau sesudahnya, dengan cara sebagai berikut:
| Code:: |
Private Sub cmdFirst_Click() rs.MoveFirst End Sub Private Sub cmdPrevious_Click() If Not rs.BOF Then rs.MovePrevious End Sub Private Sub cmdNext_Click() If Not rs.EOF Then rs.MoveNext End Sub Private Sub cmdLast_Click() rs.MoveLast End Sub |
Method MoveFirst dan MoveNext biasanya digunakan untuk melakukan perulangan di dalam suatu Recordset untuk mengakses semua record yang ada, seperti yang ditunjukkan pada contoh berikut ini:
| Code:: |
rs.MoveFirst Do Until rs.EOF total = total + rs("UnitsInStock") * rs("UnitPrice") rs.MoveNext Loop Print "Total UnitsInStock * UnitPrice = " & total |
ADO juga mendukung sebuah method umum bernama Move, dengan sintaks sebagai berikut:
| Code:: |
Move NumRecords, [Start] |
NumRecords adalah sebuah nilai yang bertipe Long dan merupakan jumlah record yang akan dilewatkan sampai selesai (jika positif) atau permulaan (jika negatif) dari Recordset. Perpindahan bersifat relatif ke record yang diidentifikasi oleh argumen Start, dan dapat berupa sebuah nilai bookmark dari salah satu konstanta berikut ini:
| Value (Nilai) | Deskripsi |
| 0-adBookmarkCurrent | Record yang aktif. |
| 1-adBookmarkFirst | Record pertama di Recordset. |
| 2-adBookmarkLast | Record terakhir di Recordset. |
Seperti yang Anda lihat di bawah ini, method Move merupakan "penjelmaan" dari keempat method Movexxxx. Kita telah membahasnya sebelum ini.
| Code:: |
rs.Move 0, adBookmarkFirst 'sama dengan MoveFirst rs.Move -1 'sama dengan MovePrevious rs.Move 1 'sama dengan MoveNext rs.Move 0, adBookmarkLast 'sama dengan MoveLast rs.Move 10, adBookmarkFirst 'menuju ke record yang kesepuluh rs.Move -1, adBookmarkLast 'menuju ke record berikutnya ke record terakhir rs.Move 0 'refresh record yang sedang aktif |
Jika Anda memberi nilai negatif yang menujuk ke sebuah record sebelum record pertama, property BOF menjadi bernilai True dan tidak ada error yang terjadi. Sama dengan jika Anda memberi nilai positif yang menunjuk ke sebuah record setelah record terakhir, property EOF diset ke nilai True dan juga tidak ada error yang terjadi. Menariknya, Anda dapat memilih sebuah nilai negatif walaupun dengan forward-only Recordset. Jika record tujuan masih berada dalam cache lokal, tidak ada error yang terjadi (Anda tidak dapat menggunakan MovePrevious dengan forward-only Recordset, terlepas dari apakah record sebelumnya berada di dalam cache.
Anda dapat juga melakukan navigasi terhadap sebuah Recordset dengan menggunakan property Bookmark dan AbsolutePosition. ADO juga menyediakan sebuah method CompareBookmarks yang membolehkan Anda melakukan perbandingan bookmark yang berasal dari Recordset yang sama, atau berasal dari sebuah Recordset yang di-cloned. Method ini memiliki sintaks sebagai berikut:
| Code:: |
result = CompareBookmarks(Bookmark1, Bookmark2) |
result dapat menerima salah satu dari nilai berikut:
| Value (Nilai) | Deskripsi |
| 0-adCompareLessThan | Bookmark pertama merefer kepada sebuah record yang mendahului record yang direfer oleh record kedua. |
| 1-adCompareEqual | Kedua bookmark menunjuk kepada record yang sama. |
| 2-adBookmarkGreaterThan | Bookmark pertama merefer kepada sebuah record yang mengikuti record yang direfer oleh record kedua. |
| 3-adCompareNotEqual | Kedua bookmark menunjuk kepada record yang berbeda, tapi Provider tidak dapat membedakan yang mana datang lebih dulu. |
| 4-adCompareNotComparable | Kedua bookmark tidak dapat dibandingkan |
Simpan, Tambah, dan Hapus Record
ADO berbeda dari DAO dan RDO dalam method Update. Yang harus Anda lakukan untuk melakukan perubahan terhadap sebuah record adalah dengan meng-assign sebuah nilai baru kepada satu atau lebih object Fields dan lalu pindah ke record lainnya. Update di ADO mendukung kemampuan untuk mengubah banyak field dalam satu kesempatan, dengan menggunakan sintaks berikut ini:
| Code:: |
Update [Fields] [,Values] |
Fields adalah sebuah nama field yang berisi sebuah data bertipe Variant, sebuah field yang memiliki indeks, atau sebuah array dari nama field atau dari indeks. Values adalah sebuah nilai tunggal yang mengandung sebuah data bertipe Variant atau sebuah array dari nilai-nilai. Kedua argumen ini bersifat opsional, tapi Anda tidak dapat menghilangkan hanya salah satu dari keduanya: Jika tersedia, keduanya harus terdiri dari jumlah argumen yang sama. Contoh berikut ini menunjukkan bagaimana Anda dapat meng-update banyak field dengan menggunakan sintaks sebagai berikut:
| Code:: |
'Update empat field dalam satu operasi rs.Update Array("FirstName", "LastName", "BirthDate", "HireDate"), _Array("John", "Smith", #1/1/1961#, #12/3/1994#) |
Karena sebuah operasi update otomatis terbentuk jika satu atau lebih field dalam record yang aktif telah dimodifikasi, ADO menyediakan method CancelMethod untuk membatalkan perubahan yang telah terjadi dan mengembalikan ke posisi sebelum terjadi perubahan. Anda dapat menggunakan method Update dan CancelUpdate bersamaan untuk menawarkan kepada user sebuah kesempatan untuk mengkonfirmasikan atau membatalkan perubahan yang terjadi pada record yang aktif:
| Code:: |
If rs.EditMode = adEditInProgress Then If MsgBox("Anda ingin menyimpan perubahan?", vbYesNo) = vbYes Then rs.Update Else rs.CancelUpdate End If End If |
Anda dapat menambah record baru ke suatu Recordset dengan menggunakan method AddNew. Method ini sama dengan method Update yang mendukung dua bentuk sintaks, dengan atau tanpa argumen. Jika Anda tidak melewatkan sebuah argumen, Anda membuat sebuah record baru pada akhir dari Recordset dan Anda melakukan sebuah assign nilai kepada field-nya dengan menggunakan Field Collection:
| Code:: |
rs.AddNewrs("FirstName") = "Robert" rs("LastName") = "Doe" rs("BirthDate") = #2/5/1955# rs.Update |
Anda tidak membutuhkan sebuah method Update secara eksplisit setelah sebuah method AddNew, karena method Movexxxx apapun dapat melakukannya. Dalam sintaks bentuk kedua, Anda melewatkan method AddNew sebuah daftar field dan sebuah daftar nilai; di mana dalam hal ini, tidak perlu menggunakan Update karena nilai-nilai tersebut langsung disimpan ke dalam database:
| Code:: |
'Statement ini mempunyai hasil yang sama seperti potongan code sebelumnya. rs.AddNew Array("FirstName", "LastName", "BirthDate"), _ Array("Robert", "Doe", #2/5/1955#) |
Setelah Anda menyimpan perubahan dengan method Update, record yang baru saja Anda tambahkan akan menjadi record yang aktif. Jika Anda menerbitkan sebuah method AddNew, Anda menyimpan perubahan secara otomatis ke record yang baru saja ditambahkan sebelumnya, seperti jika Anda telah melakukan eksekusi sebuah method Movexxxx. Tergantung dari tipe cursor, bisa saja record yang telah ditambahkan tidak langsung kelihatan di Recordset, sehingga Anda harus mengeksekusi sebuah method Requery untuk melihatnya.
Anda dapat menghapus record yang aktif dengan mengeksekusi method Delete. Method ini menerima sebuah argumen yang bersifat opsional:
| Code:: |
rs.Delete [AffectRecords] |
Jika AffectRecords bernilai "1-adAffectedCurrent" atau tidak ada, hanya record yang aktif saja yang dihapus. Ketika Anda menghapus sebuah record, pointer masih berada pada record yang dihapus tersebut, yang sebenarnya record tersebut tidak dapat diakses lagi, jadi Anda harus memindahkan pointer ke record lainnya:
| Code:: |
rs.Delete rs.MoveNext If rs.EOF Then rs.MoveLast |
Anda dapat menghapus sekumpulan record dengan meng-assign sebuah konstanta enumarasi ke dalam property Filter lalu membangkitkan sebuah method Delete dengan argumen AffectRecords diset ke "2-adAffectGroup":
| Code:: |
'Setelah mencoba sebuah Update Batch, hapus semua record yang gagal 'ditransfer ke server...rs.Filter = adFilterConflictingRecords rs.Delete adAffectGrouprs.Filter = adFilterNone 'hapus filter-nya |
Anda seharusnya melakukan percabangan operasi penghapusan dalam sebuah transaksi jika Anda ingin memberikan kesempatan ke user Anda untuk membatalkan penghapusan record tsb.
by : masino sinaga

2 komentar:
bisakah saya bertanya tentang pemrograman ASP classic kepada anda?
bisakah saya bertanya tentang pemrograman ASP classic kepada anda?
Posting Komentar