マイナー・マイナー

隠れた名作の発掘が生きがい。

【VBA】XMLファイルの内容をEXCELファイルに読み込む


スポンサードリンク

ときにはXMLの要素や属性をEXCELに読み込んで扱いたいこともあります。XMLファイルから要素の内容と属性を読み込んで、EXCELファイルへと出力するサンプルプログラムを書きました。


f:id:yosinoo:20150902232220j:plain


まず、上図のようなXMLEXCELとをマップするためのTypeを用意しました。


XmlTypes

Option Explicit

' メンバタイプ
Public Type Member
    id As Integer
    name As String
    age As Integer
End Type


XMLを読み込むクラスモジュールは次のように書きました。実行には「Microsoft XML, v6.0」が必要なので、VBAのTools->Referencesよりチェックをつけておきます。


XmlReader

Option Explicit

' DOM
Private xmlDocument As MSXML2.DOMDocument

' コンストラクタ
Public Sub Class_Initialize()
End Sub

' XMLをDOMオブジェクトにロードする
Public Sub LoadXmlFile(ByVal fileName As String)
    ' MSXMLオブジェクトを生成
    Set xmlDocument = Nothing
    Set xmlDocument = New MSXML2.DOMDocument
    xmlDocument.Load (fileName)
End Sub

' メンバリストを取得する
Public Function GetMemberList(ByRef memberList() As XmlTypes.Member)
    Dim membersNode As IXMLDOMNode
    Dim memberNode As IXMLDOMNode
    Dim memberAttribute As MSXML2.IXMLDOMAttribute
   
    ' XMLのmemberノードを取得する
    Set membersNode = xmlDocument.SelectSingleNode("//members")
    Dim i As Integer
    i = 0
    For Each memberNode In membersNode.childNodes
        ReDim Preserve memberList(i)
       
        ' idの属性値を取得する
        For Each memberAttribute In memberNode.Attributes
            If memberAttribute.name = "id" Then
                memberList(i).id = memberAttribute.Value
            End If
        Next memberAttribute
       
        ' memberの子要素を取得する
        Dim childNode As IXMLDOMNode
        For Each childNode In memberNode.childNodes
            ' name要素の値を取得する
            If childNode.nodeName = "name" Then
                memberList(i).name = childNode.text
            End If
            ' age要素の値を取得する
            If childNode.nodeName = "age" Then
                memberList(i).age = childNode.text
            End If
        Next childNode
       
        i = i + 1
    Next memberNode
   
End Function

' デストラクタ
Public Sub Class_Terminate()
    If Not xmlDocument Is Nothing Then Set xmlDocument = Nothing
End Sub


DOMDocumentのオブジェクトを内部に保持し、このオブジェクトに対して読み込み関連の操作を提供します。まず、LoadXmlFileでXMLファイルをDOMオブジェクトにロードします。その後、GetMemberListでXMLの要素と属性をMember型の配列に格納します。


XMLの対象要素の取得はSelectSingleNodeメソッドにXPathを指定して行います。このメソッドは最初に見つかった要素のみを取得します。複数取得する場合はSelectNodesメソッドが利用できます。属性値は、対象要素のattributesを調べて取得します。対象要素の子要素は、childNodesを調べて取得します。


XMLReaderを利用して、XMLから読み込んだMember配列の内容をEXCELのセルへと出力するモジュールは次のように書きました。


SampleXmlReaderModule

Option Explicit

Sub ReadSample()

    ' 入力ファイル
    Dim inputFileName As String
    inputFileName = "C:\sample_input.xml"
   
    ' XMLの読み込み準備を行う
    Dim xr As XmlReader
    Set xr = New XmlReader
    xr.LoadXmlFile (inputFileName)
   
    ' XMLよりデータを読み込む
    Dim memberList() As XmlTypes.Member
    Call xr.GetMemberList(memberList)
   
    ' 取得結果をセルに出力する
    If Sgn(memberList) <> 0 Then
   
        Dim rowIndex As Long
        rowIndex = 2
       
        Dim i As Integer
        For i = 0 To UBound(memberList)
            Cells(rowIndex, 1) = memberList(i).id
            Cells(rowIndex, 2) = memberList(i).name
            Cells(rowIndex, 3) = memberList(i).age
            rowIndex = rowIndex + 1
        Next i
    End If
   
    Set xr = Nothing
End Sub


id、name、ageがそれぞれ1、2、3列目に出力されました。