Excel Kişilerini Bir VBA Makrosuyla Brevo'ya Gönderme (ve Office Scripts Alternatifi)
Bir Excel sayfasından kişileri tek tıkla Brevo API'sine gönderen çalışan bir VBA makrosu. Ayrıca ne zaman Office Scripts + Power Automate kullanılmalı, Google Apps Script kurulumuna kıyasla ödünleşmeler.
Excel’de kişileriniz var ve onları Brevo’da istiyorsunuz. Hızlı ve kolay cevap, dosyayı .csv olarak kaydedip içe aktarmaktır, bu bir kez için iyidir. Tekrar tekrar yaptığınız herhangi bir şey için (haftalık satış teslimi, ekibinizin günlük güncellediği bir çalışma kitabı, yenilenen bir iş ortağı listesi) Excel’in içinde senkronizasyonu yapan bir düğme istersiniz.
Bu kılavuz bunun için gerçekten anlamlı olan iki yolu kapsar:
- Çalışma kitabına gömülü bir VBA makrosu: lisans yok, bulut yok, çevrimdışı çalışır, bir kullanıcı bir düğmeye tıkladığı an çalışır. “Excel’den Brevo’ya” vakalarının yaklaşık %80’i için doğru cevap.
- Office Scripts + Power Automate: VBA yerine TypeScript, bulutta çalışır, zamanlanmış tetikleyicileri destekler. Çalışma kitabı OneDrive/SharePoint’te yaşıyorsa ve gözetimsiz senkronizasyon istiyorsanız doğru cevap, ancak Power Automate lisanslamasının farkında olun.
Google Sheets eşdeğerini arıyorsanız, Apps Script üzerine eşlik eden makaleye bakın. Ve dizüstü bilgisayarınızdaki bir komut dosyasından yalnızca tek seferlik bir CSV içe aktarımı istiyorsanız, CSV içe aktarma kılavuzunda Python, Node.js ve cURL sürümleri vardır.
Makronun yaptığı şey
Bir kullanıcı sayfadaki “Brevo’ya Senkronize Et” düğmesine tıkladığında:
- Etkin çalışma sayfasından her satırı okur (önce başlık satırı, satır başına bir kişi).
- Brevo’nun
jsonBodyparametresi için şekillendirilmiş bir JSON dizisi oluşturur. - Bunu çalışma kitabının saklanan API anahtarıyla
https://api.brevo.com/v3/contacts/importadresine POST eder. - Sonucu bir mesaj kutusuyla gösterir.
Hepsi bu. ~120 satır VBA. Aşağıda tam, çalışan modül var.
Makronun beklediği sayfa düzeni
| firstName | lastName | company | city | |
|---|---|---|---|---|
| [email protected] | Jane | Doe | Acme | Berlin |
| [email protected] | John | Smith | Globex | Paris |
email zorunludur. Diğer her sütun bir Brevo kişi özniteliği olur, sütun başlığıyla (büyük harfle) öznitelik adına eşlenir. Yani firstName → FIRSTNAME, company → COMPANY. Özel öznitelikler (standart kümenin ötesindeki herhangi bir şey) Brevo hesabınızda önce mevcut olmalıdır. Bunları Kişiler → Ayarlar → Kişi öznitelikleri altında tanımlayın.
Adım 1: VBA editörünü açın
Excel’de: Alt + F11 tuşlarına basın. VBA editörü açılır. Soldaki Project bölmesinde, çalışma kitabınıza sağ tıklayın ve Insert → Module seçin. Boş bir Module1 görünür.
Adım 2: Tam makroyu yapıştırın
Module1’in içeriğini bununla değiştirin:
' ===========================================================================' 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 FunctionAdım 3: Çalışma kitabını .xlsm olarak kaydedin
VBA makroları yalnızca makro etkin çalışma kitaplarında kalıcıdır. Farklı Kaydet → Excel Macro-Enabled Workbook (.xlsm) seçin. Düz .xlsx biçimi makroları sessizce siler. Birçok kişi kodunu ilk seferde bu şekilde kaybeder.
Adım 4: API anahtarınızı yapılandırın
ConfigureApiKey öğesini bir kez çalıştırın. Ya:
- VBA editöründe,
ConfigureApiKeyalt yordamının içine herhangi bir yere tıklayın veF5tuşuna basın ya da - Excel’de, Developer → Macros,
ConfigureApiKeyseçin, Run.
xkeysib-... anahtarınızı yapıştırın. Makro onu çalışma kitabının kendi içinde özel bir belge özelliği olarak saklar. Kaynak kodda değil, kayıt defterinde değil ve dosyayla seyahat eder (yani dikkatli olun: .xlsm dosyasını birine e-postayla gönderirseniz, API anahtarı da onunla birlikte gider).
Anahtarı çalışma kitabının dışında bir yere koymayı tercih ederseniz, depolamayı Windows kayıt defterine değiştirin:
' 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 altına yazar (kullanıcı başına, çalışma kitabı başına değil). Birden fazla çalışma kitabının tek bir anahtarı paylaşması gerekiyorsa veya anahtarın dosyada olmasını istemiyorsanız bunu kullanın.
Adım 5: Sayfaya bir düğme ekleyin
Bu, onu teknik olmayan kullanıcılar için tek tıklık bir deneyime dönüştüren şeydir.
Insert → Shapes → Rectangle, sayfaya bir tane bırakın, “Brevo’ya Senkronize Et” olarak etiketleyin. Şekle sağ tıklayın → Assign Macro → SyncSheetToBrevo seçin. Bitti.
Veya daha cilalı bir UI için, Office Custom UI Editor üzerinden özel bir şerit sekmesi ekleyin. Ancak çoğu dahili araç için, şekil-düğme yeterlidir.
Adım 6: Çalıştırın
Düğmeye tıklayın. Makro satırları okur, gruplar, her grubu Brevo’ya gönderir ve bir özet mesaj kutusu gösterir. Brevo’nun içe aktarması asenkrondur, dolayısıyla başarı mesajı “Brevo grubu kabul etti” anlamına gelir, gerçek kişi oluşturma sunucu tarafında sonraki birkaç saniye içinde gerçekleşir. Bittiğinde Brevo’dan bir e-posta özeti alacaksınız (eğer disableNotification: true ayarlamadıysanız).
Yaygın tuzaklar
Düğme hiçbir şey yapmıyor ve hata yok. Makrolar devre dışı. Sayfanın üstündeki sarı güvenlik çubuğuna bakın, Enable Content öğesine tıklayın. Kuruluşunuz makroları engelliyorsa, aşağıdaki güven merkezi/kod imzalama yoluna bakın.
Compile error: User-defined type not defined. MSXML2.XMLHTTP içermeyen Mac Excel’desiniz. Mac VBA HTTPS isteklerini doğrudan yapamaz; bunun yerine aşağıdaki Office Scripts yolunu kullanın.
Brevo’dan belirgin nedeni olmayan 400 Bad Request. Neredeyse her zaman şunlardan biri: (a) sayfanızdaki bir özel öznitelik henüz Brevo’da yok (önce oluşturun); (b) JSON escape hatası (escape edilmemiş hücre değerlerindeki tırnak işaretleri veya ters eğik çizgiler). Koddaki EscapeJson işlevi standart durumları yönetir; verilerinizde garip karakterler varsa, payload’ı Immediate penceresine günlüğe kaydedin (Debug.Print payload) ve inceleyin.
401 Unauthorized. Yanlış üst bilgi. Bu api-key (küçük harf, tire), Authorization değil. Makro doğru olanı kullanır, ancak başka bir yerden bir kod parçacığı kopyaladıysanız, tekrar kontrol edin.
Excel büyük içe aktarmalarda donuyor. Makro UI iş parçacığında senkron olarak çalışır. 50.000+ satır için, JSON oluştururken ve Brevo’yu beklerken Excel’in 10-30 saniye askıda kaldığını izleyeceksiniz. Ya bunu kabul edin ya da MSXML2.XMLHTTP’yi asenkron varyantına geçirin, ancak bu ölçekte Power Automate’te (sonraki bölüm) daha iyi durumdasınız.
VBA yeterli olmadığında: Office Scripts + Power Automate
VBA zamanlanmış bulut senkronizasyonu yapamaz. İhtiyaçlarınız:
- Çalışma kitabının kimse açmadan her saat Brevo’ya senkronize olması
- Çalışma kitabının web’den düzenlendiği OneDrive/SharePoint’te olması
- Masaüstü makrolarını yasaklayan bir BT departmanı
…ise Office Scripts (Microsoft’un Apps Script bulut eşdeğeri) artı Power Automate (zamanlama ve HTTP katmanları) istersiniz.
Bölünme: Office Scripts sayfayı okur ve kişi verilerini döndürür. Power Automate bu verileri alır ve bir tetikleyicide Brevo’ya POST eder.
Office Script (web için Excel → 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 akışı:
- Tetikleyici: Recurrence (her 1 saatte bir), veya manuel düğme veya değişiklik odaklı senkronizasyon istiyorsanız “When a row is modified”.
- Eylem: Excel Online → Run script: çalışma kitabınıza ve yukarıdaki betiğe yönlendirin. Dönüş değerini
contactsolarak kaydedin. - Eylem: HTTP (bu Premium bağlayıcıdır, aşağıdaki lisanslama notuna bakın).
- 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:
- Eylem: Condition → durum kodu 202 değilse, Teams/e-posta uyarısı gönder.
Lisanslama gerçeklik kontrolü: HTTP eylemi bir Power Automate Premium bağlayıcısıdır. Microsoft 365 Business Basic/Standard planlarında standart bağlayıcılar alırsınız ancak Premium almazsınız. En ucuz geçici çözüm Power Automate Premium eklentisidir (yazıldığı sırada kullanıcı/ay başına yaklaşık 15 ABD doları) veya HTTP’yi standart akışın çağırabileceği küçük bir Azure Function’a taşıyın. Premium dahil E3/E5’teyseniz, hazırsınız.
Apps Script hikayesinin daha temiz olmasının ana nedeni budur: Apps Script’in UrlFetchApp paketi ücretsiz ve kısıtlamasızdır, Microsoft eşdeğeri ise ağ çağrısını ücretli bir bağlayıcı katmanının arkasına koyar.
VBA mı, Office Scripts mi, Apps Script mi: ne zaman hangisini seçmeli
| İhtiyaç | En iyi seçenek |
|---|---|
| Ekibinizin zaten her gün açtığı bir çalışma kitabında tek tıklık düğme | VBA makrosu (bu kılavuz, üst yarı) |
| OneDrive/SharePoint’teki çalışma kitabı, saatlik otomatik senkronizasyon | Office Scripts + Power Automate (HTTP için Premium gerekir) |
| Yalnızca Mac Excel, VBA kullanılamıyor | Office Scripts + Power Automate |
| Veriler Excel’de değil, Google Sheets’te yaşıyor | Apps Script (ücretsiz, zamanlanmış tetikleyiciler yerleşik) |
| Tek seferlik içe aktarım, bir daha asla gerekmeyecek | Save As → CSV ve CSV içe aktarma komut dosyası |
| 10 MB’dan büyük dosyadan toplu içe aktarım | fileUrl ile CSV: CSV kılavuzuna bakın |
Bu neden Zapier ve no-code platformlarını yener
Yinelenen bir Excel’den Brevo’ya işi için, üçüncü taraf otomasyon araçları (Zapier, Make, n8n) görev başına ücret alır ve verileriniz ile Brevo arasına bir üçüncü taraf koyar. VBA yaklaşımının sıfır süregelen maliyeti, üçüncü taraf veri akışı yoktur ve dosyanın içinde yaşar (çalışma kitabı taşındığında, entegrasyon onunla birlikte taşınır). Office Scripts + Power Automate benzerdir ancak Microsoft üçüncü taraf olarak (M365’teyseniz zaten yığınınızdadır).
Brevo’nun POST /v3/contacts/import uç noktasının tüm amacı, bir tutkal platformuna ihtiyacınız olmamasıdır. Araçlarınız zaten HTTP istekleri yapmayı bilir.