Cara Mendorong Kontak Excel ke Brevo dengan VBA Macro (dan Alternatif Office Scripts)
VBA macro yang berfungsi yang mengirim kontak dari sheet Excel ke API Brevo dalam satu klik, plus kapan menggunakan Office Scripts + Power Automate sebagai gantinya, dan trade-off vs setup Google Apps Script.
Anda memiliki kontak di Excel dan Anda menginginkannya di Brevo. Jawaban cepat dan kasar adalah menyimpan file sebagai .csv dan mengimpornya, yang baik-baik saja sekali. Untuk apa pun yang Anda lakukan berulang kali, serah-terima penjualan mingguan, workbook yang diperbarui tim Anda setiap hari, daftar mitra yang di-refresh, Anda menginginkan tombol langsung di dalam Excel yang melakukan sinkronisasi.
Panduan ini membahas dua jalur yang sebenarnya masuk akal untuk itu:
- VBA macro yang tertanam dalam workbook, tanpa lisensi, tanpa cloud, bekerja offline, berjalan saat pengguna mengklik tombol. Jawaban yang tepat untuk sekitar 80% kasus “Excel ke Brevo”.
- Office Scripts + Power Automate, TypeScript alih-alih VBA, berjalan di cloud, mendukung trigger terjadwal. Jawaban yang tepat jika workbook ada di OneDrive/SharePoint dan Anda ingin sinkronisasi tanpa pengawasan, tetapi waspadai lisensi Power Automate.
Jika Anda mencari ekuivalen Google Sheets, lihat artikel pendamping tentang Apps Script. Dan jika Anda hanya ingin impor CSV satu kali dari script di laptop Anda, panduan impor CSV memiliki versi Python, Node.js, dan cURL.
Apa yang dilakukan macro
Ketika pengguna mengklik tombol “Sync to Brevo” di sheet:
- Baca setiap baris dari worksheet aktif (baris header pertama, satu kontak per baris).
- Bangun array JSON yang berbentuk untuk parameter
jsonBodyBrevo. - POST ke
https://api.brevo.com/v3/contacts/importdengan API key yang tersimpan di workbook. - Tampilkan kotak pesan dengan hasilnya.
Itu saja. Sekitar 120 baris VBA. Di bawah ini adalah modul lengkap yang berfungsi.
Tata letak sheet yang diharapkan macro
| firstName | lastName | company | city | |
|---|---|---|---|---|
| [email protected] | Jane | Doe | Acme | Berlin |
| [email protected] | John | Smith | Globex | Paris |
email wajib. Setiap kolom lain menjadi atribut kontak Brevo, dipetakan oleh header kolom (huruf besar) ke nama atribut. Jadi firstName -> FIRSTNAME, company -> COMPANY. Atribut kustom (apa pun di luar set standar) harus ada di akun Brevo Anda terlebih dahulu, definisikan di bawah Contacts -> Settings -> Contact attributes.
Langkah 1: Buka VBA editor
Di Excel: tekan Alt + F11. VBA editor terbuka. Di panel Project di sebelah kiri, klik kanan workbook Anda dan pilih Insert -> Module. Sebuah Module1 kosong muncul.
Langkah 2: Tempel macro lengkap
Ganti konten Module1 dengan ini:
' ===========================================================================' Brevo contact sync for Excel' Reads the active sheet's rows and POSTs them to Brevo's import API.' ===========================================================================Option Explicit
Private Const BREVO_API_BASE As String = "https://api.brevo.com/v3"Private Const BREVO_LIST_ID As Long = 42 ' <- your Brevo list IDPrivate Const BATCH_SIZE As Long = 1000
' --- Public entry points (the ones you assign to ribbon buttons) -----------
Public Sub SyncSheetToBrevo() Dim apiKey As String apiKey = GetApiKey() If apiKey = "" Then MsgBox "No API key configured. Run ConfigureApiKey first.", _ vbExclamation, "Brevo Sync" Exit Sub End If
Dim ws As Worksheet Set ws = ActiveSheet
Dim emailCol As Long emailCol = FindEmailColumn(ws) If emailCol = 0 Then MsgBox "Sheet must have an 'email' column in row 1.", _ vbExclamation, "Brevo Sync" Exit Sub End If
Dim lastRow As Long, lastCol As Long lastRow = ws.Cells(ws.Rows.Count, emailCol).End(xlUp).Row lastCol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column If lastRow < 2 Then MsgBox "No contact rows found.", vbInformation, "Brevo Sync" Exit Sub End If
Dim contacts As Collection Set contacts = New Collection
Dim r As Long, c As Long For r = 2 To lastRow Dim email As String email = LCase(Trim(CStr(ws.Cells(r, emailCol).Value))) If email <> "" And InStr(email, "@") > 0 Then Dim json As String json = "{""email"":""" & EscapeJson(email) & """,""attributes"":{"
Dim attrFirst As Boolean attrFirst = True For c = 1 To lastCol If c <> emailCol Then Dim val As String val = CStr(ws.Cells(r, c).Value) If val <> "" Then If Not attrFirst Then json = json & "," Dim attrName As String attrName = UCase(Trim(CStr(ws.Cells(1, c).Value))) json = json & """" & attrName & """:""" & EscapeJson(val) & """" attrFirst = False End If End If Next c
json = json & "}}" contacts.Add json End If Next r
If contacts.Count = 0 Then MsgBox "No valid contact rows found.", vbInformation, "Brevo Sync" Exit Sub End If
Dim totalSent As Long Dim batchNum As Long Dim okCount As Long, failCount As Long Dim batchStart As Long
For batchStart = 1 To contacts.Count Step BATCH_SIZE batchNum = batchNum + 1 Dim batchEnd As Long batchEnd = batchStart + BATCH_SIZE - 1 If batchEnd > contacts.Count Then batchEnd = contacts.Count
Dim payload As String payload = "{""jsonBody"":[" Dim i As Long For i = batchStart To batchEnd If i > batchStart Then payload = payload & "," payload = payload & contacts(i) Next i payload = payload & "],""listIds"":[" & BREVO_LIST_ID & _ "],""updateExistingContacts"":true,""emptyContactsAttributes"":false}"
Dim ok As Boolean ok = PostToBrevo(apiKey, payload) If ok Then okCount = okCount + 1 totalSent = totalSent + (batchEnd - batchStart + 1) Else failCount = failCount + 1 End If Next batchStart
MsgBox "Sent " & totalSent & " contact(s) in " & batchNum & " batch(es)." _ & vbCrLf & "Successful batches: " & okCount _ & vbCrLf & "Failed batches: " & failCount, _ vbInformation, "Brevo Sync"End Sub
Public Sub ConfigureApiKey() Dim key As String key = InputBox("Paste your Brevo API key (xkeysib-...):", "Brevo API Key") If key = "" Then Exit Sub key = Trim(key) If Left(key, 8) <> "xkeysib-" Then MsgBox "That doesn't look like a Brevo API key (should start with xkeysib-).", _ vbExclamation, "Brevo API Key" Exit Sub End If
On Error Resume Next ThisWorkbook.CustomDocumentProperties("BrevoApiKey").Delete On Error GoTo 0
ThisWorkbook.CustomDocumentProperties.Add _ Name:="BrevoApiKey", _ LinkToContent:=False, _ Type:=msoPropertyTypeString, _ Value:=key
ThisWorkbook.Save MsgBox "API key saved inside the workbook.", vbInformation, "Brevo API Key"End Sub
' --- Private helpers --------------------------------------------------------
Private Function GetApiKey() As String On Error Resume Next GetApiKey = ThisWorkbook.CustomDocumentProperties("BrevoApiKey").Value On Error GoTo 0End Function
Private Function FindEmailColumn(ws As Worksheet) As Long Dim lastCol As Long, c As Long lastCol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column For c = 1 To lastCol If LCase(Trim(CStr(ws.Cells(1, c).Value))) = "email" Then FindEmailColumn = c Exit Function End If Next c FindEmailColumn = 0End Function
Private Function PostToBrevo(apiKey As String, payload As String) As Boolean Dim http As Object Set http = CreateObject("MSXML2.XMLHTTP") http.Open "POST", BREVO_API_BASE & "/contacts/import", False http.SetRequestHeader "api-key", apiKey http.SetRequestHeader "Content-Type", "application/json" http.SetRequestHeader "Accept", "application/json" http.Send payload PostToBrevo = (http.Status = 202) If Not PostToBrevo Then Debug.Print "Brevo error " & http.Status & ": " & http.responseText End IfEnd Function
Private Function EscapeJson(s As String) As String Dim r As String r = Replace(s, "\", "\\") r = Replace(r, """", "\""") r = Replace(r, vbCrLf, "\n") r = Replace(r, vbLf, "\n") r = Replace(r, vbCr, "\n") r = Replace(r, vbTab, "\t") EscapeJson = rEnd FunctionLangkah 3: Simpan workbook sebagai .xlsm
VBA macro hanya bertahan di workbook yang diaktifkan macro. Save As, pilih Excel Macro-Enabled Workbook (.xlsm). Format .xlsx biasa menghapus macro secara diam-diam, banyak orang kehilangan kode dengan cara ini pertama kali.
Langkah 4: Konfigurasi API key Anda
Jalankan ConfigureApiKey sekali. Salah satu:
- Di VBA editor, klik di mana saja di dalam sub
ConfigureApiKeydan tekanF5, atau - Di Excel, Developer -> Macros, pilih
ConfigureApiKey, Run.
Tempel key xkeysib-... Anda. Macro menyimpannya sebagai custom document property di dalam workbook itu sendiri, tidak ada di source code, tidak ada di registry, dan ikut dengan file (jadi waspada: jika Anda mengirim .xlsm ke seseorang, API key ikut bersamanya).
Jika Anda lebih suka menempatkan key di luar workbook, alihkan penyimpanan ke Windows registry:
' Replace the body of ConfigureApiKey with:SaveSetting "Brevo", "Sync", "ApiKey", key
' And GetApiKey with:GetApiKey = GetSetting("Brevo", "Sync", "ApiKey", "")SaveSetting/GetSetting menulis di bawah HKCU\Software\VB and VBA Program Settings\Brevo\Sync, per pengguna, bukan per workbook. Gunakan ini jika beberapa workbook harus berbagi satu key, atau jika Anda tidak ingin key ada di file.
Langkah 5: Tambahkan tombol di sheet
Inilah yang mengubahnya menjadi pengalaman satu klik untuk pengguna non-teknis.
Insert -> Shapes -> Rectangle, jatuhkan satu ke sheet, beri label “Sync to Brevo.” Klik kanan shape -> Assign Macro -> pilih SyncSheetToBrevo. Selesai.
Atau, untuk UI yang lebih halus, tambahkan tab ribbon kustom melalui Office Custom UI Editor, tetapi untuk sebagian besar tool internal, shape-as-button sudah cukup.
Langkah 6: Jalankan
Klik tombol. Macro membaca baris, mem-batch-nya, mem-POST setiap batch ke Brevo, dan menampilkan kotak pesan ringkasan. Impor Brevo bersifat asynchronous, jadi pesan sukses berarti “Brevo menerima batch”, pembuatan kontak sebenarnya terjadi di sisi server dalam beberapa detik berikutnya. Anda akan menerima ringkasan email dari Brevo ketika selesai (kecuali Anda menyetel disableNotification: true).
Jebakan umum
Tombol tidak melakukan apa-apa dan tidak ada error. Macro dinonaktifkan. Lihat bilah keamanan kuning di bagian atas sheet, klik Enable Content. Jika organisasi Anda memblokir macro, lihat jalur trust-center / code-signing di bawah.
Compile error: User-defined type not defined. Anda di Mac Excel, yang tidak memiliki MSXML2.XMLHTTP. Mac VBA tidak dapat membuat HTTPS request secara langsung; gunakan jalur Office Scripts di bawah sebagai gantinya.
400 Bad Request dari Brevo tanpa penyebab yang jelas. Hampir selalu salah satu dari: (a) atribut kustom di sheet Anda belum ada di Brevo, buat terlebih dahulu; (b) bug JSON escaping, tanda kutip atau backslash di nilai sel yang tidak ter-escape. Fungsi EscapeJson di kode menangani kasus standar; jika data Anda memiliki karakter aneh, log payload ke jendela Immediate (Debug.Print payload) dan inspeksi.
401 Unauthorized. Header salah. Itu adalah api-key (huruf kecil, tanda hubung), bukan Authorization. Macro menggunakan yang benar, tetapi jika Anda menyalin snippet dari tempat lain, periksa kembali.
Excel membeku pada impor besar. Macro berjalan secara sinkron pada thread UI. Untuk 50.000+ baris, Anda akan melihat Excel hang selama 10-30 detik saat membangun JSON dan menunggu Brevo. Entah terima saja, atau alihkan MSXML2.XMLHTTP ke varian async, tetapi pada skala itu Anda lebih baik di Power Automate (bagian berikutnya).
Ketika VBA tidak cukup: Office Scripts + Power Automate
VBA tidak dapat melakukan sinkronisasi cloud terjadwal. Jika Anda perlu:
- Workbook menyinkron ke Brevo setiap jam tanpa siapa pun membukanya
- Workbook di OneDrive/SharePoint, diedit dari web
- Departemen IT yang melarang macro desktop
…maka Anda menginginkan Office Scripts (ekuivalen cloud Microsoft dari Apps Script) plus Power Automate (lapisan penjadwalan dan HTTP mereka).
Pembagiannya: Office Scripts membaca sheet dan mengembalikan data kontak. Power Automate mengambil data tersebut dan mem-POST-nya ke Brevo pada trigger.
Office Script (Excel for the web -> Automate -> New Script):
function main(workbook: ExcelScript.Workbook): {email: string, attributes: Record<string, string>}[] { const sheet = workbook.getActiveWorksheet(); const range = sheet.getUsedRange(); if (!range) return [];
const values = range.getValues() as string[][]; if (values.length < 2) return [];
const headers = values[0].map(h => String(h).trim()); const emailIdx = headers.findIndex(h => h.toLowerCase() === "email"); if (emailIdx === -1) throw new Error("Sheet must have an 'email' column");
const contacts: {email: string, attributes: Record<string, string>}[] = []; for (let r = 1; r < values.length; r++) { const row = values[r]; const email = String(row[emailIdx] ?? "").trim().toLowerCase(); if (!email || !email.includes("@")) continue;
const attributes: Record<string, string> = {}; for (let c = 0; c < headers.length; c++) { if (c === emailIdx) continue; const v = row[c]; if (v === null || v === "") continue; attributes[headers[c].toUpperCase()] = String(v); } contacts.push({ email, attributes }); } return contacts;}Flow Power Automate:
- Trigger: Recurrence (setiap 1 jam), atau tombol manual, atau “When a row is modified” jika Anda ingin sinkronisasi yang dipicu perubahan.
- Action: Excel Online -> Run script, arahkan ke workbook Anda dan script di atas. Simpan nilai kembaliannya sebagai
contacts. - Action: HTTP (ini konektor Premium, lihat catatan lisensi di bawah).
- Method:
POST - URI:
https://api.brevo.com/v3/contacts/import - Headers:
api-key: xkeysib-...,Content-Type: application/json - Body:
{"jsonBody": @{outputs('Run_script')?['body/result']},"listIds": [42],"updateExistingContacts": true}
- Method:
- Action: Condition -> jika status code bukan 202, kirim peringatan Teams/email.
Pemeriksaan realitas lisensi: action HTTP adalah konektor Premium Power Automate. Pada paket Microsoft 365 Business Basic/Standard, Anda mendapatkan konektor standar tetapi bukan Premium. Solusi termurah adalah add-on Power Automate Premium (~$15/pengguna/bulan saat penulisan), atau pindahkan HTTP ke Azure Function kecil yang dapat dipanggil oleh flow standar. Jika Anda sudah di E3/E5 dengan Premium termasuk, Anda siap.
Inilah alasan utama cerita Apps Script lebih bersih: UrlFetchApp Apps Script gratis dan tanpa batasan, sementara ekuivalen Microsoft menempatkan panggilan jaringan di balik tier konektor berbayar.
VBA vs Office Scripts vs Apps Script: kapan harus memilih apa
| Kebutuhan | Opsi terbaik |
|---|---|
| Tombol satu klik di workbook yang sudah dibuka tim Anda setiap hari | VBA macro (panduan ini, bagian atas) |
| Workbook di OneDrive/SharePoint, sinkronisasi otomatis per jam | Office Scripts + Power Automate (perlu Premium untuk HTTP) |
| Hanya Mac Excel, tidak bisa pakai VBA | Office Scripts + Power Automate |
| Data ada di Google Sheets, bukan Excel | Apps Script (gratis, trigger terjadwal built-in) |
| Impor sekali pakai, tidak akan pernah perlu lagi | Save As -> CSV dan gunakan script impor CSV |
| Impor massal dari file >10 MB | CSV dengan fileUrl, lihat panduan CSV |
Mengapa ini lebih baik dari Zapier / platform no-code
Untuk pekerjaan Excel-ke-Brevo yang berulang, tool otomatisasi pihak ketiga (Zapier, Make, n8n) menagih per task dan menempatkan pihak ketiga antara data Anda dan Brevo. Pendekatan VBA memiliki nol biaya berkelanjutan, tidak ada aliran data pihak ketiga, dan hidup di dalam file, ketika workbook berpindah, integrasi berpindah dengannya. Office Scripts + Power Automate serupa tetapi dengan Microsoft sebagai pihak ketiga (sudah ada di stack Anda jika Anda di M365).
Inti dari endpoint POST /v3/contacts/import Brevo adalah Anda tidak membutuhkan platform perekat, tool Anda sudah tahu cara membuat HTTP request.