ExcelとWebGISを連携させるときには,電子国土であれGoogleMapであれ,ExcelのデータをXMLファイルに変換する必要があります。
たった一つのノードを追加するだけでも結構面倒な手順になるので、関数を作って可読性を高めてみる試みをしてみました。
目次
何をする関数か
次のような属性・値と内容を持った要素を追加する場合,
1 |
<Youso Zokusei="Atai">Naiyou</Youso> |
VBAでは以下のようなコードを書かなければなりません。(変数宣言などは省略します)
1 2 3 4 5 6 7 8 9 10 11 |
'Yousoという要素を用意 Set tmpElement = XmlDoc.createElement("Youso") 'その要素にZokuseiという属性とAtaiという値を設定 tmpElement.setAttribute "Zokusei", "Atai" 'その要素にNaiyouという内容を設定 tmpElement.Text = "Naiyou" 'その要素を上位の要素(親ノード)に子ノードとして追加 ParentElement.appendChild tmpElement |
このように,1行のXMLの要素を追加するだけでも最低2行,内容や属性・値を追加すると3~4行になってしまいます。
上記のようなやり方を改善し、コードの記述を短く、可読性を高めて何をやっているかわかるようにすることが狙いです。
関数を読んだり変数の受け渡しは増えるので、速度は若干遅くなるかもしれませんが、試してみた結果,わかるほど遅くなるわけでもなく十分実用の範囲だったので,今後はこれで行こうと思います。
関数の作り方
関数名
AddElement = 要素を追加する
引数
- xd ; 要素を追加するXMLドキュメントオブジェクト
- ParentNode ; 追加される親ノードのXML要素オブジェクト
- elm ; 追加する要素名
- Txt ; 要素の内容[省略化]
- Attr1(~Attr4); 要素の属性(4つまで)[省略化]
- AttrText1(~AttrText4); 要素の属性に設定する値(4つまで)[省略化]
戻り値
- 追加されるXML要素オブジェクト
動作確認状況
Excel | 32ビット | 64ビット |
---|---|---|
2007 | OK | – |
2010 | たぶんOK(未確認) | たぶんOK(未確認) |
2011 Mac | NG | – |
2013 | OK | OK |
2007, 2013の32ビットおよび2013の64ビットで動作確認しました。MSXMLの参照設定があるため、2011 Macでは動作しません。
ソースコード
標準モジュールを用意して、以下のコードを記述します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
'XMLのノードに属性付き要素を加える 要参照設定 Microsoft XML, v6.0 Function AddElement(xd As MSXML2.DOMDocument60, _ ParentNode As MSXML2.IXMLDOMElement, _ elm As String, _ Optional Txt As String, _ Optional Attr1, Optional AttrText1, _ Optional Attr2, Optional AttrText2, _ Optional Attr3, Optional AttrText3, _ Optional Attr4, Optional AttrText4) As MSXML2.IXMLDOMElement Dim tmpElement As MSXML2.IXMLDOMElement 'elmという要素を設定 Set tmpElement = xd.createElement(elm) '要素に内容がある場合は追加する If Not IsMissing(Txt) Then tmpElement.Text = Txt '属性とその値がある場合は追加する(4つまで) If Not IsMissing(Attr1) And Not IsMissing(AttrText1) Then _ tmpElement.setAttribute Attr1, AttrText1 If Not IsMissing(Attr2) And Not IsMissing(AttrText2) Then _ tmpElement.setAttribute Attr2, AttrText2 If Not IsMissing(Attr3) And Not IsMissing(AttrText3) Then _ tmpElement.setAttribute Attr3, AttrText3 If Not IsMissing(Attr4) And Not IsMissing(AttrText4) Then _ tmpElement.setAttribute Attr4, AttrText4 '指定したノードに要素を追加する ParentNode.appendChild tmpElement '追加した要素を戻り値として設定する Set AddElement = tmpElement End Function |
関数の使い方
事前の準備
作成するXMLドキュメントのオブジェクトや使用する要素オブジェクトの変数宣言などをします。
1 2 3 4 5 |
Dim XmlDoc As MSXML2.DOMDocument60 Set XmlDoc = New MSXML2.DOMDocument60 Dim ParentElement As MSXML2.IXMLDOMElement Dim tmpElement As MSXML2.IXMLDOMElement 'そのほか,使用する分のオブジェクト変数を宣言 |
内容のみの要素を追加
引数は要素名,内容までを指定し,属性以降は省略します。
1 |
Set tmpElement = AddElement(XmlDoc, ParentElement, "scale", "1.1") |
xmlDocオブジェクトのParenteElementの中に以下の要素が追加されます。
1 |
<scale>1.1</scale> |
内容なしで属性・値を追加
引数は内容のみ省略します。
1 2 |
Set tmpElement = AddElement(XmlDoc, IconStyleElement, "hotSpot", , _ "x", "20", "y", "2", "xunits", "pixels", "yunits", "pixels") |
以下のように内容なし,属性・値ありの要素が追加されます。属性を4つ以上追加する場合は関数を拡張する必要があります。
1 |
<hotSpot x="20" y="2" xunits="pixels" yunits="pixels"/> |
要素をネストする場合
XML要素オブジェクト変数を必要なだけ用意する必要があります。
1 2 3 |
Set IconElement = AddElement(XmlDoc, IconStyleElement, "Icon") Set tmpElement = AddElement(XmlDoc, IconElement, "href", _ "http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png") |
以下のようにネストされた構造になります。
1 2 3 4 5 |
<Icon> <href> http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png </href> </Icon> |
使用例
この関数を使って、Google Earthにプレイスマークをプロットするためのkmlファイルを作成することができます。