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.

Featured image for article: Cara Mendorong Kontak Excel ke Brevo dengan VBA Macro (dan Alternatif Office Scripts)

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:

  1. 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”.
  2. 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:

  1. Baca setiap baris dari worksheet aktif (baris header pertama, satu kontak per baris).
  2. Bangun array JSON yang berbentuk untuk parameter jsonBody Brevo.
  3. POST ke https://api.brevo.com/v3/contacts/import dengan API key yang tersimpan di workbook.
  4. 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

emailfirstNamelastNamecompanycity
[email protected]JaneDoeAcmeBerlin
[email protected]JohnSmithGlobexParis

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 ID
Private 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 0
End 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 = 0
End 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 If
End 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 = r
End Function

Langkah 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 ConfigureApiKey dan tekan F5, 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:

  1. Trigger: Recurrence (setiap 1 jam), atau tombol manual, atau “When a row is modified” jika Anda ingin sinkronisasi yang dipicu perubahan.
  2. Action: Excel Online -> Run script, arahkan ke workbook Anda dan script di atas. Simpan nilai kembaliannya sebagai contacts.
  3. 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
      }
  4. 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

KebutuhanOpsi terbaik
Tombol satu klik di workbook yang sudah dibuka tim Anda setiap hariVBA macro (panduan ini, bagian atas)
Workbook di OneDrive/SharePoint, sinkronisasi otomatis per jamOffice Scripts + Power Automate (perlu Premium untuk HTTP)
Hanya Mac Excel, tidak bisa pakai VBAOffice Scripts + Power Automate
Data ada di Google Sheets, bukan ExcelApps Script (gratis, trigger terjadwal built-in)
Impor sekali pakai, tidak akan pernah perlu lagiSave As -> CSV dan gunakan script impor CSV
Impor massal dari file >10 MBCSV 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.

Bacaan lanjutan

Frequently Asked Questions

Apakah VBA macro benar-benar dapat memanggil API Brevo dari dalam Excel?
Ya. VBA dapat membuat HTTP request melalui MSXML2.XMLHTTP, yang dikirimkan dengan setiap instalasi Windows modern. Macro melakukan POST JSON ke api.brevo.com/v3/contacts/import, endpoint yang sama dengan yang akan dihit oleh script Python atau Node. Mac Excel juga dapat melakukannya melalui Office Scripts + Power Automate, tetapi VBA Mac desktop tidak bisa (tidak ada MSXML).
Apakah saya dapat menjalankan ini sesuai jadwal seperti time trigger Apps Script?
Tidak dari VBA saja, Excel harus terbuka agar Application.OnTime aktif. Untuk sinkronisasi terjadwal tanpa pengawasan, Anda memiliki dua opsi: (1) Windows Task Scheduler yang membuka workbook dan menjalankan macro, atau (2) Office Scripts yang dipicu oleh Power Automate flow terjadwal (dibahas nanti dalam panduan ini).
Apakah VBA aman? Perusahaan saya memblokir macro.
VBA macro berjalan dengan akses file system dan registry, jadi memblokirnya secara default adalah kebijakan yang masuk akal. Dua jalur untuk menyiasatinya: (1) tandatangani macro dengan sertifikat code-signing dan letakkan workbook di Trusted Location, atau (2) lewati VBA sepenuhnya dan gunakan Office Scripts (TypeScript, sandbox, tanpa akses file system). Office Scripts adalah jalur modern yang direstui Microsoft.
Bagaimana ini dibandingkan dengan pendekatan Google Apps Script?
Apps Script lebih dekat ke set-and-forget, berjalan di cloud Google, trigger terjadwal sudah built-in, tanpa lisensi Excel/Power Automate. VBA menang untuk pekerjaan offline dan sinkronisasi manual satu klik dari workbook yang sudah dibuka tim Anda. Office Scripts + Power Automate adalah ekuivalen cloud/terjadwal di sisi Microsoft, tetapi Power Automate sering memerlukan konektor premium berbayar untuk HTTP keluar.
Brevo के साथ मुफ्त में शुरू करें