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.

Featured image for article: Excel Kişilerini Bir VBA Makrosuyla Brevo'ya Gönderme (ve Office Scripts Alternatifi)

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:

  1. Ç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.
  2. 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:

  1. Etkin çalışma sayfasından her satırı okur (önce başlık satırı, satır başına bir kişi).
  2. Brevo’nun jsonBody parametresi için şekillendirilmiş bir JSON dizisi oluşturur.
  3. Bunu çalışma kitabının saklanan API anahtarıyla https://api.brevo.com/v3/contacts/import adresine POST eder.
  4. 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

emailfirstNamelastNamecompanycity
[email protected]JaneDoeAcmeBerlin
[email protected]JohnSmithGlobexParis

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 firstNameFIRSTNAME, companyCOMPANY. Ö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 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

Adı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, ConfigureApiKey alt yordamının içine herhangi bir yere tıklayın ve F5 tuşuna basın ya da
  • Excel’de, Developer → Macros, ConfigureApiKey seç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 MacroSyncSheetToBrevo 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ışı:

  1. Tetikleyici: Recurrence (her 1 saatte bir), veya manuel düğme veya değişiklik odaklı senkronizasyon istiyorsanız “When a row is modified”.
  2. Eylem: Excel Online → Run script: çalışma kitabınıza ve yukarıdaki betiğe yönlendirin. Dönüş değerini contacts olarak kaydedin.
  3. 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
      }
  4. 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üğmeVBA makrosu (bu kılavuz, üst yarı)
OneDrive/SharePoint’teki çalışma kitabı, saatlik otomatik senkronizasyonOffice Scripts + Power Automate (HTTP için Premium gerekir)
Yalnızca Mac Excel, VBA kullanılamıyorOffice Scripts + Power Automate
Veriler Excel’de değil, Google Sheets’te yaşıyorApps Script (ücretsiz, zamanlanmış tetikleyiciler yerleşik)
Tek seferlik içe aktarım, bir daha asla gerekmeyecekSave As → CSV ve CSV içe aktarma komut dosyası
10 MB’dan büyük dosyadan toplu içe aktarımfileUrl 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.

Daha fazla okuma

Frequently Asked Questions

Bir VBA makrosu Excel'in içinden Brevo'nun API'sini gerçekten çağırabilir mi?
Evet. VBA, her modern Windows kurulumunda gelen MSXML2.XMLHTTP üzerinden HTTP istekleri yapabilir. Makro, JSON'u api.brevo.com/v3/contacts/import adresine POST eder, bir Python veya Node komut dosyasının vuracağı aynı uç noktadır. Mac Excel bunu Office Scripts + Power Automate üzerinden yapabilir, ancak masaüstü Mac VBA yapamaz (MSXML yok).
Bunu Apps Script zaman tetikleyicileri gibi zamanlanmış olarak çalıştırabilir miyim?
Yalnızca VBA'dan çalıştıramazsınız. Application.OnTime'ın ateşlenmesi için Excel'in açık olması gerekir. Gözetimsiz zamanlanmış senkronizasyon için iki seçeneğiniz vardır: (1) çalışma kitabını açıp makroyu çalıştıran Windows Görev Zamanlayıcısı veya (2) bir Power Automate zamanlanmış akışıyla tetiklenen Office Scripts (bu kılavuzun ilerleyen kısımlarında ele alınmıştır).
VBA güvenli mi? Şirketim makroları engelliyor.
VBA makroları dosya sistemi ve kayıt defteri erişimiyle çalışır, dolayısıyla bunları varsayılan olarak engellemek mantıklı bir politikadır. Bunu aşmak için iki yol vardır: (1) makroyu bir kod imzalama sertifikasıyla imzalayın ve çalışma kitabını Güvenilir Konuma yerleştirin veya (2) VBA'yı tamamen atlayın ve Office Scripts (TypeScript, sandbox, dosya sistemi erişimi yok) kullanın. Office Scripts modern Microsoft onaylı yoldur.
Bu, Google Apps Script yaklaşımıyla nasıl karşılaştırılır?
Apps Script kur-ve-unut yaklaşımına daha yakındır. Google'ın bulutunda çalışır, zamanlanmış tetikleyiciler yerleşiktir, Excel/Power Automate lisansı gerekmez. VBA, çevrimdışı çalışma ve ekibinizin zaten açık tuttuğu bir çalışma kitabından tek tıkla manuel senkronizasyon için kazanır. Office Scripts + Power Automate Microsoft tarafındaki bulut/zamanlanmış eşdeğerdir, ancak Power Automate genellikle giden HTTP için ücretli bir premium bağlayıcı gerektirir.
Brevo ile ücretsiz başlayın