Kako gurnuti Excel kontakte u Brevo pomoću VBA makroa (i alternativa Office Scripts)

Funkcionalan VBA makro koji šalje kontakte iz Excel lista u Brevo API jednim klikom. Plus, kada umesto toga koristiti Office Scripts + Power Automate, i kompromisi u odnosu na rešenje sa Google Apps Script.

Featured image for article: Kako gurnuti Excel kontakte u Brevo pomoću VBA makroa (i alternativa Office Scripts)

Imate kontakte u Excelu i želite ih u Brevu. Brz i prljav odgovor je da sačuvate fajl kao .csv i uvezete ga, što je u redu jednom. Za bilo šta što radite više puta (nedeljna prodajna primopredaja, radna sveska koju vaš tim svakodnevno ažurira, partnerska lista koja se osvežava), želite dugme tačno unutar Excela koje radi sinhronizaciju.

Ovaj vodič pokriva dva puta koja stvarno imaju smisla za to:

  1. VBA makro ugrađen u radnu svesku. Bez licenciranja, bez oblaka, radi van mreže, izvršava se u trenutku kada korisnik klikne dugme. Pravi odgovor za oko 80 % slučajeva „Excel u Brevo”.
  2. Office Scripts + Power Automate. TypeScript umesto VBA, izvršava se u oblaku, podržava rasporedjene okidače. Pravi odgovor ako radna sveska živi u OneDrive/SharePoint i želite nenadgledanu sinhronizaciju, ali budite svesni licenciranja Power Automate.

Ako tražite Google Sheets ekvivalent, pogledajte prateći članak o Apps Script. A ako samo želite jednokratan CSV uvoz iz skripte na svom laptopu, vodič za uvoz CSV ima verzije u Pythonu, Node.js i cURL.

Šta makro radi

Kada korisnik klikne na dugme „Sync to Brevo” na listu:

  1. Pročita svaki red iz aktivnog radnog lista (prvo red zaglavlja, jedan kontakt po redu).
  2. Izgradi JSON niz oblikovan za Brevo jsonBody parametar.
  3. Pošalje na https://api.brevo.com/v3/contacts/import sa API ključem koji je sačuvan u radnoj svesci.
  4. Prikazuje prozor sa porukom o rezultatu.

To je sve. Oko 120 linija VBA. Ispod je ceo funkcionalan modul.

Raspored lista koji makro očekuje

emailfirstNamelastNamecompanycity
[email protected]JaneDoeAcmeBerlin
[email protected]JohnSmithGlobexParis

email je obavezan. Svaka druga kolona postaje atribut Brevo kontakta, mapiran preko zaglavlja kolone (velika slova) na ime atributa. Tako firstName postaje FIRSTNAME, company postaje COMPANY. Prilagođeni atributi (sve van standardnog skupa) moraju prvo postojati u vašem Brevo nalogu. Definišite ih pod Contacts → Settings → Contact attributes.

Korak 1: otvorite VBA editor

U Excelu: pritisnite Alt + F11. Otvara se VBA editor. U panelu Project sa leve strane, desni klik na vašu radnu svesku i izaberite Insert → Module. Pojavljuje se prazan Module1.

Korak 2: nalepite ceo makro

Zamenite 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: sačuvajte radnu svesku kao .xlsm

VBA makroi opstaju samo u radnim sveskama sa omogućenim makroima. Sačuvaj kao, izaberite Excel Macro-Enabled Workbook (.xlsm). Običan format .xlsx tiho uklanja makroe. Mnogi ljudi tako prvi put izgube kod.

Korak 4: konfigurišite svoj API ključ

Pokrenite ConfigureApiKey jednom. Bilo:

  • U VBA editoru kliknite bilo gde unutar sub ConfigureApiKey i pritisnite F5, ili
  • U Excelu Developer → Macros, izaberite ConfigureApiKey, Run.

Nalepite svoj xkeysib-... ključ. Makro ga čuva kao prilagođenu osobinu dokumenta unutar same radne sveske. Nije u izvornom kodu, nije u registru i putuje sa fajlom (pa budite svesni: ako pošaljete .xlsm imejlom nekome, API ključ ide sa njim).

