Πώς να στείλετε επαφές Excel στο Brevo με μακροεντολή VBA (και η εναλλακτική Office Scripts)

Μια λειτουργική μακροεντολή VBA που δημοσιεύει επαφές από φύλλο Excel στο API του Brevo με ένα κλικ. Συν, πότε να χρησιμοποιήσετε Office Scripts + Power Automate και τα συμβιβαστικά σημεία έναντι μιας ρύθμισης Google Apps Script.

Featured image for article: Πώς να στείλετε επαφές Excel στο Brevo με μακροεντολή VBA (και η εναλλακτική Office Scripts)

Έχετε επαφές στο Excel και τις θέλετε στο Brevo. Η γρήγορη και πρόχειρη απάντηση είναι να αποθηκεύσετε το αρχείο ως .csv και να το εισάγετε, που είναι εντάξει μία φορά. Για οτιδήποτε κάνετε επαναλαμβανόμενα, εβδομαδιαία παράδοση πωλήσεων, workbook που η ομάδα σας ενημερώνει καθημερινά, λίστα συνεργατών που ανανεώνεται, θέλετε ένα κουμπί ακριβώς μέσα στο Excel που να κάνει τον συγχρονισμό.

Αυτός ο οδηγός καλύπτει τις δύο διαδρομές που πραγματικά έχουν νόημα γι’ αυτό:

  1. Μια μακροεντολή VBA ενσωματωμένη στο workbook. Χωρίς αδειοδότηση, χωρίς cloud, λειτουργεί offline, εκτελείται τη στιγμή που ένας χρήστης κάνει κλικ σε κουμπί. Η σωστή απάντηση για το ~80% των περιπτώσεων «Excel σε Brevo».
  2. Office Scripts + Power Automate. TypeScript αντί για VBA, τρέχει στο cloud, υποστηρίζει προγραμματισμένα triggers. Η σωστή απάντηση αν το workbook ζει σε OneDrive/SharePoint και θέλετε συγχρονισμό χωρίς επίβλεψη, αλλά να γνωρίζετε την αδειοδότηση του Power Automate.

Αν ψάχνετε το ισοδύναμο για Google Sheets, δείτε το συνοδευτικό άρθρο για το Apps Script. Και αν θέλετε απλά μια εφάπαξ εισαγωγή CSV από script στον φορητό σας, ο οδηγός εισαγωγής CSV έχει εκδόσεις σε Python, Node.js και cURL.

Τι κάνει η μακροεντολή

Όταν ο χρήστης κάνει κλικ σε ένα κουμπί «Sync to Brevo» στο φύλλο:

  1. Διαβάζει κάθε γραμμή από το ενεργό φύλλο εργασίας (πρώτα η γραμμή κεφαλίδων, μία επαφή ανά γραμμή).
  2. Κατασκευάζει έναν πίνακα JSON σχηματισμένο για την παράμετρο jsonBody του Brevo.
  3. Κάνει POST στο https://api.brevo.com/v3/contacts/import με το αποθηκευμένο API key του workbook.
  4. Εμφανίζει ένα message box με το αποτέλεσμα.

Αυτό είναι. ~120 γραμμές VBA. Παρακάτω είναι η πλήρης, λειτουργική μονάδα.

Διάταξη φύλλου που αναμένει η μακροεντολή

emailfirstNamelastNamecompanycity
[email protected]JaneDoeAcmeBerlin
[email protected]JohnSmithGlobexParis

Το email είναι υποχρεωτικό. Κάθε άλλη στήλη γίνεται attribute επαφής Brevo, αντιστοιχισμένο μέσω της κεφαλίδας στήλης (σε κεφαλαία) στο όνομα του attribute. Έτσι firstNameFIRSTNAME, companyCOMPANY. Τα προσαρμοσμένα attributes (οτιδήποτε πέρα από το τυπικό σύνολο) πρέπει πρώτα να υπάρχουν στον λογαριασμό σας στο Brevo, ορίστε τα στο Contacts → Settings → Contact attributes.

Βήμα 1: Ανοίξτε τον VBA editor

Στο Excel: πατήστε Alt + F11. Ο VBA editor ανοίγει. Στο panel Project στα αριστερά, κάντε δεξί κλικ στο workbook σας και επιλέξτε Insert → Module. Εμφανίζεται ένα κενό Module1.

Βήμα 2: Επικολλήστε την πλήρη μακροεντολή

