Kako poslati Excel kontakte u Brevo pomoću VBA makronaredbe (i alternativa s Office Scripts)

Radna VBA makronaredba koja jednim klikom šalje kontakte iz Excel lista u Brevo API, plus kada koristiti Office Scripts + Power Automate i kompromisi u odnosu na postavku s Google Apps Script.

Featured image for article: Kako poslati Excel kontakte u Brevo pomoću VBA makronaredbe (i alternativa s Office Scripts)

Imate kontakte u Excelu i želite ih u Brevu. Brz i jednostavan odgovor je spremiti datoteku kao .csv i uvesti je, što je u redu jednom. Za bilo što što radite ponavljano (tjedna primopredaja prodaje, radna knjiga koju vaš tim ažurira dnevno, popis partnera koji se osvježava) želite gumb točno unutar Excela koji vrši sinkronizaciju.

Ovaj vodič pokriva dva puta koji zaista imaju smisla:

  1. VBA makronaredba ugrađena u radnu knjigu, bez licenciranja, bez oblaka, radi izvan mreže, izvršava se u trenutku kad korisnik klikne gumb. Pravi odgovor za ~80% slučajeva “Excel u Brevo”.
  2. Office Scripts + Power Automate, TypeScript umjesto VBA-a, radi u oblaku, podržava zakazane okidače. Pravi odgovor ako radna knjiga živi u OneDriveu/SharePointu i želite neaduzevu sinkronizaciju, ali budite svjesni licenciranja Power Automatea.

Ako tražite ekvivalent za Google Sheets, pogledajte popratni članak o Apps Scriptu. A ako samo želite jednokratan CSV uvoz iz skripte na svom laptopu, vodič za uvoz CSV-a ima Python, Node.js i cURL verzije.

Što makronaredba radi

Kad korisnik klikne gumb “Sync to Brevo” na listu:

  1. Pročita svaki red s aktivnog radnog lista (prvo redak zaglavlja, jedan kontakt po redu).
  2. Sastavi JSON polje oblikovano za Brevo parametar jsonBody.
  3. Šalje POST na https://api.brevo.com/v3/contacts/import s API ključem pohranjenim u radnoj knjizi.
  4. Prikaže okvir s porukom o rezultatu.

To je to. ~120 linija VBA-a. Ispod je cijeli, radni modul.

Raspored lista koji makronaredba očekuje

emailfirstNamelastNamecompanycity
[email protected]JaneDoeAcmeBerlin
[email protected]JohnSmithGlobexParis

email je obavezan. Svaki drugi stupac postaje atribut Brevo kontakta, mapiran prema zaglavlju stupca (s velikim slovima) na ime atributa. Tako firstNameFIRSTNAME, companyCOMPANY. Prilagođeni atributi (sve izvan standardnog skupa) moraju prvo postojati u vašem Brevo računu, definirajte ih pod Kontakti → Postavke → Atributi kontakta.

Korak 1: Otvorite VBA editor

U Excelu: pritisnite Alt + F11. Otvara se VBA editor. U Project ploči s lijeve strane, kliknite desnom tipkom miša svoju radnu knjigu i odaberite Insert → Module. Pojavljuje se prazan Module1.

Korak 2: Zalijepite cijelu makronaredbu

Zamijenite sadržaj Module1 ovim:

' ===========================================================================
' 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

Korak 3: Spremite radnu knjigu kao .xlsm

VBA makronaredbe ostaju samo u radnim knjigama s omogućenim makronaredbama. Save As → odaberite Excel Macro-Enabled Workbook (.xlsm). Običan .xlsx format tiho uklanja makronaredbe, mnogi ljudi tako izgube kod prvi put.

Korak 4: Konfigurirajte svoj API ključ

Pokrenite ConfigureApiKey jednom. Ili:

  • U VBA editoru, kliknite bilo gdje unutar ConfigureApiKey sub-rutine i pritisnite F5, ili
  • U Excelu, Developer → Macros, odaberite ConfigureApiKey, Run.

Zalijepite svoj xkeysib-... ključ. Makronaredba ga sprema kao prilagođeno svojstvo dokumenta unutar same radne knjige, nije u izvornom kodu, nije u registru i putuje s datotekom (zato budite svjesni: ako pošaljete .xlsm e-poštom nekome, API ključ ide s njim).

Ako biste radije stavili ključ negdje izvan radne knjige, zamijenite pohranu Windows registrom:

' Replace the body of ConfigureApiKey with:
SaveSetting "Brevo", "Sync", "ApiKey", key
' And GetApiKey with:
GetApiKey = GetSetting("Brevo", "Sync", "ApiKey", "")

