Hogyan küldd át az Excel kapcsolatokat a Brevóba VBA makróval (és az Office Scripts alternatíva)
Egy működő VBA makró, ami egy kattintással átküldi az Excel táblád kapcsolatait a Brevo API-ra, plusz mikor érdemes inkább Office Scripts + Power Automate megoldást választani, és a Google Apps Script beállítással szembeni kompromisszumok.
Vannak kapcsolataid az Excelben, és szeretnéd őket a Brevóban. A gyors és piszkos válasz az, hogy elmented .csv-ként és importálod, ami egyszer rendben van. Bármire, amit ismételten csinálsz, heti értékesítési átadás, egy munkafüzet, amit a csapat naponta frissít, partnerlista, ami friss adatokkal jön, gombot szeretnél magában az Excelben, ami elvégzi a szinkront.
Ez az útmutató a két olyan utat mutatja be, amelyek tényleg értelmesek erre:
- VBA makró a munkafüzetbe ágyazva, nincs licenc, nincs felhő, offline is működik, abban a pillanatban fut, amikor a felhasználó megnyom egy gombot. A megfelelő válasz az “Excel-to-Brevo” esetek nagyjából 80%-ára.
- Office Scripts + Power Automate, TypeScript a VBA helyett, a felhőben fut, támogatja az ütemezett triggereket. A megfelelő válasz, ha a munkafüzet OneDrive-on/SharePoint-on van, és felügyelet nélküli szinkront szeretnél, de számolj a Power Automate licenceléssel.
Ha a Google Sheets megfelelőt keresed, nézd meg a kapcsolódó cikket az Apps Scriptről. Ha pedig csak egy egyszeri CSV importot szeretnél a laptopodról, a CSV import útmutatóban Python, Node.js és cURL verziók is vannak.
Mit csinál a makró
Amikor a felhasználó rákattint a “Sync to Brevo” gombra a táblán:
- Beolvassa az aktív munkalap minden sorát (fejléc-sor először, egy kapcsolat soronként).
- Felépít egy JSON tömböt a Brevo
jsonBodyparaméteréhez igazítva. - POST-olja a
https://api.brevo.com/v3/contacts/importcímre a munkafüzetben tárolt API kulccsal. - Megjeleníti az eredményt egy üzenetdobozban.
Ennyi. Nagyjából 120 sornyi VBA. Lentebb a teljes, működő modul.
A makró által várt táblaelrendezés
| firstName | lastName | company | city | |
|---|---|---|---|---|
| [email protected] | Jane | Doe | Acme | Berlin |
| [email protected] | John | Smith | Globex | Paris |
Az email kötelező. Minden más oszlop Brevo kapcsolat-attribútum lesz, az oszlop fejléce (nagybetűsítve) az attribútum nevéhez van rendelve. Tehát firstName -> FIRSTNAME, company -> COMPANY. Az egyéni attribútumoknak (a standardokon túl bárminek) először létezniük kell a Brevo fiókodban, definiáld őket a Contacts -> Settings -> Contact attributes alatt.
1. lépés: nyisd meg a VBA szerkesztőt
Excelben: nyomd meg az Alt + F11 billentyűkombinációt. Megnyílik a VBA szerkesztő. Bal oldalt a Project panelen kattints jobbgombbal a munkafüzetedre, és válaszd az Insert -> Module opciót. Megjelenik egy üres Module1.
2. lépés: illeszd be a teljes makrót
Cseréld le a Module1 tartalmát erre:
' ===========================================================================' 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 Function3. lépés: mentsd el a munkafüzetet .xlsm-ként
A VBA makrók csak makró-engedélyezett munkafüzetekben maradnak meg. Save As, válaszd az Excel Macro-Enabled Workbook (.xlsm) opciót. Az egyszerű .xlsx formátum csendben eldobja a makrókat, sokan így vesztik el a kódjukat először.
4. lépés: konfiguráld az API kulcsodat
Futtasd a ConfigureApiKey makrót egyszer. Vagy:
- A VBA szerkesztőben kattints a
ConfigureApiKeysub bárhova belülre, és nyomd meg azF5billentyűt, vagy - Excelben Developer -> Macros, válaszd a
ConfigureApiKey-t, Run.
Illeszd be az xkeysib-... kulcsodat. A makró egyéni dokumentum-tulajdonságként tárolja magában a munkafüzetben, nem a forráskódban, nem a registryben, és a fájllal együtt utazik (tehát figyelj: ha elküldöd az .xlsm-et valakinek, az API kulcs is vele megy).
Ha inkább a munkafüzeten kívül szeretnéd tárolni a kulcsot, váltsd át a tárolást a Windows registryre:
' Replace the body of ConfigureApiKey with:SaveSetting "Brevo", "Sync", "ApiKey", key
' And GetApiKey with:GetApiKey = GetSetting("Brevo", "Sync", "ApiKey", "")A SaveSetting/GetSetting a HKCU\Software\VB and VBA Program Settings\Brevo\Sync alá ír, felhasználónként, nem munkafüzetenként. Ezt akkor használd, ha több munkafüzetnek kell ugyanazt a kulcsot megosztania, vagy ha nem akarod, hogy a kulcs a fájlban legyen.
5. lépés: tegyél egy gombot a táblára
Ez az, ami egykattintásos élménnyé teszi nem-műszaki felhasználók számára.
Insert -> Shapes -> Rectangle, dobj egyet a táblára, címkézd “Sync to Brevo” felirattal. Jobb klikk az alakzatra -> Assign Macro -> válaszd a SyncSheetToBrevo-t. Kész.
Vagy egy csiszoltabb felülethez adj hozzá egy egyéni szalagfület az Office Custom UI Editorral, de a legtöbb belső eszközhöz az alakzat-mint-gomb bőven elég.
6. lépés: futtasd
Kattints a gombra. A makró beolvassa a sorokat, csomagokra bontja, csomagonként POST-olja a Brevónak, és üzenetdobozban összegzést mutat. A Brevo importja aszinkron, tehát a sikerüzenet azt jelenti, hogy “a Brevo elfogadta a csomagot”, a tényleges kapcsolat-létrehozás a szerver oldalon történik a következő néhány másodpercben. A Brevótól e-mail összegzést kapsz, amikor befejeződik (kivéve, ha a disableNotification: true van beállítva).
Gyakori csapdák
A gomb nem csinál semmit, és nincs hibaüzenet. A makrók le vannak tiltva. Nézd meg a sárga biztonsági sávot a tábla tetején, kattints az Enable Content gombra. Ha a céged tiltja a makrókat, nézd meg a trust-center / code-signing utat alább.
Compile error: User-defined type not defined. Mac Excelen vagy, amin nincs MSXML2.XMLHTTP. A Mac VBA közvetlenül nem tud HTTPS kéréseket küldeni; használd inkább az Office Scripts utat alább.
400 Bad Request a Brevótól látható ok nélkül. Szinte mindig az alábbiak egyike: (a) egy egyéni attribútum a táblában még nem létezik a Brevóban, hozd létre először; (b) JSON-escape hiba, idézőjelek vagy backslash-ek a cellaértékben, amiket nem escape-eltünk. A kódban lévő EscapeJson függvény a standard eseteket kezeli; ha az adatban furcsa karakterek vannak, naplózd a payload-ot az Immediate ablakba (Debug.Print payload) és vizsgáld meg.
401 Unauthorized. Rossz fejléc. api-key (kisbetű, kötőjel), nem Authorization. A makró a megfelelőt használja, de ha máshonnan másoltál snippetet, ellenőrizd kétszer.
Az Excel lefagy nagy importoknál. A makró szinkron módon fut a UI szálon. 50 000+ sornál nézheted, ahogy az Excel 10-30 másodpercig lefagy, miközben a JSON-t építi és a Brevóra vár. Vagy fogadd el, vagy válts a MSXML2.XMLHTTP aszinkron variánsára, de ekkora volumennél jobban jársz a Power Automate-tel (következő szakasz).
Amikor a VBA nem elég: Office Scripts + Power Automate
A VBA nem tud ütemezett felhős szinkront. Ha az kell, hogy:
- A munkafüzet óránként szinkronizálódjon a Brevóval anélkül, hogy bárki megnyitná
- A munkafüzet OneDrive-on/SharePoint-on legyen, webről szerkesztve
- IT-osztály, ami tiltja az asztali makrókat
…akkor Office Scriptset (a Microsoft felhős megfelelője az Apps Scriptnek) plusz Power Automate-et (az ütemezésre és HTTP-re szolgáló réteget) szeretnél.
A megosztás: az Office Scripts beolvassa a táblát és visszaadja a kapcsolat-adatokat. A Power Automate veszi azt az adatot és POST-olja a Brevóra trigger alapján.
Az Office Script (Excel a weben -> 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;}A Power Automate folyamat:
- Trigger: Recurrence (óránként), vagy manuális gomb, vagy “When a row is modified”, ha változás-vezérelt szinkront szeretnél.
- Action: Excel Online -> Run script, mutasd a munkafüzetedre és a fenti scriptre. Mentsd el a visszatérési értéket
contactsnéven. - Action: HTTP (ez a Premium konnektor, lásd a licencelési megjegyzést alább).
- 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 -> ha a státuszkód nem 202, küldj Teams/email riasztást.
Licencelés-realitás-ellenőrzés: a HTTP action a Power Automate Premium konnektor. Microsoft 365 Business Basic/Standard csomagokon megkapod a standard konnektorokat, de a Premiumot nem. A legolcsóbb áthidaló megoldás a Power Automate Premium kiegészítő (~15 USD/felhasználó/hónap a cikk írásakor), vagy költöztesd át a HTTP-t egy kis Azure Functionre, amit a standard folyamat hívhat. Ha már E3/E5-ön vagy Premiummal, készen állsz.
Ez a fő oka annak, hogy az Apps Script sztori tisztább: az Apps Script UrlFetchApp ingyenes és korlátlan, míg a Microsoft megfelelője a hálózati hívást fizetős konnektor-rétegbe teszi.
VBA vs Office Scripts vs Apps Script: mikor melyiket válaszd
| Igény | Legjobb opció |
|---|---|
| Egykattintásos gomb egy munkafüzetben, amit a csapatod úgyis nyitva tart | VBA makró (ez az útmutató, felső fele) |
| Munkafüzet OneDrive-on/SharePoint-on, óránkénti automatikus szinkron | Office Scripts + Power Automate (Premium kell HTTP-hez) |
| Csak Mac Excel, nem használhatsz VBA-t | Office Scripts + Power Automate |
| Az adat Google Sheetsben él, nem Excelben | Apps Script (ingyenes, beépített ütemezett triggerek) |
| Egyszeri import, soha többet nem kell | Save As -> CSV és CSV import script |
| Tömeges import 10 MB-nál nagyobb fájlból | CSV fileUrl-lel, lásd a CSV útmutatót |
Miért jobb ez, mint a Zapier / no-code platformok
Ismétlődő Excel-Brevo munkára a harmadik féltől származó automatizációs eszközök (Zapier, Make, n8n) feladatonként számláznak, és egy harmadik felet tesznek az adataid és a Brevo közé. A VBA megközelítésnek nulla a folyamatos költsége, nincs harmadik féltől származó adatáramlás, és a fájlon belül él, amikor a munkafüzet költözik, az integráció vele költözik. Az Office Scripts + Power Automate hasonló, de a Microsoft a harmadik fél (már a stackedben van, ha M365-ön vagy).
A Brevo POST /v3/contacts/import végpontjának egész lényege, hogy nincs szükséged ragasztó-platformra, az eszközeid már tudják, hogyan kell HTTP kéréseket küldeni.