Αντικαταστήστε τα περιεχόμενα του Module1 με αυτό:

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

Βήμα 3: Αποθηκεύστε το workbook ως .xlsm

Οι μακροεντολές VBA διατηρούνται μόνο σε workbooks με ενεργοποιημένες μακροεντολές. Save As → επιλέξτε Excel Macro-Enabled Workbook (.xlsm). Η απλή μορφή .xlsx αφαιρεί τις μακροεντολές σιωπηλά, πολλοί άνθρωποι χάνουν κώδικα έτσι την πρώτη φορά.

Βήμα 4: Διαμορφώστε το API key σας

Εκτελέστε το ConfigureApiKey μία φορά. Είτε:

  • Στον VBA editor, κάντε κλικ οπουδήποτε μέσα στο sub ConfigureApiKey και πατήστε F5, ή
  • Στο Excel, Developer → Macros, επιλέξτε ConfigureApiKey, Run.

Επικολλήστε το κλειδί xkeysib-.... Η μακροεντολή το αποθηκεύει ως custom document property μέσα στο ίδιο το workbook, δεν είναι στον πηγαίο κώδικα, δεν είναι στο registry και ταξιδεύει με το αρχείο (οπότε προσοχή: αν στείλετε το .xlsm με email σε κάποιον, το API key πάει μαζί του).

Αν προτιμάτε να βάλετε το κλειδί κάπου εκτός του workbook, αλλάξτε την αποθήκευση στο registry των Windows:

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

Το SaveSetting/GetSetting γράφει κάτω από το HKCU\Software\VB and VBA Program Settings\Brevo\Sync, ανά χρήστη, όχι ανά workbook. Χρησιμοποιήστε το αν πολλά workbooks πρέπει να μοιράζονται ένα κλειδί, ή αν δεν θέλετε το κλειδί στο αρχείο.

Βήμα 5: Προσθέστε ένα κουμπί στο φύλλο

Αυτό είναι που το μετατρέπει σε εμπειρία ενός κλικ για μη-τεχνικούς χρήστες.

Insert → Shapes → Rectangle, ρίξτε ένα στο φύλλο, ονομάστε το «Sync to Brevo». Δεξί κλικ στο σχήμα → Assign Macro → επιλέξτε SyncSheetToBrevo. Έτοιμο.

Ή, για πιο γυαλισμένο UI, προσθέστε προσαρμοσμένη καρτέλα ribbon μέσω του Office Custom UI Editor, αλλά για τα περισσότερα εσωτερικά εργαλεία, το σχήμα-ως-κουμπί είναι αρκετό.

Βήμα 6: Εκτελέστε το

Κάντε κλικ στο κουμπί. Η μακροεντολή διαβάζει τις γραμμές, τις δημιουργεί σε batches, κάνει POST κάθε batch στο Brevo και εμφανίζει ένα συνοπτικό message box. Η εισαγωγή του Brevo είναι ασύγχρονη, οπότε το μήνυμα επιτυχίας σημαίνει «Το Brevo αποδέχθηκε το batch», η πραγματική δημιουργία επαφών συμβαίνει στην πλευρά του server τα επόμενα δευτερόλεπτα. Θα λάβετε email σύνοψης από το Brevo όταν τελειώσει (εκτός αν ορίσετε disableNotification: true).

Συνηθισμένες παγίδες

Το κουμπί δεν κάνει τίποτα και δεν υπάρχει σφάλμα. Οι μακροεντολές είναι απενεργοποιημένες. Δείτε την κίτρινη μπάρα ασφαλείας στην κορυφή του φύλλου, κάντε κλικ Enable Content. Αν ο οργανισμός σας μπλοκάρει μακροεντολές, δείτε τη διαδρομή trust-center / code-signing παρακάτω.

Compile error: User-defined type not defined. Είστε σε Mac Excel, που δεν έχει MSXML2.XMLHTTP. Το Mac VBA δεν μπορεί να κάνει HTTPS αιτήματα απευθείας, χρησιμοποιήστε τη διαδρομή Office Scripts παρακάτω.

400 Bad Request από το Brevo χωρίς προφανή αιτία. Σχεδόν πάντα ένα από: (α) ένα προσαρμοσμένο attribute στο φύλλο σας δεν υπάρχει ακόμα στο Brevo, δημιουργήστε το πρώτα; (β) bug JSON escaping, εισαγωγικά ή backslashes σε τιμές κελιών που δεν έγιναν escape. Η συνάρτηση EscapeJson στον κώδικα χειρίζεται τις τυπικές περιπτώσεις, αν τα δεδομένα σας έχουν περίεργους χαρακτήρες, καταγράψτε το payload στο Immediate window (Debug.Print payload) και ελέγξτε.