Ako biste radije stavili ključ van radne sveske, prebacite skladište na Windows registar:

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

SaveSetting/GetSetting zapisuje pod HKCU\Software\VB and VBA Program Settings\Brevo\Sync, po korisniku, ne po radnoj svesci. Koristite ovo ako više radnih svesaka treba da deli jedan ključ, ili ako ne želite ključ u fajlu.

Korak 5: dodajte dugme na list

Ovo je ono što ovo pretvara u iskustvo jednog klika za netehničke korisnike.

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

Ili, za izglačaniji UI, dodajte prilagođeni ribbon tab preko Office Custom UI Editor. Ali za većinu internih alata, oblik kao dugme je sasvim dovoljan.

Korak 6: pokrenite ga

Kliknite na dugme. Makro čita redove, deli ih na pakete, šalje svaki paket u Brevo i prikazuje sumarni prozor poruke. Brevo uvoz je asinhron, pa poruka o uspehu znači „Brevo je prihvatio paket”. Stvarno kreiranje kontakata se dešava na strani servera u narednih nekoliko sekundi. Dobićete imejl sa rezimeom od Brevo kada završi (osim ako ste postavili disableNotification: true).

Česte zamke

Dugme ne radi ništa i nema greške. Makroi su onemogućeni. Pogledajte žutu sigurnosnu traku na vrhu lista i kliknite Enable Content. Ako vaša organizacija blokira makroe, pogledajte ispod put preko trust centra i potpisivanja koda.

Compile error: User-defined type not defined. Vi ste na Mac Excelu, koji nema MSXML2.XMLHTTP. Mac VBA ne može direktno da pravi HTTPS zahteve. Umesto toga koristite donji put Office Scripts.

400 Bad Request od Brevo bez očiglednog razloga. Skoro uvek jedan od: (a) prilagođeni atribut u vašem listu još ne postoji u Brevu, prvo ga kreirajte; (b) bug u JSON eskejpovanju, navodnici ili obrnute kose crte u vrednostima ćelija koje nisu eskejpovane. Funkcija EscapeJson u kodu obrađuje standardne slučajeve. Ako vaši podaci imaju čudne karaktere, zapišite payload u Immediate prozor (Debug.Print payload) i pregledajte.

401 Unauthorized. Pogrešno zaglavlje. To je api-key (mala slova, crtica), ne Authorization. Makro koristi pravo, ali ako ste isečak kopirali odnekud drugde, dvaput proverite.

Excel se zamrzava na velikim uvozima. Makro se izvršava sinhrono na UI niti. Za 50.000+ redova posmatraćete kako Excel visi 10 do 30 sekundi dok gradi JSON i čeka Brevo. Ili to prihvatite, ili prebacite MSXML2.XMLHTTP na njegovu asinhronu varijantu. Ali na toj skali bolje vam je u Power Automate (sledeći odeljak).

Kada VBA nije dovoljno: Office Scripts + Power Automate

VBA ne može da radi rasporedjenu oblak sinhronizaciju. Ako vam treba:

  • Da se radna sveska sinhronizuje sa Brevo svakog sata bez da je iko otvori
  • Radna sveska u OneDrive/SharePoint, uređivana sa veba
  • IT odeljenje koje zabranjuje desktop makroe

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

Podela: 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 veb, 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 tok:

  1. Trigger: Recurrence (svakog 1 sata), ili ručno dugme, ili „When a row is modified” ako želite sinhronizaciju vođenu promenama.
  2. Action: Excel Online → Run script. Uperite ga na vašu radnu svesku i gornju skriptu. Sačuvajte njenu povratnu vrednost kao contacts.
  3. Action: HTTP (ovo je Premium konektor, vidite napomenu o licenciranju ispod).
    • 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. Ako status kod nije 202, pošaljite Teams/imejl upozorenje.

Provera realnosti licenciranja: akcija HTTP je Premium konektor Power Automate. Na planovima Microsoft 365 Business Basic/Standard dobijate standardne konektore, ali ne i Premium. Najjeftinija obilaznica je dodatak Power Automate Premium (oko 15 USD po korisniku mesečno u trenutku pisanja), ili premestite HTTP u malu Azure Function koju standardni tok može pozvati. Ako ste već na E3/E5 sa uključenim Premium, spremni ste.

