ユーザが設定したidの値に基づいて、そのidの要素・属性値を
すべて取得させる目的で下記のようなVBAを組んでみました。
各属性値を読み込む際に、idの値によって判定し、一致する場合には値を取得します。
しかし、XPath式の設定方法が良くないようで、うまく属性値を取得できません。
XPath式に変数を入れることは出来ないでしょうか。
また、他に効率の良い組み方はありますでしょうか。
'Xに、/AAAA/BBBB[@id="1"]/CCCC/@DDDDの値(175)を取り込むコード
Private Sub CommandButton1_Click()
Dim DOM As MSXML2.DOMDocument
Dim ID As Double
Set DOM = New MSXML2.DOMDocument
DOM.async = False
DOM.Load ("c:\sample.xml")
ID = Range("a1") 'Range("a1") = 1
For Each Node In DOM.SelectNodes("//AAAA/BBBB[@id = ID]/CCCC/@DDDD") 'とすると、Xは空のまま。
'For Each Node In DOM.SelectNodes("//AAAA/BBBB[@id = 1]/CCCC/@DDDD") とすると、Xに属性値(175)が読み込まれる。
'For Each Node In DOM.SelectNodes("//AAAA/BBBB[@id = '1']/CCCC/@DDDD") とすると、Xに属性値(175)が読み込まれる。
X = Node.Value
Next
MsgBox X
End Sub
<!--- c:\sample.xml --->
<?xml version="1.0" encoding="Shift_JIS" standalone="yes" ?>
<AAAA>
<BBBB id="1">
<CCCC DDDD="175" EEEE="600" FFFF="1200">
<GGGG>
<HHHH XXXX="0.3" YYYY="0.00083" ZZZZ="0.00083"/>
<IIII XXXX="0.4" YYYY="0.00073" ZZZZ="0.00083"/>
<!--- 中略 --->
</GGGG>
</CCCC>
</BBBB>
<BBBB id="2">
<CCCC DDDD="150" EEEE="600" FFFF="1200">
<GGGG>
<HHHH XXXX="0.3" YYYY="0.00083" ZZZZ="0.00083"/>
<IIII XXXX="0.4" YYYY="0.00073" ZZZZ="0.00083"/>
<!--- 中略 --->
</GGGG>
</CCCC>
</BBBB>
<!--- 中略 --->
</AAAA>
> For Each Node In DOM.SelectNodes("//AAAA/BBBB[@id = ID]/CCCC/@DDDD") 'とすると、Xは空のまま。
この場合の大文字 ID は、<ID> ノードとして解釈されています。
> 'For Each Node In DOM.SelectNodes("//AAAA/BBBB[@id = 1]/CCCC/@DDDD") とすると、Xに属性値(175)が読み込まれる。
それと同じ XPath 式を構築すれば OK です。
すなわち、
sXPash = "//AAAA/BBBB[@id = ID]/CCCC/@DDDD"
ではなく
sXPash = "//AAAA/BBBB[@id = " & CStr(ID) & "]/CCCC/@DDDD"
であるということです。
> DOM.Load ("c:\sample.xml")
VBA では、戻り値を受け取らないメソッドの呼び出しは
DOM.Load "c:\sample.xml"
もしくは
Call DOM.Load("c:\sample.xml")
と記述する必要がありますのでご注意を。
今回は引数が 1 つだけなので、括弧をつけても
Call DOM.Load( ("c:\sample.xml") )
の意味で解釈されますけれどね。
>魔界の仮面弁士様
返信ありがとうございます。
" & CStr(ID) & "のように式を修正したところ、狙ったとおりの動作ができることを確認しました。
ただそのまま変数を書いただけではノード扱いになってしまうんですね。