SaveSetting/GetSetting piše pod HKCU\Software\VB and VBA Program Settings\Brevo\Sync, po korisniku, ne po radnoj knjizi. Koristite ovo ako više radnih knjiga treba dijeliti jedan ključ ili ako ne želite ključ u datoteci.

Korak 5: Dodajte gumb na list

Ovo je ono što pretvara stvar u iskustvo s jednim klikom za netehničke korisnike.

Insert → Shapes → Rectangle, ispustite jedan na list, označite ga “Sync to Brevo.” Desni klik na oblik → Assign Macro → odaberite SyncSheetToBrevo. Gotovo.

Ili, za poliranije sučelje, dodajte prilagođeni ribbon tab preko Office Custom UI Editora, ali za većinu internih alata, oblik kao gumb je sasvim dovoljan.

Korak 6: Pokrenite

Kliknite gumb. Makronaredba čita redove, grupira ih, šalje svaku grupu u Brevo i prikazuje sažetnu poruku. Brevo uvoz je asinkron, pa poruka o uspjehu znači “Brevo je prihvatio grupu”, stvarno stvaranje kontakata događa se serverski u sljedećih nekoliko sekundi. Dobit ćete sažetak e-poštom od Brevoa kad završi (osim ako postavite disableNotification: true).

Česte zamke

Gumb ne radi ništa i nema pogreške. Makronaredbe su onemogućene. Pogledajte žutu sigurnosnu traku na vrhu lista, kliknite Enable Content. Ako vaša organizacija blokira makronaredbe, pogledajte put trust-center / potpisivanja koda u nastavku.

Compile error: User-defined type not defined. Vi ste na Mac Excelu, koji nema MSXML2.XMLHTTP. Mac VBA ne može slati HTTPS zahtjeve izravno; umjesto toga koristite Office Scripts put u nastavku.

400 Bad Request od Brevoa bez očitog uzroka. Gotovo uvijek jedno od: (a) prilagođeni atribut u vašem listu još ne postoji u Brevu, prvo ga stvorite; (b) bug u JSON escapeanju, navodnici ili obrnute kose crte u vrijednostima ćelija koje nisu escapane. Funkcija EscapeJson u kodu obrađuje standardne slučajeve; ako vaši podaci imaju čudne znakove, zabilježite payload u prozor Immediate (Debug.Print payload) i pregledajte.

401 Unauthorized. Pogrešno zaglavlje. To je api-key (mala slova, crtica), ne Authorization. Makronaredba koristi ispravno, ali ako ste kopirali isječak odnekud drugud, dvostruko provjerite.

Excel se zamrzava na velikim uvozima. Makronaredba radi sinkrono na UI dretvi. Za 50.000+ redaka gledat ćete kako se Excel zaledi na 10-30 sekundi dok gradi JSON i čeka Brevo. Ili to prihvatite, ili prebacite MSXML2.XMLHTTP na njegovu asinkronu varijantu, ali na toj skali bolje vam je u Power Automate (sljedeći odjeljak).

Kad VBA nije dovoljno: Office Scripts + Power Automate

VBA ne može raditi zakazanu sinkronizaciju u oblaku. Ako trebate:

  • Sinkronizaciju radne knjige u Brevo svaki sat bez da je itko otvori
  • Radna knjiga u OneDriveu/SharePointu, uređena s weba
  • IT odjel koji zabranjuje desktop makronaredbe

…onda želite Office Scripts (Microsoftov ekvivalent Apps Scripta u oblaku) plus Power Automate (njihov sloj za raspored i HTTP).

Podjela: Office Scripts čita list i vraća podatke o kontaktima. Power Automate uzima te podatke i šalje ih u Brevo na okidač.

Office Script (Excel za 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;
}

Power Automate tijek:

  1. Okidač: Recurrence (svakih 1 sat), ili ručni gumb, ili “When a row is modified” ako želite sinkronizaciju potaknutu promjenom.
  2. Akcija: Excel Online → Run script, usmjerite je na svoju radnu knjigu i gornji skript. Spremite njegov povratni vrijednosti kao contacts.
  3. Akcija: HTTP (ovo je Premium konektor, vidi napomenu o licenciranju u nastavku).
    • Metoda: POST
    • URI: https://api.brevo.com/v3/contacts/import
    • Zaglavlja: api-key: xkeysib-..., Content-Type: application/json
    • Tijelo:
      {
      "jsonBody": @{outputs('Run_script')?['body/result']},
      "listIds": [42],
      "updateExistingContacts": true
      }
  4. Akcija: Condition → ako statusni kod ≠ 202, pošaljite Teams/email upozorenje.

