Genel Bakış
XmlHttp Request (MSXML2.XMLHTTP nesnesi), VBA kodunun bir web sunucusuna HTTP isteği (GET, POST vb.) göndermesini ve sunucunun yanıtını okumasını sağlar. Web servislerinden veri çekmek, bir sayfanın metnini almak ya da bir forma veri göndermek için kullanılır. Nesne Microsoft XML (MSXML) kitaplığında yer alır ve genellikle CreateObject ile oluşturulur.
Yanıttaki Türkçe karakterler bozuk görünüyorsa responseBody verisini ADODB.Stream nesnesiyle UTF-8 olarak çözebilirsiniz:
VBA'nın JSON ayrıştırıcısı yoktur. Yanıt JSON ise Split, InStr ve Mid gibi metin işlevleriyle ya da hazır bir JSON modülüyle çözülür.
Makro çalıştığında B2 hücresinde sunucunun durum kodu ve metni, C2 hücresinde yanıtın karakter sayısı görünür. Durum kodu 200 ise yanıtın ilk 200 karakteri D2 hücresine yazılır. Ağ ya da adres hatasında B2 hücresine hata iletisi yazılır. Bu örnekte yöntem eşzamanlı (False) çağrıldığı için yanıt gelene kadar Excel bekler; zaman aşımları bu beklemeyi sınırlar.
Makro ham metni dört kayda ayırdı. İlk kayıtta ürün adı Elma, adet 12, birim fiyat 18,50 ve tutar 222,00 olarak yazıldı. Son kayıt Portakal ürününe aittir ve tutarı 405,00 değerindedir. Ondalık sayılar Val işleviyle okunur; Val nokta ayırıcıyı bölgesel ayarlardan bağımsız tanır. Gerçek bir yanıtta Range("A2").Value yerine http.responseText kullanırsınız.
Makro her satırdaki kodu işleve gönderir. 200 kodu için Başarılı, 404 kodu için Sayfa bulunamadı, 500 kodu için Sunucu hatası açıklaması yazılır. Listede olmayan kod ise Tanımsız kod sonucunu verir. Case 500 To 599 aralığı sayesinde tüm sunucu hataları tek satırla karşılanır. Gerçek istekte aynı işlevi DurumAciklama(http.Status) biçiminde çağırabilirsiniz.
Söz dizimi
Nesne, ek bir başvuru eklemeden (geç bağlama) CreateObject işleviyle oluşturulur. Ardından Open, setRequestHeader ve send yöntemleri sırayla çağrılır:
VBA
4 satır
Set http = CreateObject("MSXML2.XMLHTTP")
http.Open yontem, adres, [eszamanli], [kullanici], [parola]
http.setRequestHeader baslik, deger
http.send [govde]
- yontem: HTTP yöntemi; "GET", "POST", "PUT", "DELETE" ya da "HEAD" gibi bir metin. Zorunludur.
- adres: İsteğin gönderileceği tam web adresi. Zorunludur.
- eszamanli: İsteğe bağlıdır; varsayılanı True (asenkron) değeridir. False verirseniz kod yanıt gelene kadar bekler ve Excel o sürede donuk görünür.
- kullanici: İsteğe bağlı; kimlik doğrulaması gereken sitelerde kullanıcı adı.
- parola: İsteğe bağlı; kimlik doğrulaması gereken sitelerde parola.
- baslik, deger: setRequestHeader için üstbilgi adı ve değeri. Open çağrısından sonra, send çağrısından önce kullanılmalıdır.
- govde: send için isteğe bağlı gönderilecek veri (metin, bayt dizisi ya da XML belgesi). POST isteğinde form verisi ya da JSON metni burada verilir.
Önemli özellikler
- Status: HTTP durum kodu (Long). 200 başarılı, 404 bulunamadı, 500 sunucu hatası anlamına gelir.
- statusText: Durum kodunun sunucudan gelen metin karşılığı (ör. OK).
- readyState: İsteğin aşamasını verir: 0 başlatılmadı, 1 açıldı, 2 gönderildi, 3 alınıyor, 4 tamamlandı. Asenkron çalışırken yanıtı okumadan önce değerin 4 olduğunu denetleyin.
- responseText: Yanıtı metin olarak verir. JSON, HTML ve CSV gibi metin yanıtları için kullanılır.
- responseBody: Yanıtı ham bayt dizisi olarak verir. Resim, PDF gibi ikili dosyalar ve karakter kodlaması sorunlarında kullanılır.
- responseXML: Yanıt XML ise ayrıştırılmış belge nesnesini verir.
Önemli yöntemler
- Open: İsteği tanımlar; yöntemi, adresi ve eşzamanlılık seçeneğini belirler.
- setRequestHeader: İsteğe üstbilgi ekler (ör. Content-Type, User-Agent, Authorization).
- send: İsteği sunucuya gönderir.
- getResponseHeader: Yanıttaki tek bir üstbilgiyi okur.
- getAllResponseHeaders: Yanıtın tüm üstbilgilerini tek metin olarak verir.
- abort: Devam eden isteği iptal eder.
- setTimeouts: Yalnız ServerXMLHTTP nesnesinde bulunur; çözümleme, bağlanma, gönderme ve alma için zaman aşımlarını milisaniye cinsinden ayarlar.
Yanıtın işlenmesi ve durum kodları
İstek gönderildikten sonra önce Status değerine bakın. 200-299 arası başarıyı, 300-399 yönlendirmeyi, 400-499 istemci hatasını (yanlış adres, yetki yok), 500 ve üzeri sunucu hatasını gösterir. Yalnızca başarılı yanıtta responseText içeriğini işleyin.Yanıttaki Türkçe karakterler bozuk görünüyorsa responseBody verisini ADODB.Stream nesnesiyle UTF-8 olarak çözebilirsiniz:
VBA
7 satır
Set akim = CreateObject("ADODB.Stream")
akim.Type = 1: akim.Open
akim.Write http.responseBody
akim.Position = 0: akim.Type = 2
akim.Charset = "utf-8"
metin = akim.ReadText
akim.Close
1. GET isteği ile web sayfası metnini alma
A2 hücresine okumak istediğiniz web adresini yazın. Aşağıdaki kodu standart bir modüle (Ekle > Modül) yapıştırın ve SayfaIndir makrosunu çalıştırın. Makro durum kodunu B2'ye, yanıtın uzunluğunu C2'ye, başarılı yanıtta ilk 200 karakteri D2'ye yazar. Bu örnek ağ bağlantısı gerektirdiği için sayfada otomatik çalıştırılmaz.
VBA
31 satır
Option Explicit
' A2 hücresindeki adrese GET isteği gönderir
Sub SayfaIndir()
Dim http As Object
Dim adres As String
adres = Trim(Range("A2").Value)
If Len(adres) = 0 Then
MsgBox "A2 hücresine bir web adresi yazın.", vbExclamation
Exit Sub
End If
On Error GoTo Hata
Set http = CreateObject("MSXML2.ServerXMLHTTP.6.0")
' Zaman aşımları (ms): çözümleme, bağlanma, gönderme, alma
http.setTimeouts 5000, 5000, 10000, 15000
http.Open "GET", adres, False
http.setRequestHeader "User-Agent", "ExcelVBA"
http.send
Range("B2").Value = http.Status & " " & http.statusText
Range("C2").Value = Len(http.responseText)
If http.Status = 200 Then
Range("D2").Value = Left(http.responseText, 200)
End If
Exit Sub
Hata:
Range("B2").Value = "Hata: " & Err.Description
End Sub
XmlHttp Request
Formülünü incelemek için bir hücre seçin.| A | B | C | D | |
|---|---|---|---|---|
| 1 | Adres | Durum | Yanıt Uzunluğu | İlk 200 Karakter |
| 2 | (adresi buraya yazın) |
Web İsteğiExcelDepo v1.0.0
2. Yanıt metnini satırlara ve sütunlara ayırma
A2 hücresi, bir sunucudan gelen responseText değerini temsil eder: kayıtlar (ürünler) dik çizgiyle, her kaydın alanları (ürün, adet, birim fiyat) noktalı virgülle ayrılmıştır. Kodu standart bir modüle yapıştırıp YanitiSatirlaraBol makrosunu çalıştırın. Makro metni kayıt ve alanlara böler, sonuçları B:E sütunlarına yazar ve tutarı hesaplar. Ağ bağlantısı gerekmediği için bu örnek sayfada çalıştırılır.
VBA
31 satır
Option Explicit
' Sunucu yanıtı gibi bir metni satırlara ve alanlara böler
Sub YanitiSatirlaraBol()
Dim yanit As String
Dim satirlar() As String
Dim alanlar() As String
Dim i As Long
Dim hedef As Long
' Dik çizgiyi gerçek yanıttaki satır sonuna çevir
yanit = Replace(Range("A2").Value, "|", vbLf)
' Windows satır sonlarını tek tipe indir
yanit = Replace(yanit, vbCrLf, vbLf)
satirlar = Split(yanit, vbLf)
For i = 0 To UBound(satirlar)
If Len(Trim(satirlar(i))) > 0 Then
alanlar = Split(satirlar(i), ";")
If UBound(alanlar) >= 2 Then
hedef = i + 2
Cells(hedef, 2).Value = alanlar(0)
Cells(hedef, 3).Value = Val(alanlar(1))
Cells(hedef, 4).Value = Val(alanlar(2))
Cells(hedef, 5).Value = Cells(hedef, 3).Value * Cells(hedef, 4).Value
End If
End If
Next i
Range("D2:E5").NumberFormat = "#,##0.00"
End Sub
XmlHttp Request
Formülünü incelemek için bir hücre seçin.| A | B | C | D | E | |
|---|---|---|---|---|---|
| 1 | Ham Yanıt | Ürün | Adet | Birim Fiyat | Tutar |
| 2 | Elma;12;18.5|Armut;8;22|Muz;20;35|Portakal;15;27 | Elma | 12 | 18,50 | 222,00 |
| 3 | Armut | 8 | 22,00 | 176,00 | |
| 4 | Muz | 20 | 35,00 | 700,00 | |
| 5 | Portakal | 15 | 27,00 | 405,00 |
Yanıt AyrıştırmaExcelDepo v1.0.0
3. HTTP durum kodunu yorumlama
Bir istekten sonra Status değerini anlamlı bir iletiye çevirmek için ayrı bir işlev yazmak iyi bir alışkanlıktır. Kodu standart bir modüle yapıştırın ve DurumKodlariniYaz makrosunu çalıştırın. Makro B sütunundaki kodları okur, açıklamaları C sütununa yazar. Gerçek kodda DurumAciklama işlevine http.Status değerini verirsiniz.
VBA
35 satır
Option Explicit
' HTTP durum kodunu Türkçe açıklamaya çevirir
Function DurumAciklama(ByVal kod As Long) As String
Select Case kod
Case 200
DurumAciklama = "Başarılı"
Case 301, 302
DurumAciklama = "Adres taşındı (yönlendirme)"
Case 401
DurumAciklama = "Kimlik doğrulaması gerekli"
Case 403
DurumAciklama = "Erişim yasak"
Case 404
DurumAciklama = "Sayfa bulunamadı"
Case 408
DurumAciklama = "İstek zaman aşımına uğradı"
Case 429
DurumAciklama = "Çok fazla istek gönderildi"
Case 500 To 599
DurumAciklama = "Sunucu hatası"
Case Else
DurumAciklama = "Tanımsız kod"
End Select
End Function
Sub DurumKodlariniYaz()
Dim son As Long
Dim i As Long
son = Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To son
Cells(i, 3).Value = DurumAciklama(CLng(Cells(i, 2).Value))
Next i
End Sub
XmlHttp Request
Formülünü incelemek için bir hücre seçin.| A | B | C | |
|---|---|---|---|
| 1 | İstek | Durum Kodu | Açıklama |
| 2 | Ürün listesi | 200 | Başarılı |
| 3 | Eski adres | 301 | Adres taşındı (yönlendirme) |
| 4 | Yetkisiz erişim | 401 | Kimlik doğrulaması gerekli |
| 5 | Eksik sayfa | 404 | Sayfa bulunamadı |
| 6 | Yoğun kullanım | 429 | Çok fazla istek gönderildi |
| 7 | Sunucu çökmesi | 500 | Sunucu hatası |
| 8 | Bilinmeyen yanıt | 799 | Tanımsız kod |
Durum KodlarıExcelDepo v1.0.0
Kullanırken dikkat edin
- Tek tek durum denetimi yapın: İstek hata verse bile Excel çoğu zaman VBA hatası üretmez; sunucu sadece 404 ya da 500 koduyla yanıt döner. Yanıtı kullanmadan önce her zaman Status değerini denetleyin. Ağ kesintisi ya da yanlış adres gibi durumlar için ayrıca On Error kullanın.
- Eşzamanlı çağrı Excel'i bekletir: Open çağrısında eşzamanlı (False) kullanırsanız kod yanıt gelene kadar durur ve Excel yanıt vermiyor gibi görünür. Bu yüzden ServerXMLHTTP nesnesinin setTimeouts yöntemiyle makul zaman aşımları verin. Döngüyle çok sayıda istek atacaksanız sayıyı sınırlı tutun ve sunucunun istek sınırlarına uyun.
- Önbellek sorunu: XMLHTTP nesnesi GET yanıtlarını Windows önbelleğinden alabilir; bu durumda sayfa değişse bile eski veri gelir. ServerXMLHTTP nesnesi bu tür önbellek kullanmadığı için güncel veri gerekiyorsa tercih edilebilir. Alternatif olarak adrese her seferinde değişen bir parametre ekleyebilirsiniz.
- Karakter kodlaması: Sunucu karakter kümesini belirtmezse responseText içindeki Türkçe karakterler (ş, ğ, ı) bozuk çıkabilir. Bu durumda responseBody verisini ADODB.Stream ile UTF-8 olarak çözün.
- Güvenlik ve uyumluluk: Eski sunucularda TLS 1.2 desteği ya da sertifika sorunları isteğin başarısız olmasına yol açabilir. Kurumsal ağlarda güvenlik duvarı ve vekil sunucu (proxy) ayarları da engel olabilir. Makrolar yalnız Windows için Excel'de güvenilir çalışır; Mac sürümünde MSXML bulunmaz. Parola ve erişim anahtarlarını kodun içine açık yazmaktan kaçının.
- İlgili konular:
- CreateObject: Nesneyi geç bağlama ile oluşturan VBA işlevi.
- ServerXMLHTTP ve WinHttp.WinHttpRequest: Aynı işi yapan alternatif HTTP nesneleri.
- Split, Replace, InStr, Mid: Yanıt metnini ayrıştırmak için kullanılan VBA metin işlevleri.
- On Error: Ağ hatalarını yakalamak için kullanılan hata yönetimi deyimi.
- Select Case: Durum kodlarını sınıflandırmak için kullanışlı deyim.
- Veri > Veri Al > Web'den (Data > Get Data > From Web): Kod yazmadan web verisi almanın Power Query yolu.
- WEBHİZMETİ, XMLFİLTRELE, URLKODLA: Web'den veri almak, XML'i ayrıştırmak ve adres kodlamak için çalışma sayfası işlevleri.