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.
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:
- 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”.
- 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:
- Pročita svaki red iz aktivnog radnog lista (prvo red zaglavlja, jedan kontakt po redu).
- Izgradi JSON niz oblikovan za Brevo
jsonBodyparametar. - Pošalje na
https://api.brevo.com/v3/contacts/importsa API ključem koji je sačuvan u radnoj svesci. - Prikazuje prozor sa porukom o rezultatu.
To je sve. Oko 120 linija VBA. Ispod je ceo funkcionalan modul.
Raspored lista koji makro očekuje
| firstName | lastName | company | city | |
|---|---|---|---|---|
| [email protected] | Jane | Doe | Acme | Berlin |
| [email protected] | John | Smith | Globex | Paris |
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 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 FunctionKorak 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
ConfigureApiKeyi pritisniteF5, 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:
- Trigger: Recurrence (svakog 1 sata), ili ručno dugme, ili „When a row is modified” ako želite sinhronizaciju vođenu promenama.
- Action: Excel Online → Run script. Uperite ga na vašu radnu svesku i gornju skriptu. Sačuvajte njenu povratnu vrednost kao
contacts. - 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}
- Method:
- 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
| Potreba | Najbolja opcija |
|---|---|
| Dugme jednog klika u radnoj svesci koju vaš tim već svakodnevno otvara | VBA makro (ovaj vodič, gornja polovina) |
| Radna sveska u OneDrive/SharePoint, satna automatska sinhronizacija | Office Scripts + Power Automate (treba Premium za HTTP) |
| Samo Mac Excel, ne može da koristi VBA | Office Scripts + Power Automate |
| Podaci žive u Google Sheets, ne u Excelu | Apps Script (besplatno, rasporedjeni okidači ugrađeni) |
| Jednokratan uvoz, nikad više neće trebati | Save As → CSV i koristite skriptu za uvoz CSV |
| Masovni uvoz iz fajla >10 MB | CSV 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.