401 Unauthorized. Λάθος header. Είναι api-key (πεζά γράμματα, παύλα), όχι Authorization. Η μακροεντολή χρησιμοποιεί τη σωστή, αλλά αν αντιγράψατε snippet από αλλού, ξανατσεκάρετε.

Το Excel παγώνει σε μεγάλες εισαγωγές. Η μακροεντολή τρέχει σύγχρονα στο νήμα UI. Για 50.000+ γραμμές, θα δείτε το Excel να κρέμεται για 10 έως 30 δευτερόλεπτα ενώ χτίζει το JSON και περιμένει το Brevo. Είτε αποδεχτείτε το, είτε αλλάξτε το MSXML2.XMLHTTP στην ασύγχρονη παραλλαγή του, αλλά σε αυτή την κλίμακα είστε καλύτερα στο Power Automate (επόμενη ενότητα).

Όταν το VBA δεν είναι αρκετό: Office Scripts + Power Automate

Το VBA δεν μπορεί να κάνει προγραμματισμένο cloud συγχρονισμό. Αν χρειάζεστε:

  • Το workbook να συγχρονίζεται με το Brevo κάθε ώρα χωρίς να το ανοίγει κανείς
  • Το workbook σε OneDrive/SharePoint, επεξεργασμένο από web
  • Τμήμα IT που απαγορεύει desktop μακροεντολές

…τότε θέλετε Office Scripts (το cloud ισοδύναμο της Microsoft για το Apps Script) συν Power Automate (το επίπεδο προγραμματισμού και HTTP τους).

Ο διαχωρισμός: το Office Scripts διαβάζει το φύλλο και επιστρέφει τα δεδομένα επαφών. Το Power Automate παίρνει αυτά τα δεδομένα και τα κάνει POST στο Brevo σε ένα trigger.

Το Office Script (Excel για το 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;
}

Το flow Power Automate:

  1. Trigger: Recurrence (κάθε 1 ώρα), ή χειροκίνητο κουμπί, ή «When a row is modified» αν θέλετε συγχρονισμό βασισμένο σε αλλαγές.
  2. Action: Excel Online → Run script, στρέψτε το στο workbook σας και το script παραπάνω. Αποθηκεύστε την επιστρεφόμενη τιμή ως contacts.
  3. Action: HTTP (αυτός είναι ο Premium connector, δείτε τη σημείωση αδειοδότησης παρακάτω).
    • 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 → αν ο status code ≠ 202, στείλτε ειδοποίηση Teams/email.

Έλεγχος πραγματικότητας αδειοδότησης: η ενέργεια HTTP είναι Premium connector του Power Automate. Στα πλάνα Microsoft 365 Business Basic/Standard παίρνετε τους standard connectors αλλά όχι το Premium. Η φθηνότερη λύση είναι το πρόσθετο Power Automate Premium (~15 USD/χρήστη/μήνα τη στιγμή της συγγραφής), ή μετακινήστε το HTTP σε μια μικρή Azure Function που το standard flow μπορεί να καλέσει. Αν ήδη είστε σε E3/E5 με Premium συμπεριλαμβανόμενο, είστε έτοιμοι.

Αυτός είναι ο κύριος λόγος που η ιστορία του Apps Script είναι πιο καθαρή: το UrlFetchApp του Apps Script είναι δωρεάν και χωρίς περιορισμούς, ενώ το ισοδύναμο της Microsoft βάζει την κλήση δικτύου πίσω από επί πληρωμή connector tier.

VBA έναντι Office Scripts έναντι Apps Script: πότε επιλέγετε τι

ΑνάγκηΚαλύτερη επιλογή
Κουμπί ενός κλικ σε workbook που η ομάδα σας ήδη ανοίγει καθημερινάΜακροεντολή VBA (αυτός ο οδηγός, πάνω μισό)
Workbook σε OneDrive/SharePoint, ωριαίος αυτόματος συγχρονισμόςOffice Scripts + Power Automate (χρειάζεται Premium για HTTP)
Μόνο Mac Excel, δεν μπορείτε να χρησιμοποιήσετε VBAOffice Scripts + Power Automate
Τα δεδομένα ζουν στο Google Sheets, όχι στο ExcelApps Script (δωρεάν, προγραμματισμένα triggers ενσωματωμένα)
Εφάπαξ εισαγωγή, δεν θα τη χρειαστείτε ξανάSave As → CSV και χρησιμοποιήστε το script εισαγωγής CSV
Μαζική εισαγωγή από αρχείο >10 MBCSV με fileUrl, δείτε τον οδηγό CSV

