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.
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:
- 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”.
- 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:
- Pročita svaki red s aktivnog radnog lista (prvo redak zaglavlja, jedan kontakt po redu).
- Sastavi JSON polje oblikovano za Brevo parametar
jsonBody. - Šalje POST na
https://api.brevo.com/v3/contacts/imports API ključem pohranjenim u radnoj knjizi. - 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
| firstName | lastName | company | city | |
|---|---|---|---|---|
| [email protected] | Jane | Doe | Acme | Berlin |
| [email protected] | John | Smith | Globex | Paris |
email je obavezan. Svaki drugi stupac postaje atribut Brevo kontakta, mapiran prema zaglavlju stupca (s velikim slovima) na ime atributa. Tako firstName → FIRSTNAME, company → COMPANY. 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 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: 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
ConfigureApiKeysub-rutine i pritisniteF5, 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:
- Okidač: Recurrence (svakih 1 sat), ili ručni gumb, ili “When a row is modified” ako želite sinkronizaciju potaknutu promjenom.
- Akcija: Excel Online → Run script, usmjerite je na svoju radnu knjigu i gornji skript. Spremite njegov povratni vrijednosti kao
contacts. - 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}
- Metoda:
- 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
| Potreba | Najbolja opcija |
|---|---|
| Gumb s jednim klikom u radnoj knjizi koju vaš tim već dnevno otvara | VBA makronaredba (ovaj vodič, gornja polovica) |
| Radna knjiga u OneDriveu/SharePointu, satna automatska sinkronizacija | Office Scripts + Power Automate (potreban Premium za HTTP) |
| Samo Mac Excel, ne može se koristiti VBA | Office Scripts + Power Automate |
| Podaci žive u Google Sheets, ne u Excelu | Apps Script (besplatan, ugrađeni zakazani okidači) |
| Jednokratan uvoz, više vam neće trebati | Save As → CSV i koristite skriptu za uvoz CSV-a |
| Skupni uvoz iz datoteke >10 MB | CSV 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.