Bayangkan sebuah job yang hampir tidak melakukan apa-apa: membuka workbook bulanan, menulis tanggal hari ini ke satu sel, lalu menyimpannya kembali. Jalankan itu melalui sebuah layanan cukup sering dan sebuah keluhan tetap saja datang. Makronya hilang, atau kurs tukar yang tertaut kini terbaca #REF!, dan tim operasional yakin kode Anda yang menghapusnya. Padahal tidak ada yang dihapus. Yang biasanya terjadi adalah sebuah workbook bermakro dikirim keluar dengan nama .xlsx biasa, dan Excel patuh pada aturan content-type ECMA-376: sebuah paket yang content type-nya menyatakan tanpa VBA tidak bisa memuat sebuah proyek VBA, terlepas dari apakah byte-nya sungguh ada di sana. File itu tidak rusak. File itu diganti nama menjadi sebuah keadaan di mana Excel diwajibkan mengabaikan sebagian darinya
Makro dan tautan workbook eksternal adalah dua hal yang paling konsisten hilang akibat otomatisasi, karena alasan mendasar yang sama. Keduanya berada di luar grid sel yang sebenarnya disentuh oleh kode editing, sehingga kode yang bernalar dalam kerangka baris dan kolom akan menjatuhkannya tanpa pernah mengeluarkan perintah hapus sama sekali. HotXLS adalah pustaka native Delphi dan C++Builder yang membaca dan menulis XLS dan XLSX tanpa Excel terinstal, dan ia memperlakukan kedua aset ini sebagai payload yang dibawanya secara sengaja, bukan sekadar data yang kebetulan ikut disalin. Berikut ini adalah apa yang dibutuhkan masing-masing dari jalur penyimpanan Anda, dan di mana jaminannya berhenti
Mengapa Kedua Aset Ini Berperilaku Berbeda di Bawah Penulisan Ulang
Sebuah proyek VBA adalah satu binary yang opak. Di dalam paket OOXML, itu adalah file vbaProject.bin; di dalam file BIFF lawas, itu adalah sebuah OLE storage. Ada tepat dua cara untuk kehilangannya: writer tidak pernah menyalinnya ke output, atau outputnya mendapatkan tipe file yang melarangnya. Kedua kegagalan itu sama-sama total dan senyap. Proyeknya ada atau tidak ada
Sebuah tautan eksternal sama sekali bukan sebuah blob. Itu adalah sebuah graf hubungan kecil: sebuah path atau URL target yang menunjuk ke workbook lain, daftar nama sheet yang diekspos target itu, dan sebuah cache opsional dari nilai-nilai yang terakhir terlihat di sheet-sheet tersebut sehingga Excel bisa menampilkan sesuatu ketika targetnya offline. Ketiga bagian itu punya masa hidup yang berbeda di bawah sebuah penulisan ulang, dan sebuah pustaka bisa dengan setia mempertahankan sebagian sementara diam-diam menjatuhkan yang lain. Asimetri itulah bagian yang layak dipahami secara presisi, karena tidak ada apa pun dalam kode editing sel yang akan memunculkannya ke permukaan
Membawa Proyek VBA Melalui Penulisan Ulang XLSX
Pada sisi XLSX, TXLSXWorkbook mempertahankan payload makro apa adanya. Properti VbaProject menyimpan byte mentah vbaProject.bin di dalam sebuah AnsiString, dan sebuah string kosong adalah cara model ini menyatakan tidak ada makro. Di sekelilingnya ada tiga operasi: HasVbaProject menjawab apakah sebuah proyek ada, ClearVbaProject menghapusnya secara sengaja, dan LoadVbaProjectFromFile menyuntikkan satu yang diekstrak dari sebuah template. Panggilan terakhir itu lebih berharga daripada kelihatannya. Ia memungkinkan workbook hasil generate mengambil sebuah proyek makro standar tanpa perlu menyeret seluruh file template melalui pipeline
var
Book: TXLSXWorkbook;
Sheet: TXLSXWorksheet;
begin
Book := TXLSXWorkbook.Create;
try
Sheet := Book.Sheets.Add('Data');
Sheet.Cells[1, 1].Value := 'Refreshed ' + DateTimeToStr(Now);
Book.LoadVbaProjectFromFile('macros\vbaProject.bin');
if not Book.HasVbaProject then
raise Exception.Create('VBA payload failed to load');
// Ekstensi .xlsm bukan sekadar kosmetik: ekstensi ini yang memilih
// content type macro-enabled di dalam paket.
Book.SaveAs('monthly-report.xlsm');
finally
Book.Free;
end;
end;
Baris penyimpanan adalah titik di mana seluruh masalah ini berputar. Sebuah workbook yang memegang proyek VBA harus ditulis dengan semantik macro-enabled, dan HotXLS menerapkannya ketika nama target berakhiran .xlsm. Berikan .xlsx sebagai gantinya dan Excel akan menolak makronya, meskipun byte-nya secara fisik ada di dalam paket dan akan berhasil dideserialisasi dengan baik. Ekstensinya bukan dekorasi; ia yang memilih content type yang memberitahu Excel bahwa sebuah proyek VBA diizinkan untuk ada. Kebanyakan waktu Anda hanya perlu membawa payload-nya melalui saja. Ketika Anda perlu membaca ke dalamnya, katakanlah untuk mendaftar nama modul demi sebuah laporan audit, ParsedVBAProject mengekspos sebuah model modul yang telah diparse sementara VbaProject tetap menjadi byte asli yang tidak tersentuh
Menggunakan Kembali Makro dari Workbook XLS Lawas
Facade BIFF mencerminkan kumpulan tool yang sama dengan satu langkah tambahan. HasVBAProject memeriksa sebuah file yang sudah dimuat, SaveVBAProjectToFile menulis storage proyek itu keluar ke disk, dan LoadVBAProjectFromFile membacanya kembali ke dalam workbook lain. Jalan memutar lewat sebuah file ini membuat tugas modernisasi yang umum menjadi mudah: angkat makro keluar dari sebuah model era 2003 dan tanamkan ke output XLS yang baru saja dihasilkan, tanpa membutuhkan template asli saat runtime
var
Src, Dst: IXLSWorkbook; // referensi interface: tanpa Free manual
begin
Src := TXLSWorkbook.Create;
if Src.Open('legacy-model.xls') <= 0 then
raise Exception.Create('Cannot open legacy model');
if Src.HasVBAProject then
Src.SaveVBAProjectToFile('extracted-vba.bin');
Dst := TXLSWorkbook.Create;
Dst.Sheets.Add.Name := 'Report2026';
Dst.LoadVBAProjectFromFile('extracted-vba.bin');
Dst.SaveAs('report-with-macros.xls');
end;
Model memorinya adalah jebakan di sini, dan arahnya berlawanan dengan class XLSX. TXLSWorkbook dipegang melalui interface IXLSWorkbook yang reference-counted, sehingga Anda tidak pernah membebaskannya secara manual; TXLSXWorkbook pada XLSX adalah objek biasa yang harus Anda bungkus dalam try..finally dan bebaskan. Campurkan kedua konvensi itu dalam satu unit dan crash double-free akan menyusul. Satu batas lagi yang layak dihormati: jaga agar ekstraksi dan injeksi tetap berada dalam satu format file. Storage proyek BIFF dan vbaProject.bin OOXML adalah sepupu, bukan kontainer yang sama, dan sebuah pipeline yang harus mengeluarkan makro dalam kedua format itu sebaiknya menyimpan template makro terpisah untuk masing-masing
Tautan Eksternal: Peta Bertahan, Nilai Cache Tidak
Untuk workbook XLSX, HotXLS mengekspos tautan eksternal melalui koleksi ExternalLinks. Setiap TXLSXExternalLink membawa sebuah Target, path atau URL dari workbook remote, ditambah sebuah daftar SheetNames yang menamai sheet-sheet yang direferensikannya. Keduanya bertahan utuh melalui siklus open-and-save, dan Anda juga bisa membangun sebuah tautan dari nol:
var
Link: TXLSXExternalLink;
begin
Link := Book.ExternalLinks.Add('\\fileserver\finance\fx-rates-2026.xlsx');
Link.SheetNames.Add('FX');
if Book.ExternalLinks.Count > 0 then
Writeln(Format('%d external link(s): delivery requires reachable targets',
[Book.ExternalLinks.Count]));
end;
Batasnya berada satu tingkat lebih dalam daripada daftar target. HotXLS melakukan round-trip pada peta tautannya, yakni target dan nama sheet, tetapi tidak mem-parse atau menulis ulang nilai sel cache yang disimpan OOXML di dalam elemen sheetDataSet milik tautan tersebut. Cache itulah yang memungkinkan Excel menampilkan angka terakhir yang diketahui ketika file sumbernya offline, dan workbook hasil generate dikirim tanpa itu. Konsekuensinya jatuh pada penerima, bukan pada Anda. Buka file semacam itu ketika targetnya tidak terjangkau, sebuah laptop yang lepas dari VPN atau sebuah share yang berganti nama, dan formula yang bergantung pada tautan itu akan menghasilkan #REF! atau macet di balik prompt update. Jadi dua aturan muncul dari sini. Jangan menjanjikan bahwa workbook hasil generate akan menampilkan nilai tautan eksternalnya secara offline. Dan baca ExternalLinks.Count yang bukan nol sebagai prasyarat pengiriman, bukan sebagai fitur: setiap target harus terjangkau dari mana pun file itu akan dibuka nantinya
Apa yang Dipertahankan Byte demi Byte oleh Pembaca XLS
Untuk struktur yang tidak dimodelkannya, sisi BIFF punya jawaban yang berbeda: biarkan persis seperti saat ditemukan. Pivot cache dan pivot view (keluarga record SX*), definisi QueryTable, koneksi data eksternal, custom view, gambar header, dan record tema semuanya melewati siklus open-and-save sebagai blok record mentah, tidak di-parse dan tidak dimodifikasi. Referensi eksternal itu sendiri melakukan round-trip melalui record EXTERNSHEET dan SupBook yang mendasarinya. Tidak ada API pembuatan bertipe untuk itu di sisi XLS, tetapi sebuah tautan yang sudah ada bertahan tidak tersentuh melewati proses editing
Preservasi byte demi byte adalah jaminan sungguhan dengan sisi yang tajam. Karena tidak ada apa pun yang membaca sebuah struktur yang dipertahankan, edit Anda tidak bisa merusaknya. Untuk alasan yang sama, tidak ada apa pun yang memperbaruinya juga. Sisipkan baris melalui sebuah region yang ditunjuk oleh sebuah pivot cache atau query table yang dipertahankan, dan struktur itu tetap memegang koordinat aslinya sementara data di bawahnya bergeser. Filenya tetap XML atau BIFF yang valid; maknanya diam-diam sudah melenceng dari kesejajarannya, dan tidak ada error yang muncul untuk memberitahu Anda. Layout yang bisa dipertanggungjawabkan adalah menjaga edit hasil generate tetap berada di sheet yang tidak memegang struktur yang dipertahankan, disiplin yang sama yang melindungi sheet yang terkunci dan terkonfigurasi cetak dalam artikel kami tentang proteksi worksheet dan page setup
Memverifikasi File yang Sungguh-Sungguh Anda Tulis
Kedua mode kegagalan itu sama-sama senyap pada saat penulisan, sehingga pemeriksaan yang benar-benar penting dilakukan dengan membuka kembali outputnya, bukan memercayai kode yang menghasilkannya. Tiga pemeriksaan mencakup hampir semuanya. Buka kembali file itu dan pastikan HasVbaProject masih mengembalikan true setiap kali makro diharapkan ada, yang menangkap payload yang hilang dan ekstensi yang salah dalam satu pengujian saja. Baca ExternalLinks.Count dan bandingkan dengan jumlah sebelum penulisan ulang. Lalu buka file itu sekali di Excel dengan makro dinonaktifkan, karena validasi content-type Excel lebih ketat daripada pustaka mana pun, dan Excel adalah program yang akan digunakan pelanggan Anda untuk menilai file tersebut
Tidak satu pun dari itu membutuhkan parse penuh di jalur masuk. Ketika workbook datang dalam jumlah besar dan Anda hanya perlu men-triase mana yang membawa konten yang diatur, probing ringan dalam artikel kami tentang listing sheet dan inspeksi workbook ringan memungkinkan Anda mengarahkan file bermakro dan bertaut ke pipeline yang lebih ketat sebelum penulisan ulang pertama pun berjalan
Ada beberapa pertanyaan yang cukup sering muncul untuk dijawab langsung di sini. HotXLS tidak pernah menjalankan makro yang dipertahankannya: tidak ada runtime VBA di dalam pustaka ini, hanya mekanisme untuk menyimpan, menyalin, mengekstrak, dan menyuntikkan proyek itu sebagai data. Di sebuah server, itu adalah properti keamanan yang layak dinyatakan, karena sebuah makro berbahaya yang melewati pipeline tetap inert hingga sebuah Excel desktop membuka file itu dan seorang pengguna mengaktifkan konten. Mengonversi .xlsm ke .xlsx sambil mempertahankan makronya tidak mungkin dilakukan, dan itu adalah aturan formatnya, bukan keterbatasan pustaka: content type .xlsx menyatakan sebuah workbook bebas makro, sehingga satu-satunya hasil yang jujur adalah tetap sebagai .xlsm atau memanggil ClearVbaProject dan mengirim sebuah file yang sungguh-sungguh tidak memilikinya. Penggantian nama yang senyap adalah satu-satunya pilihan yang tidak memuaskan siapa pun. Dan ketika sel yang tertaut menampilkan #REF! setelah sebuah penulisan ulang, penyebabnya adalah cache nilai yang hilang seperti dibahas di atas: file baru itu membawa target tetapi tidak membawa angka cache-nya, sehingga Excel harus menyelesaikan sumbernya pada saat dibuka, dan sebuah path yang tidak terjangkau atau relatif terhadap lingkungan akan mengalahkannya. Entah jaminlah bahwa target itu terjangkau, atau tulis nilai hasil perhitungan ke dalam sel sebelum pengiriman dan hilangkan dependensinya sama sekali
Mengedit workbook milik orang lain sebagian besar adalah pekerjaan mempertahankan hal-hal yang tidak Anda tulis sendiri dan tidak sepenuhnya Anda pahami. Fasilitas round-trip VBA dan tautan eksternal yang dijelaskan di sini disertakan dalam HotXLS Delphi Component untuk Delphi dan C++Builder, bersama properti audit yang memungkinkan Anda mendeteksi konten yang diatur begitu sebuah file tiba