Γιατί αυτό κερδίζει τα Zapier / no-code πλατφόρμες

Για επαναλαμβανόμενη εργασία Excel σε Brevo, εργαλεία αυτοματισμού τρίτων (Zapier, Make, n8n) χρεώνουν ανά task και βάζουν τρίτο μεταξύ των δεδομένων σας και του Brevo. Η προσέγγιση VBA έχει μηδενικό συνεχιζόμενο κόστος, χωρίς ροή δεδομένων τρίτων, και ζει μέσα στο αρχείο, όταν το workbook μετακινείται, η ενσωμάτωση μετακινείται μαζί. Το Office Scripts + Power Automate είναι παρόμοιο αλλά με τη Microsoft ως τρίτο (ήδη στο stack σας αν είστε σε M365).

Όλο το νόημα του endpoint POST /v3/contacts/import του Brevo είναι ότι δεν χρειάζεστε μια κολλητική πλατφόρμα, τα εργαλεία σας ήδη ξέρουν πώς να κάνουν HTTP αιτήματα.

Περαιτέρω ανάγνωση

Frequently Asked Questions

Μπορεί πραγματικά μια μακροεντολή VBA να καλέσει το API του Brevo από μέσα από το Excel;
Ναι. Το VBA μπορεί να κάνει HTTP αιτήματα μέσω MSXML2.XMLHTTP, που έρχεται με κάθε σύγχρονη εγκατάσταση Windows. Η μακροεντολή κάνει POST JSON στο api.brevo.com/v3/contacts/import, το ίδιο endpoint που θα χτυπούσε ένα script Python ή Node. Το Mac Excel μπορεί επίσης μέσω Office Scripts + Power Automate, αλλά το desktop Mac VBA δεν μπορεί (δεν έχει MSXML).
Μπορώ να το εκτελώ σε προγραμματισμένη βάση όπως τα time triggers του Apps Script;
Όχι μόνο από VBA. Το Excel πρέπει να είναι ανοιχτό για να ενεργοποιηθεί το Application.OnTime. Για προγραμματισμένο συγχρονισμό χωρίς επίβλεψη έχετε δύο επιλογές: (1) Windows Task Scheduler που ανοίγει το workbook και εκτελεί τη μακροεντολή, ή (2) Office Scripts που ενεργοποιείται από προγραμματισμένο Power Automate flow (καλύπτεται παρακάτω σε αυτόν τον οδηγό).
Είναι ασφαλές το VBA; Η εταιρεία μου μπλοκάρει μακροεντολές.
Οι μακροεντολές VBA τρέχουν με πρόσβαση στο σύστημα αρχείων και το registry, οπότε η εξ ορισμού απαγόρευσή τους είναι λογική πολιτική. Δύο διαδρομές γύρω από αυτό: (1) υπογράψτε τη μακροεντολή με πιστοποιητικό code-signing και βάλτε το workbook σε Trusted Location, ή (2) παραλείψτε εντελώς το VBA και χρησιμοποιήστε Office Scripts (TypeScript, σε sandbox, χωρίς πρόσβαση στο σύστημα αρχείων). Το Office Scripts είναι η σύγχρονη διαδρομή που ευλογεί η Microsoft.
Πώς συγκρίνεται με την προσέγγιση Google Apps Script;
Το Apps Script είναι πιο κοντά στο «ρύθμισε και ξέχνα», τρέχει στο cloud της Google, με προγραμματισμένα triggers ενσωματωμένα, χωρίς άδεια Excel/Power Automate. Το VBA κερδίζει για offline εργασία και χειροκίνητο συγχρονισμό με ένα κλικ από workbook που η ομάδα σας ήδη έχει ανοιχτό. Το Office Scripts + Power Automate είναι το cloud/προγραμματισμένο ισοδύναμο στην πλευρά της Microsoft, αλλά το Power Automate συχνά χρειάζεται premium connector επί πληρωμή για εξερχόμενο HTTP.
Ξεκινήστε δωρεάν με το Brevo