Access
 sql >> Teknologi Basis Data >  >> RDS >> Access

Sisipan Massal atau Perbarui untuk tabel dengan bidang Lampiran

Sejak Access 2010, Access telah mendukung tipe data Lampiran yang di permukaan tampak seperti fitur yang nyaman untuk menyimpan gambar atau file kecil. Namun, pencarian google cepat biasanya akan menunjukkan bahwa mereka sebaiknya dihindari. Ini semua bermuara pada fakta bahwa tipe data Lampiran sebenarnya adalah Bidang Multi-Nilai (MVF), dan ini datang dengan beberapa masalah. Pertama, Anda tidak akan dapat menggunakan kueri untuk menyisipkan atau memperbarui beberapa catatan sekaligus. Memang, setiap tabel yang berisi tipe data seperti itu memaksa Anda untuk melakukan banyak kode dan untuk alasan itu saja, kami menghindari penggunaan tipe data seperti itu secara normal.

Namun, ada masalah. Kami senang menggunakan galeri gambar dan tema, yang keduanya bergantung pada tabel sistem, MSysResources yang sayangnya menggunakan tipe data lampiran. Ini menimbulkan masalah untuk mengelola sumber daya di perpustakaan standar kami karena kami ingin menggunakan MSysResources tetapi kami tidak dapat dengan mudah memperbarui atau memasukkannya secara massal.

Jenis data lampiran (dan juga MVF) memaksa Anda untuk menggunakan pemrograman "baris demi baris" ketika berhadapan dengan bidang MVF, ini adalah twofer dengan bidang Lampiran karena Anda harus menggunakan LoadFromFile atau SaveToFile metode. Microsoft memiliki artikel dengan contoh tentang metode tersebut. Jadi, Anda harus berinteraksi dengan sistem file saat menambahkan catatan baru. Tidak selalu diinginkan dalam semua situasi. Sekarang, jika kita menyalin dari satu tabel ke tabel lain, kita dapat menghindari memantul pada sistem file dengan melakukan sesuatu seperti:

Redupkan SourceParentRs Sebagai DAO.Recordset2Dim SourceChildRs Sebagai DAO.Recordset2Dim TargetParentRs Sebagai DAO.Recordset2Dim TargetChildRs Sebagai DAO.Recordset2Dim SourceField As DAO.Field2Set SourceParentRs =db.OpenRecordset("FieldWithAttachment) ", dbOpenDynaset, dbAppendOnly)Lakukan Sampai SourceParentRs.EOF TargetParentRs.AddNew Untuk Setiap SourceField Di SourceParentRs.Fields Jika SourceField.Type <> dbAttachment Kemudian TargetParentRs.Fields(SourceField.Name).Value =SourceFieldRs.Value Target'Value Harus menyimpan catatan terlebih dahulu sebelum dapat mengedit bidang MVF TargetParentRs.Bookmark =TargetParentRs.LastModified Set SourceChildRs =SourceParentRs.Fields("Data").Value Set TargetChildRs =TargetParentRs.Fields("Data").Nilai Lakukan Hingga SourcechildRs.EOF TargetChildRs.AddNew Const ChunkSize Selama =32768 Dim TotalSize Selama Redup Offset Selama TotalSize =SourceChildRs.Fields(" FileData").FieldSize Offset =TotalSize Mod ChunkSize TargetChildRs.Fields("FileData").AppendChunk(SourceChildRs.GetChunk(0, Offset) Lakukan Hingga Offset> TotalSize TargetChildRs.Fields("FileData").AppendsetChunk(SourceChildRs.Off , ChunkSize) Offset =Offset + ChunkSize Loop TargetChildRs.Update SourceChildRs.MoveNext Loop TargetParentRs.Update SourceParentRs.MoveNextLoop

Perulangan suci, batman! Itu banyak kode, semua hanya untuk menyalin lampiran dari satu tabel ke tabel lainnya. Meskipun kami tidak terpental sistem file, itu juga sangat lambat. Berdasarkan pengalaman kami, tabel dengan 1000 catatan yang berisi satu lampiran dapat memakan waktu menit hanya untuk diproses. Sekarang, ini cukup besar jika Anda mempertimbangkan ukurannya. Meja dengan lampiran tidak terlalu besar. Bahkan, mari kita lakukan percobaan. Mari kita lihat apa yang terjadi jika saya menyalin dan menempel melalui lembar data:

Jadi menyalin dan menempel praktis seketika. Jelas kode yang digunakan dengan menempelkan bukan kode yang sama yang akan kita gunakan di VBA. Namun, kami sangat yakin bahwa jika kami dapat melakukannya secara interaktif, kami juga dapat melakukannya di VBA. Bisakah kita meniru kecepatan penempelan interaktif di VBA? Jawabannya ternyata ya, kita bisa!

Percepat dengan …. XML?

Anehnya metode yang menyediakan cara tercepat untuk menyalin data, termasuk lampiran adalah melalui file XML. Saya akui saya tidak meraih file XML kecuali sebagai solusi untuk batasan. Rata-rata, file XML relatif lambat untuk format file lain tetapi dalam kasus ini, XML memiliki satu keuntungan besar; tidak ada masalah dalam mendeskripsikan MVF. Mari buat file XML dan selidiki kemampuan yang kita dapatkan dengan mengimpor/mengekspor file XML.

Setelah dialog wizard ekspor biasa untuk mengatur jalur untuk menyimpan file XML, kita akan mendapatkan dialog seperti ini:

Jika kita kemudian mengklik tombol “More Option…”, kita mendapatkan dialog ini sebagai gantinya:

Dari dialog ini, kita melihat beberapa petunjuk lagi tentang apa yang mungkin; yaitu:

  • Kami memiliki opsi untuk mengekspor seluruh tabel atau hanya sebagian tabel dengan menerapkan filter
  • Kita dapat mengubah keluaran XML.
  • Kami dapat menjelaskan skema selain isi tabel.

Saya menemukan bahwa yang terbaik adalah menyematkan skema; defaultnya adalah mengekspornya tetapi sebagai file terpisah. Namun, itu bisa rawan kesalahan dan mereka bisa lupa menyertakan file XSD dengan file XML. Ini dapat diubah melalui tab skema yang ditampilkan:

Mari selesaikan ekspornya dan lihat sekilas data file XML yang dihasilkan.

Perhatikan bahwa lampiran dijelaskan dalam Data subtree dan konten file dikodekan base-64. Mari kita coba mengimpor file XML. Setelah melalui wizard impor, kita akan mendapatkan dialog ini:

Perhatikan fitur berikut:

  • Seperti halnya ekspor, kami memiliki opsi untuk mengubah XML.
  • Kami dapat mengontrol apakah akan mengimpor struktur, data, atau keduanya

Jika kami kemudian selesai mengimpor file XML, kami menemukan bahwa itu secepat operasi copy'n'paste yang kami lakukan.

Kami sekarang tahu ada cara yang lebih baik untuk menyalin beberapa catatan dengan lampiran. Namun dalam situasi ini, kami ingin melakukannya secara terprogram, bukan interaktif. Bisakah kita melakukan hal yang sama seperti yang baru saja kita lakukan? Sekali lagi jawabannya adalah ya. Ada beberapa cara untuk melakukan hal yang sama tetapi menurut saya metode yang paling mudah adalah dengan menggunakan 3 metode baru yang ditambahkan ke Application objek sejak Access 2010:

  • ExportXML metode
  • TransformXML metode
  • ImportXML metode

Perhatikan bahwa ExportXML metode mendukung ekspor dari berbagai objek. Namun, karena tujuannya di sini adalah untuk dapat menyalin atau memperbarui secara massal catatan tabel dengan bidang lampiran, tipe objek terbaik untuk kita gunakan adalah kueri tersimpan. Dengan kueri yang disimpan, kami dapat mengontrol baris mana yang harus dimasukkan atau diperbarui dan kami juga dapat membentuk output. Jika Anda melihat desain skema MSysResources tabel di bawah ini:

Ada masalah potensial. Setiap kali kami menggunakan tema atau gambar, kami merujuk item berdasarkan nama, bukan ID. Namun, Name kolom tidak unik dan bukan kunci utama tabel. Oleh karena itu, ketika kami menambah atau memperbarui catatan, kami ingin mencocokkan pada Name kolom, bukan Id kolom. Ini berarti ketika kita mengekspor, kita mungkin tidak boleh menyertakan Id kolom dan kita harus mengekspor hanya daftar unik Name untuk memastikan sumber daya tidak tiba-tiba berubah dari "Open.png" menjadi "Close.png" atau sesuatu yang konyol.

Kami kemudian akan membuat kueri untuk bertindak sebagai sumber rekaman yang ingin kami impor ke MSysResources meja. Mari kita mulai dengan SQL ini hanya untuk mendemonstrasikan pemfilteran ke subset record:

SELECT e.Data, e.Extension, e.Name, e.TypeFROM Example AS eWHERE e.Name In ("blue","red","green");

Kami kemudian akan menyimpannya sebagai qryResourcesExport . Kami kemudian dapat menulis kode VBA untuk mengekspor XML:

Application.ExportXML _ ObjectType:=acExportQuery, _ DataSource:="qryResourcesExport", _ DataTarget:="C:\Path\to\Resources.xml", _ OtherFlags:=acEmbedSchema

Ini mengemulasi ekspor yang awalnya kami lakukan secara interaktif.

Namun, jika kita kemudian mengimpor XML yang dihasilkan, kita hanya memiliki opsi untuk menambahkan data ke tabel yang ada. Kami tidak dapat mengontrol tabel mana yang akan ditambahkan; itu akan menemukan tabel atau tabel kueri dengan nama yang sama (mis. qryResourcesExport dan menambahkan catatan ke kueri itu. Jika kueri dapat diperbarui, maka tidak ada masalah dan akan dimasukkan ke dalam Example yang menjadi dasar kueri. Tetapi bagaimana jika kueri sumber yang kami gunakan tidak dapat diperbarui atau mungkin tidak ada? Dalam kedua kasus tersebut, kami tidak akan dapat mengimpor file XML apa adanya. Itu bisa gagal untuk mengimpor atau akhirnya membuat tabel baru bernama qryResourcesExport yang tidak membantu kita. Dan bagaimana dengan kasus penyalinan data dari Example ke MSysResources ? Kami tidak ingin menambahkan data ke Example tabel.

Di situlah TransformXML metode datang untuk menyelamatkan. Diskusi lengkap tentang cara menulis transformasi XML berada di luar cakupan tetapi Anda harus dapat menemukan sumber daya yang cukup tentang cara menulis lembar gaya XSLT untuk menjelaskan transformasi. Ada beberapa alat online yang dapat Anda gunakan untuk memvalidasi XSLT Anda juga. Ini dia. Untuk kasus sederhana di mana kita hanya ingin mengontrol tabel mana file XML harus menambahkan catatan ke dalamnya, Anda bisa memulai dengan file XSLT ini. Anda kemudian dapat menjalankan kode VBA berikut:

Application.TransformXML _ DataSource:="C:\Path\to\Resources.xml", _ TransformSource:="C:\Path\to\ResourcesTransform.xslt", _ OutputTarget:="C:\Path\ to\Resources.xml", _ WellFormedXMLOutput:=Benar, _ ScriptOption:=acEnableScript

Kita dapat mengganti file XML asli dengan file XML yang diubah, yang sekarang akan dimasukkan ke dalam MSysResources tabel daripada ke (mungkin kueri/tabel tidak ada) qryResourcesExport .

Kami kemudian perlu menangani pembaruan. Karena kami sebenarnya menambahkan catatan baru, dan MSysResources tabel tidak memiliki batasan pada nama duplikat, kita perlu memastikan bahwa catatan yang ada dengan nama yang sama dihapus terlebih dahulu. Ini dapat dicapai dengan menulis kueri yang setara seperti ini:

HAPUS DARI MSysResources AS rWHERE r.Name In ("blue","red","green");

lalu jalankan terlebih dahulu sebelum menjalankan kode VBA:

Application.ImportXML DataSource:="C:\Path\to\Resources.xml", ImportOptions:=acAppendData

Karena file XML telah diubah, ImportXML metode sekarang akan memasukkan data ke dalam MSysResources tabel daripada kueri asli yang kami gunakan dengan ExportXML metode. Kami menentukan bahwa itu harus menambahkan data ke dalam tabel yang ada. Namun, jika tabel tidak ada, tabel akan dibuat.

Dan dengan itu, kami telah mencapai pembaruan massal/penyisipan tabel dengan bidang lampiran yang jauh lebih cepat dibandingkan dengan kode VBA recordset-and-child-recordset asli. Semoga membantu! Juga, jika Anda memerlukan bantuan untuk mengembangkan aplikasi Access, jangan ragu untuk menghubungi kami!


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Hitung Semua Objek di Database Anda

  2. JetShowPlan:Sebuah Primer

  3. 5 Jenis Perbaikan Basis Data

  4. ListView Control Drag Drop Penanganan Events

  5. Tips dan Trik Microsoft Access Bagian 2 – Formulir