To je glavni razlog zašto je Apps Script priča čistija: UrlFetchApp u Apps Script je besplatan i bez ograničenja, dok Microsoft ekvivalent stavlja mrežni poziv iza plaćenog nivoa konektora.

VBA naspram Office Scripts naspram Apps Script: kada izabrati šta

PotrebaNajbolja opcija
Dugme jednog klika u radnoj svesci koju vaš tim već svakodnevno otvaraVBA makro (ovaj vodič, gornja polovina)
Radna sveska u OneDrive/SharePoint, satna automatska sinhronizacijaOffice Scripts + Power Automate (treba Premium za HTTP)
Samo Mac Excel, ne može da koristi VBAOffice Scripts + Power Automate
Podaci žive u Google Sheets, ne u ExceluApps Script (besplatno, rasporedjeni okidači ugrađeni)
Jednokratan uvoz, nikad više neće trebatiSave As → CSV i koristite skriptu za uvoz CSV
Masovni uvoz iz fajla >10 MBCSV sa fileUrl, pogledajte CSV vodič

Zašto ovo pobeđuje Zapier i no-code platforme

Za ponavljajući Excel-u-Brevo posao, alati za automatizaciju treće strane (Zapier, Make, n8n) naplaćuju po zadatku i stavljaju treću stranu između vaših podataka i Brevo. VBA pristup ima nulte tekuće troškove, nikakav tok podataka treće strane, i živi unutar fajla. Kada se radna sveska premesti, integracija se premešta sa njom. Office Scripts + Power Automate je slično, ali sa Microsoftom kao trećom stranom (već u vašem stack-u ako ste na M365).

Cela poenta endpointa Brevo POST /v3/contacts/import je da vam ne treba lepak platforma. Vaši alati već znaju kako da prave HTTP zahteve.

Dalje čitanje

Frequently Asked Questions

Može li VBA makro stvarno pozvati Brevo API iz Excela?
Da. VBA može da pravi HTTP zahteve preko MSXML2.XMLHTTP, koji dolazi sa svakom modernom instalacijom Windows-a. Makro šalje JSON na api.brevo.com/v3/contacts/import, isti endpoint koji bi pogodila Python ili Node skripta. Mac Excel to takođe može preko Office Scripts + Power Automate, ali desktop Mac VBA ne može (nema MSXML).
Mogu li ovo da pokrećem po rasporedu kao vremenske okidače u Apps Script?
Ne iz samog VBA. Excel mora biti otvoren da bi se Application.OnTime aktivirao. Za nenadgledanu sinhronizaciju po rasporedu imate dve opcije: (1) Windows Task Scheduler koji otvara radnu svesku i pokreće makro, ili (2) Office Scripts okidan rasporedjenim Power Automate tokom (pokriveno kasnije u ovom vodiču).
Da li je VBA bezbedan? Moja kompanija blokira makroe.
VBA makroi se izvršavaju sa pristupom fajl sistemu i registru, pa je njihovo podrazumevano blokiranje razumna politika. Dva puta okolo: (1) potpišite makro sertifikatom za potpisivanje koda i stavite radnu svesku u Trusted Location, ili (2) potpuno preskočite VBA i koristite Office Scripts (TypeScript, sandbox, bez pristupa fajl sistemu). Office Scripts je moderan put koji Microsoft blagosilja.
Kako se ovo poredi sa Google Apps Script pristupom?
Apps Script je bliže „postavi i zaboravi”: izvršava se u Google oblaku, rasporedjeni okidači su ugrađeni, bez Excel/Power Automate licence. VBA pobeđuje za rad van mreže i ručnu sinhronizaciju jednim klikom iz radne sveske koju vaš tim već ima otvorenu. Office Scripts + Power Automate je oblak/rasporedjen ekvivalent na Microsoft strani, ali Power Automate često zahteva plaćeni premium konektor za odlazni HTTP.
Započnite besplatno sa Brevo