Provjera realnosti licenciranja: akcija HTTP je Power Automate Premium konektor. Na Microsoft 365 Business Basic/Standard planovima dobivate standardne konektore, ali ne i Premium. Najjeftinije zaobilazno rješenje je dodatak Power Automate Premium (~15 USD po korisniku mjesečno u trenutku pisanja), ili premjestite HTTP u malu Azure Function koju standardni tijek može pozvati. Ako ste već na E3/E5 s uključenim Premiumom, spremni ste.

Ovo je glavni razlog zašto je priča s Apps Scriptom čišća: UrlFetchApp u Apps Scriptu je besplatan i neograničen, dok Microsoftov ekvivalent stavlja mrežni poziv iza plaćenog sloja konektora.

VBA vs Office Scripts vs Apps Script, kada odabrati što

PotrebaNajbolja opcija
Gumb s jednim klikom u radnoj knjizi koju vaš tim već dnevno otvaraVBA makronaredba (ovaj vodič, gornja polovica)
Radna knjiga u OneDriveu/SharePointu, satna automatska sinkronizacijaOffice Scripts + Power Automate (potreban Premium za HTTP)
Samo Mac Excel, ne može se koristiti VBAOffice Scripts + Power Automate
Podaci žive u Google Sheets, ne u ExceluApps Script (besplatan, ugrađeni zakazani okidači)
Jednokratan uvoz, više vam neće trebatiSave As → CSV i koristite skriptu za uvoz CSV-a
Skupni uvoz iz datoteke >10 MBCSV s fileUrl, vidi CSV vodič

Zašto je ovo bolje od Zapiera / no-code platformi

Za ponavljajući posao Excel u Brevo, alati za automatizaciju trećih strana (Zapier, Make, n8n) naplaćuju po zadatku i stavljaju treću stranu između vaših podataka i Brevoa. VBA pristup nema kontinuirane troškove, nema protok podataka kroz treću stranu i živi unutar datoteke, kad se radna knjiga premjesti, integracija ide s njom. Office Scripts + Power Automate je sličan, ali s Microsoftom kao trećom stranom (već u vašem stogu ako ste na M365).

Cijela poanta Brevo POST /v3/contacts/import endpointa je da vam ne treba ljepilo platforme, vaši alati već znaju kako slati HTTP zahtjeve.

Daljnje čitanje

Frequently Asked Questions

Može li VBA makronaredba zaista pozvati Brevo API iz Excela?
Da. VBA može slati HTTP zahtjeve preko MSXML2.XMLHTTP, koji dolazi sa svakom modernom instalacijom Windowsa. Makronaredba šalje POST JSON na api.brevo.com/v3/contacts/import, isti endpoint koji bi pogodila Python ili Node skripta. Mac Excel to također može učiniti preko Office Scripts + Power Automate, ali desktop Mac VBA ne može (nema MSXML).
Mogu li ovo pokretati po rasporedu kao Apps Script vremenske okidače?
Ne samo iz VBA-a, Excel mora biti otvoren da bi se aktivirao Application.OnTime. Za neaduzevu zakazanu sinkronizaciju imate dvije opcije: (1) Windows Task Scheduler koji otvara radnu knjigu i pokreće makronaredbu, ili (2) Office Scripts pokrenut zakazanim Power Automate tokom (obrađeno kasnije u ovom vodiču).
Je li VBA siguran? Moja tvrtka blokira makronaredbe.
VBA makronaredbe imaju pristup datotečnom sustavu i registru, pa je njihovo blokiranje prema zadanim postavkama razumna politika. Dva puta oko toga: (1) potpišite makronaredbu certifikatom za potpisivanje koda i stavite radnu knjigu u Trusted Location, ili (2) potpuno preskočite VBA i koristite Office Scripts (TypeScript, sandboxed, bez pristupa datotečnom sustavu). Office Scripts je moderan put koji Microsoft preporučuje.
Kako se to uspoređuje s Google Apps Script pristupom?
Apps Script je bliži set-and-forget, radi u Google oblaku, zakazani okidači ugrađeni, bez Excel/Power Automate licence. VBA pobjeđuje za rad izvan mreže i ručnu sinkronizaciju jednim klikom iz radne knjige koju vaš tim već ima otvorenu. Office Scripts + Power Automate su ekvivalent za oblak/raspored na Microsoft strani, ali Power Automate često zahtijeva plaćeni premium konektor za odlazni HTTP.
Započnite besplatno s Brevo