Genel Bakış
DOMDocument (MSXML DOMDocument), Microsoft XML Core Services (MSXML) kitaplığının bir XML belgesini bellekte ağaç yapısı olarak temsil eden ana nesnesidir. VBA içinde XML metnini veya dosyasını yüklemek, düğümler arasında gezinmek, XPath ile veri sorgulamak ve sıfırdan yeni bir XML belgesi üretmek için kullanılır. Excel ile dış sistemler arasında veri alışverişi yapan makrolarda sık başvurulan bir nesnedir.
Sürüm 6.0 güvenlik ve kararlılık açısından önerilen sürümdür. Eski bilgisayarlarda MSXML2.DOMDocument.3.0 kullanılabilir; ancak 3.0 sürümünde XPath sorguları için SetProperty "SelectionLanguage", "XPath" çağrısı yapmak gerekir.
Tablo, makronun okuduğu kaynak listedir; makro sayfaya bir şey yazmaz. Çalıştırdığınızda Hemen Penceresi'nde önce XML bildirimi, ardından kök Personeller öğesi ve her satır için bir Personel öğesi görünür. Sicil numarası öznitelik, diğer sütunlar alt öğe olarak yazılır. Belgeyi dosyaya yazmak isterseniz xml.Save yöntemini kullanabilirsiniz.
Makro çalıştırıldığında A2:C4 aralığına üç ürünün kodu, adı ve fiyatı yazılır: kod Urun öğesinin özniteliğinden, ad ve fiyat ise alt öğelerden okunur. XML metninde bir etiket kapatılmamışsa LoadXML False döndürür ve ParseError.Reason hatanın nedenini bildirir. Dosyadan okumak için LoadXML yerine Load yöntemine dosya yolunu verin.
Makro çalıştırıldığında tutarı 10.000 ve üzerinde olan siparişlerin (bu tabloda 5001, 5003 ve 5005 numaralı satırlar) E sütununa Evet yazılır; diğer satırlar boş kalır. Filtreleme işini döngüyle tek tek karşılaştırmak yerine XPath ifadesi yapar. Tutar özniteliği ondalık ayırıcı olarak nokta içermelidir; bu yüzden değerler Replace ile düzeltilmiştir.
Nesneyi oluşturma
DOMDocument, Excel'in kendi nesne modelinin parçası değildir; MSXML kitaplığından gelir. İki yolla kullanılabilir. Birincisi geç bağlamadır (CreateObject); ek bir ayar gerektirmez ve çoğu makroda tercih edilir. İkincisi erken bağlamadır; VBA düzenleyicisinde Araçlar > Başvurular (Tools > References) penceresinden Microsoft XML, v6.0 işaretlenir ve nesne New ile oluşturulur. Erken bağlamada IntelliSense desteği alırsınız.
VBA
7 satır
' Geç bağlama
Dim xml As Object
Set xml = CreateObject("MSXML2.DOMDocument.6.0")
' Erken bağlama (MSXML 6.0 başvurusu eklenmişse)
Dim xml2 As MSXML2.DOMDocument60
Set xml2 = New MSXML2.DOMDocument60
Önemli özellikler
- Async: Belgenin eşzamansız yüklenip yüklenmeyeceğini belirler. Dosyayı yükleyip hemen okuyacaksanız False yapın.
- DocumentElement: Belgenin kök öğesini döndürür.
- XML: Belgenin tamamını XML metni olarak verir; ayrıca ayrıştırılmış belgenin çıktısını görmek için de kullanılır.
- ParseError: Yükleme hatası bilgisini taşır. ErrorCode, Reason ve Line alt özellikleriyle hatanın nedenini ve satırını gösterir.
- PreserveWhiteSpace: Öğeler arasındaki boşlukların korunup korunmayacağını belirler; varsayılanı False değeridir.
- ValidateOnParse: Yükleme sırasında şema veya DTD doğrulaması yapılıp yapılmayacağını belirler.
- Text: Bir düğümün ve alt düğümlerinin birleşik metnini okur ya da yazar.
- ChildNodes: Bir düğümün alt düğümlerini listeler.
Önemli yöntemler ve olaylar
- LoadXML(metin): XML metnini yükler. Başarılıysa True döndürür.
- Load(kaynak): Bir dosyadan XML yükler. Başarılıysa True döndürür.
- Save(hedef): Belgeyi dosyaya kaydeder.
- SelectNodes(xpath): XPath ifadesine uyan tüm düğümleri liste olarak döndürür; listenin Length özelliği düğüm sayısını verir.
- SelectSingleNode(xpath): Uyan ilk düğümü döndürür; bulunamazsa Nothing verir.
- CreateElement(ad): Yeni bir öğe düğümü oluşturur. Belgeye eklemek için AppendChild gerekir.
- CreateAttribute, CreateTextNode, CreateProcessingInstruction: Öznitelik, metin düğümü ve işleme yönergesi üretir.
- AppendChild, InsertBefore, RemoveChild: Düğüm ağacını düzenler.
- SetAttribute, GetAttribute: Bir öğenin özniteliğini yazar veya okur.
- OnReadyStateChange, OnDataAvailable: Eşzamansız yüklemede durum değişince çalışan olay özellikleridir; olay işleyicisi bir nesneyle atanır, bu yüzden Excel makrolarında nadiren kullanılır.
1. Sayfadaki listeden XML belgesi üretme
Sayfadaki personel listesini okuyup her satırı bir Personel öğesine dönüştüren bir XML belgesi kurmak istiyorsunuz. Aşağıdaki kodu standart bir modüle yapıştırın. Kod, CreateObject kullandığı için bu sayfada çalıştırılmaz; sonucu VBA düzenleyicisinin Hemen Penceresi'nde (Immediate Window) görürsünüz.
VBA
39 satır
Option Explicit
' Ad ve metin değeriyle yeni bir öğe üretir
Private Function Eleman(xml As Object, ad As String, deger As String) As Object
Dim e As Object
Set e = xml.createElement(ad)
e.Text = deger
Set Eleman = e
End Function
Sub SayfadanXmlOlustur()
Dim xml As Object, kok As Object, kayit As Object
Dim ws As Worksheet, i As Long, son As Long
Set ws = ActiveSheet
Set xml = CreateObject("MSXML2.DOMDocument.6.0")
' Kök öğeyi oluşturup belgeye ekle
Set kok = xml.createElement("Personeller")
xml.appendChild kok
son = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
For i = 2 To son
Set kayit = xml.createElement("Personel")
kayit.setAttribute "sicil", CStr(ws.Cells(i, 1).Value)
kayit.appendChild Eleman(xml, "AdSoyad", CStr(ws.Cells(i, 2).Value))
kayit.appendChild Eleman(xml, "Departman", CStr(ws.Cells(i, 3).Value))
kayit.appendChild Eleman(xml, "Sehir", CStr(ws.Cells(i, 4).Value))
' Ondalık ayırıcı nokta olsun diye virgülü noktaya çevir
kayit.appendChild Eleman(xml, "Maas", Replace(CStr(ws.Cells(i, 5).Value), ",", "."))
kok.appendChild kayit
Next i
' XML bildirimini en başa ekle
xml.insertBefore xml.createProcessingInstruction("xml", "version=""1.0"" encoding=""UTF-8"""), xml.firstChild
Debug.Print xml.XML
End Sub
DOMDocument
Formülünü incelemek için bir hücre seçin.| A | B | C | D | E | |
|---|---|---|---|---|---|
| 1 | Sicil | Ad Soyad | Departman | Şehir | Maaş |
| 2 | 1001 | Ayşe Yılmaz | Muhasebe | Ankara | 32.500,00 |
| 3 | 1002 | Mehmet Demir | Satış | İzmir | 28.750,00 |
| 4 | 1003 | Zeynep Kaya | Bilgi İşlem | İstanbul | 41.000,00 |
| 5 | 1004 | Can Öztürk | Satış | Bursa | 27.300,00 |
Personel ListesiExcelDepo v1.0.0
2. XML metnini yükleyip değerleri sayfaya yazma
Elinizdeki XML metnini LoadXML ile yükleyip her Urun öğesinin kodunu, adını ve fiyatını sayfaya yazdırmak istiyorsunuz. Kodu standart modüle yapıştırın. CreateObject kullanıldığı için örnek bu sayfada çalıştırılmaz; tablo makro çalışmadan önceki durumuyla gösterilir.
VBA
33 satır
Option Explicit
Sub XmlMetniniOku()
Dim xml As Object, urunler As Object, d As Object
Dim metin As String, satir As Long
' Örnek XML metni
metin = "<Urunler>"
metin = metin & "<Urun kod=""K101""><Ad>Dizüstü Bilgisayar</Ad><Fiyat>24500</Fiyat></Urun>"
metin = metin & "<Urun kod=""K102""><Ad>Kablosuz Mouse</Ad><Fiyat>350</Fiyat></Urun>"
metin = metin & "<Urun kod=""K103""><Ad>Monitör 27 inç</Ad><Fiyat>7800</Fiyat></Urun>"
metin = metin & "</Urunler>"
Set xml = CreateObject("MSXML2.DOMDocument.6.0")
xml.async = False
' Yükleme başarısızsa nedenini göster ve çık
If Not xml.LoadXML(metin) Then
MsgBox "XML okunamadı: " & xml.parseError.reason
Exit Sub
End If
Set urunler = xml.SelectNodes("/Urunler/Urun")
satir = 2
For Each d In urunler
ActiveSheet.Cells(satir, 1).Value = d.Attributes.getNamedItem("kod").Text
ActiveSheet.Cells(satir, 2).Value = d.SelectSingleNode("Ad").Text
' Val, nokta ayırıcılı metni sayıya güvenle çevirir
ActiveSheet.Cells(satir, 3).Value = Val(d.SelectSingleNode("Fiyat").Text)
satir = satir + 1
Next d
End Sub
DOMDocument
Formülünü incelemek için bir hücre seçin.| A | B | C | |
|---|---|---|---|
| 1 | Ürün Kodu | Ürün Adı | Fiyat |
Ürün FiyatlarıExcelDepo v1.0.0
3. XPath ile koşula uyan düğümleri bulma
Sipariş listesini bellekte bir XML belgesine dönüştürüp SelectNodes ve bir XPath koşuluyla tutarı 10.000 ve üzerindeki siparişleri bulacaksınız. Bulunan siparişlerin satırına E sütununda Evet yazılır. Kodu standart modüle yapıştırın; CreateObject kullandığı için bu sayfada çalıştırılmaz.
VBA
33 satır
Option Explicit
Sub BuyukSiparisleriIsaretle()
Dim xml As Object, kok As Object, s As Object
Dim liste As Object, d As Object
Dim ws As Worksheet, i As Long, son As Long
Dim satir As Variant
Set ws = ActiveSheet
Set xml = CreateObject("MSXML2.DOMDocument.6.0")
Set kok = xml.createElement("Siparisler")
xml.appendChild kok
son = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
' Her satırı öznitelikli bir öğeye çevir
For i = 2 To son
Set s = xml.createElement("Siparis")
s.setAttribute "no", CStr(ws.Cells(i, 1).Value)
s.setAttribute "musteri", CStr(ws.Cells(i, 2).Value)
s.setAttribute "tutar", Replace(CStr(ws.Cells(i, 4).Value), ",", ".")
kok.appendChild s
Next i
' XPath koşulu: tutar özniteliği 10000 veya daha büyük
Set liste = xml.SelectNodes("/Siparisler/Siparis[@tutar>=10000]")
For Each d In liste
satir = Application.Match(CLng(d.Attributes.getNamedItem("no").Text), ws.Range("A:A"), 0)
If Not IsError(satir) Then ws.Cells(satir, 5).Value = "Evet"
Next d
End Sub
DOMDocument
Formülünü incelemek için bir hücre seçin.| A | B | C | D | E | |
|---|---|---|---|---|---|
| 1 | Sipariş No | Müşteri | Şehir | Tutar | Büyük Sipariş |
| 2 | 5001 | Anadolu Gıda | Konya | 12.500,00 | |
| 3 | 5002 | Ege Tekstil | İzmir | 4.800,00 | |
| 4 | 5003 | Marmara Yapı | Bursa | 23.900,00 | |
| 5 | 5004 | Karadeniz Çay | Rize | 9.750,00 | |
| 6 | 5005 | Akdeniz Turizm | Antalya | 15.200,00 | |
| 7 | 5006 | Başkent Kırtasiye | Ankara | 3.100,00 |
Sipariş TakibiExcelDepo v1.0.0
Kullanırken dikkat edin
- Kullanırken dikkat edin: yükleme sonucunu denetleyin: Load ve LoadXML hata durumunda çalışma zamanı hatası vermez, yalnızca False döndürür. Sonucu denetlemezseniz sonraki satırlarda Nesne gerekli (Object required) hatası alırsınız. Nedenini görmek için ParseError.Reason ve ParseError.Line özelliklerine bakın.
- Kullanırken dikkat edin: Async özelliği: Dosyadan yükleme yapıyorsanız Async özelliğini False yapın. Aksi halde yükleme tamamlanmadan sonraki satıra geçilir ve belge boş görünür.
- Kullanırken dikkat edin: ondalık ayırıcı: XML içindeki sayılar nokta ile yazılır. Türkçe ayarlarda CStr sayıyı virgülle metne çevirir ve XPath sayı karşılaştırmaları ya da dış sistemler bunu okuyamaz. Yazarken Replace ile virgülü noktaya çevirin; okurken Val kullanın.
- Kullanırken dikkat edin: özel karakterler: CreateElement, SetAttribute ve Text özelliği &, < ve > gibi karakterleri otomatik kodlar. XML metnini elle birleştirip LoadXML ile yüklerseniz bu karakterleri kendiniz kodlamanız gerekir; aksi halde belge geçersiz olur.
- Kullanırken dikkat edin: sürüm ve güvenlik: Mümkünse MSXML2.DOMDocument.6.0 kullanın. Dışarıdan gelen, güvenmediğiniz XML dosyalarını yüklerken DTD işlemeyi kapatmak için ProhibitDTD ayarına dikkat edin. Mac sürümünde MSXML bulunmaz; bu kodlar yalnızca Windows'ta çalışır.
- Kullanırken dikkat edin: ad alanları: XML belgesi bir ad alanı (namespace) kullanıyorsa XPath sorguları sonuç vermeyebilir. Bu durumda SetProperty "SelectionNamespaces", ... ile bir önek tanımlayıp sorguda o öneki kullanmanız gerekir.
- İlgili konular:
- CreateObject işlevi: DOMDocument nesnesini geç bağlamayla oluşturur.
- XMLHTTP nesnesi: Web servislerinden XML yanıtı almak için kullanılır; yanıt DOMDocument ile okunur.
- Workbooks.OpenXML yöntemi: Bir XML dosyasını doğrudan Excel çalışma kitabı olarak açar.
- XML Eşlemeleri: Geliştirici > XML > Kaynaklar (Developer > XML > Source) ile sayfa aralıklarını XML şemasına bağlar.
- FİLTREXML: XPath ifadesiyle XML metninden değer çıkaran çalışma sayfası işlevidir.
- Replace ve Val işlevleri: Sayı ve metin dönüşümlerinde ondalık ayırıcı sorununu çözer.