• ベストアンサー

EXCELVBA XML処理

こんにちは、 下記のプログラムを作成したのですが、 (すいません、わかりづらいかもしれません。) <DIMENSION Name="E1">内の<HIERARCHY>タグ内にある <PARENT>と<CHILD>の値をセルに貼り付けようとしているのですが、 現在、下記二点で悩んでいまして、何か方法などありましたらお願い致します。 1:<DIMENSION Name="E1">処理のときに、セルにNAMEの値E1を出力  しているのですが、二回表示されてしまう。  (おそらく、<MEMBERS>と<HIERARCHY>と二つタグがあるので  そのせいかと思ったのですが、回避方法が変わりません。) 2:<DIMENSION Name="E1">だけでよいのだが、  <DIMENSION Name="Z1">まで処理を行っている  (<DIMENSION Name="E1">を抜けたという判断方法がわからず・・) VBAコード----------- Option Explicit Dim ia As Long Dim flg As Integer Private Sub CommandButton2_Click() Const cnsTITLE = "テキストファイル読み込み処理" Const cnsFILTER = "全てのファイル (*.*),*.*" Dim xlAPP As Application ' Applicationオブジェクト Dim strXMLFile As String Dim objDOM As MSXML2.DOMDocument Dim rtResult Set xlAPP = Application xlAPP.StatusBar = "読み込むファイル名を指定して下さい。" strXMLFile = xlAPP.GetOpenFilename(FileFilter:=cnsFILTER, _ Title:=cnsTITLE) If StrConv(strXMLFile, vbUpperCase) = "FALSE" Then Exit Sub Set objDOM = New MSXML2.DOMDocument rtResult = objDOM.Load(strXMLFile) If rtResult = True Then ia = 0 flg = 0 procDispDatas objDOM.childNodes Else MsgBox "読み込み失敗" End If Set objDOM = Nothing End Sub Sub procDispDatas(objNode) Dim obj For Each obj In objNode If (obj.parentNode.nodeName = "DIMENSION") Then '<DIMENSION >タグ内処理か判断 If (obj.parentNode.Attributes.getNamedItem("Name").nodeValue = "E1") Then '<DIMENSION Name="E1">タグ内処理か判断 ia = ia + 1 Cells(ia, 1).Value = _ obj.parentNode.Attributes.getNamedItem("Name").nodeValue & " : " flg = 1 End If ElseIf (flg = 1) Then If (obj.parentNode.nodeName = "HIERARCHY") Then '<HIERARCHY>タグ内処理か判断 flg = 2 End If ElseIf (flg = 2) Then If (obj.parentNode.nodeName = "NODE") Then '<NODE>タグ内処理か判断 flg = 3 End If ElseIf (flg = 3) Then Select Case obj.parentNode.nodeName Case "PARENT" '<PARENT>タグ内処理か判断 ia = ia + 1 Cells(ia, 1).Value = _ obj.parentNode.nodeName & " : " & _ obj.nodeValue Case "CHILD" '<CHILD>タグ内処理か判断 ia = ia + 1 Cells(ia, 1).Value = _ obj.parentNode.nodeName & " : " & _ obj.nodeValue Case Else End Select End If If obj.hasChildNodes Then procDispDatas obj.childNodes End If Next End Sub XMLファイル---------- <?xml version = "1.0" encoding="UTF-16" ?> <HSDATA> <DIMENSION Name="E1"> <MEMBERS> <MEMBER> <LABEL>[None]</LABEL> <AT Name="DefCurrency">[None]</AT> <DESCRIPTION Language="English">[None]</DESCRIPTION> </MEMBER> </MEMBERS> <HIERARCHY> <NODE> <PARENT>#root</PARENT> <CHILD>[None]</CHILD> </NODE> <NODE> <PARENT>#root</PARENT> <CHILD>MNG_CN</CHILD> </NODE> </HIERARCHY> </DIMENSION> <DIMENSION Name="Z1"> <HIERARCHY> <NODE> <PARENT>abc</PARENT> <CHILD>123</CHILD> </NODE> <NODE> <PARENT>def</PARENT> <CHILD>456</CHILD> </NODE> </HIERARCHY> </DIMENSION> </HSDATA>

質問者が選んだベストアンサー

  • ベストアンサー
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.2

2回表示されるのは DIMENSION/HIERARCY に NODEが2要素あるためですよ 自分で探すより XMLに探させたほうが間違いないのでは ・・・ Sub procDispDatas(objNode, Optional rg as Range = Nothing)   Dim obj as IXMLDomNode, ss as String   ss = ""   On Error Resume Next   ss = objNode.Attributes.getNamedItem("Name").nodeValue   On Error goto 0   if ss = "" then     ' DIMENSION/HIERARCY/NODEの場合     dim obj1 as IXMLDomNode     ' 子要素の PARENTとCHILDを取得     for each obj1 in obj.childNode       rg.Offset(0,0).Value = obj1.baseName       rg.Offset(0,1).Value = obj1.Text       set rg = rg.Offset(,1)     next   else if ss = "E1" then     ' <DIMENSION Name="E1"> ... </DIMENSION>"の場合     if rg is Nothing then       ' C1は適宜修正してください       set rg = Range("C1")     end if     rg.Value = ss     ' 子ノードを D,E列に転記     Set rg = rg.Offset( , 1 )     ' ノードの子ノードをXMLで選別     procDispDatas obj.selectNodes("HIERARCY/NODE"),rg   end if End Sub 呼び出し方を procDispDatas objDOM.getElementsByTagName("DIMENSION") とします これで DIMENSIONノード以外は procDispDatasに渡りません

その他の回答 (1)

  • kenpon24
  • ベストアンサー率64% (66/102)
回答No.1

xmlに明るくないので詳しくはわかりませんが、 Debug.print obj.parentNode.nodeNameで確認した限り </MEMBER> </MEMBERS> のを通過するあたりで <DIMENSION Name="E1">が参照されているように思えます。 obj.parentNode.nodeNameにDIMENSIONが格納されている) 同様に </NODE> </HIERARCHY> </DIMENSION> を通過するあたりではHSDATAが格納されています。 (1)の対策は色々あると思いますが、入力済みフラグを作るのはどうですか? procDispDatas内で Dim InputFlg as Boolean として入力したらフラグを立てる。 入力済みなら2度は書き込まない。 (2)の対策としては、 If (obj.parentNode.Attributes.getNamedItem("Name").nodeValue = "E1") Then のElse条件をつくり、Flg = 3だったらExit forするとか。 実際に処理する単位はもっと巨大でしょうから、もう少しすっきりした書き方を したいところではありますね。。。 とりあえずこんなところでどうですか?

関連するQ&A

  • VBSでXMLを読込、検索結果をテキスト出力

    VBSのソースについてご教授下さい。 【作りたい機能】 XMLファイルを読み込み、任意のエレメントを検索するスクリプトを VBSで作成しようとしています。 【状況】 ダイアログで表示させる方法はわかりました。  参照  http://www.atmarkit.co.jp/fxml/rensai/msxml01/msxml03.html 01 : Dim objDOM, rtResult 02 : 03 : Set objDOM = WScript.CreateObject("MSXML2.DOMDocument") 04 : rtResult = objDOM.load("Sample.xml") 05 : If rtResult = True Then 06 : procDispDatas objDOM.childNodes 07 : End If 08 : Set objDOM = Nothing 09 : 10 : Sub procDispDatas(objNode) 11 : Dim obj 12 : For Each obj In objNode 13 : If obj.nodeType = 3 and obj.parentNode.nodeName = "title" Then 14 : MsgBox obj.parentNode.nodeName & " : " & obj.nodeValue 15 : End If 16 : If obj.hasChildNodes Then 17 : procDispDatas obj.childNodes 18 : End If 19 : Next 20 : End Sub この結果をテキストファイルに出力させる方法に 困っております。 どこにどのように記載すればいいか 教えていただきたく存じます。 よろしくお願いいたします

  • VBScriptでXMLのデータを取得する方法

    こんにちは。 プログラミング初心者です。どうぞよろしくお願いします。 VBSで下記のようなXMLのtitleをpub idごとに別々に分けて抽出したいのですが、どうしたらよいか全く分からない状態です。 <book> <publisher> <pub id="集英社"/> </publisher> <title>ドラゴンボール</title> </book> <book> <publisher> <pub id="講談社"/> </publisher> <title>はじめの一歩</title> </book> <book> <publisher> <pub id="集英社"/> </publisher> <title>ジョジョの奇妙な冒険</title> </book> <book> <publisher> <pub id="秋田書店"/> </publisher> <title>範馬刃牙</title> </book> 下記のリンク先サイトにあったコードを試したのですが、titleが一緒くたに抽出されてしまい、別々に抽出ができません。pub idの階層が一つ深いのが原因だと思うのですが・・・どうしたらよいのか、さっぱり思いつきません。 http://www.atmarkit.co.jp/fxml/rensai/msxml01/msxml03.html Dim objDOM, rtResult Set objDOM = WScript.CreateObject("MSXML2.DOMDocument") rtResult = objDOM.load("○○.xml") If rtResult = True Then procDispDatas objDOM.childNodes End If Set objDOM = Nothing Sub procDispDatas(objNode) Dim obj For Each obj In objNode If obj.nodeType = 3 and obj.parentNode.nodeName = "title" Then MsgBox obj.parentNode.nodeName & " : " & obj.nodeValue End If If obj.hasChildNodes Then procDispDatas obj.childNodes End If Next End Sub どうかアドバイスをよろしくお願いいたします!

  • XMLをエクセルに取り込むマクロその2

    以下のtest2.xmlを <?xml version="1.0" encoding="UTF-8" ?> <McXMLRoot> <McXMLData> <McXMLPageInfo> <page>1</page> <overLay></overLay> <partition>PAGE</partition> </McXMLPageInfo> <McXMLPageData> <現頁> <value>0001</value> </現頁> <作成日付> <value>平成21年 6月 1日現在</value> </作成日付> <Group0001> <氏名> <value>あああ</value> </氏名> <生年月日> <value>昭和48年 2月21日</value> </生年月日> </Group0001> <Group0002> </Group0002> <Group0003> </Group0003> </McXMLPageData> <McXMLPageInfo> <page>2</page> <overLay></overLay> <partition>PAGE</partition> </McXMLPageInfo> <McXMLPageData> <現頁> <value>0004</value> </現頁> <作成日付> <value>平成21年 6月 1日現在</value> </作成日付> <Group0001> <氏名> <value>いいい</value> </氏名> <生年月日> <value>昭和55年 12月5日</value> </生年月日> </Group0001> <Group0002> <法人名> <value>AAA株式会社</value> </法人名> <住所> <value>AA市1丁目1番地</value> </住所> </Group0002> <Group0003> <支店名> <value>BBB営業所</value> </支店名> </Group0003> </McXMLPageData> </McXMLData> </McXMLRoot> を読むマクロ↓ Public Const XmlPass = "D:\temp\test2.xml" Public y As Integer Public ctr As Long Public Sub Auto_Open() 'On Error Resume Next Workbooks.OpenXML Filename:= _ XmlPass _ , LoadOption:=xlXmlLoadImportToList Range("A1").Select Call RetsuSakujo Call parseXML End Sub Private Sub RetsuSakujo() ctr = 1 Do Until "" = Trim(Worksheets("sheet1").Cells(1, ctr)) If "eform" = Trim(Worksheets("sheet1").Cells(1, ctr)) Or _ "page" = Trim(Worksheets("sheet1").Cells(1, ctr)) Or _ "overLay" = Trim(Worksheets("sheet1").Cells(1, ctr)) Or _ "partition" = Trim(Worksheets("sheet1").Cells(1, ctr)) Then Worksheets("sheet1").Columns(ctr).EntireColumn.Delete ctr = 0 End If ctr = ctr + 1 Loop End Sub Private Sub parseXML() Dim objDOM, rtResult y = 1 Set objDOM = CreateObject("MSXML2.DOMDocument") rtResult = objDOM.Load(XmlPass) If rtResult = True Then Call setTitle(objDOM.childNodes) End If Set objDOM = Nothing End Sub Sub setTitle(objNode) Dim obj For Each obj In objNode If obj.hasChildNodes Then If obj.parentNode.nodeName <> "McXMLRoot" And _ obj.parentNode.nodeName <> "McXMLData" And _ obj.parentNode.nodeName <> "McXMLPageData" And _ obj.parentNode.nodeName <> "McXMLPageInfo" _ Then If SearchChild(obj.childNodes) = False Then If y >= ctr Then Exit Sub End If Cells(1, y).Value = obj.parentNode.nodeName y = y + 1 End If End If Call setTitle(obj.childNodes) End If Next End Sub Private Function SearchChild(objNode) As Boolean Dim obj For Each obj In objNode If obj.hasChildNodes Then SearchChild = True Else SearchChild = False End If Next End Function を作成してエクセルマクロを試したところ、 タイトルが 現頁,作成日付,氏名,生年月日,現頁2,作成日付2,氏名2,生年月日2,法人名 となります。が、本当は 現頁,作成日付,氏名,生年月日,法人名,住所,口座番号,口座名義人,支店名 としたいのです。(エクセルでXMLソースを表示した時の順序) なにかよい方法があれば教えてください。 よろしくお願いします。

  • VBScriptを用いたXMLのデータ抽出に関して

    下記のsample.xmlから sample.xml ---------------------------------------------- <?xml version="1.0" encoding="utf-8" ?> <books> <item> <title>XML入門-第1巻</title> <price>2500</price> <isbn>1-1234-5678-X</isbn> <authors> <author>西谷 亮</author> </authors> <imgfile>1-1234-5678-X.gif</imgfile> </item> <item> <title>XML入門-第2巻</title> <price>2200</price> <isbn>1-1234-5678-0</isbn> <authors> <author>西谷 亮</author> <author>山田 太郎</author> </authors> <imgfile>1-1234-5678-0.gif</imgfile> </item> <item> <title>XML入門-第3巻</title> <price>3600</price> <isbn>1-1234-5678-1</isbn> <authors> <author>西谷 亮</author> <author>鈴木 次郎</author> </authors> <imgfile>1-1234-5678-1.gif</imgfile> </item> </books> ---------------------------------------------- 下記のtitle.vbsを用いて、「<title>」タグに表記された 書物のタイトルだけを抜き出します。 title.vbs ---------------------------------------------- 01 : Dim objDOM, rtResult 02 : 03 : Set objDOM = WScript.CreateObject("MSXML2.DOMDocument") 04 : rtResult = objDOM.load("Sample.xml") 05 : If rtResult = True Then 06 : procDispDatas objDOM.childNodes 07 : End If 08 : Set objDOM = Nothing 09 : 10 : Sub procDispDatas(objNode) 11 : Dim obj 12 : For Each obj In objNode 13 : If obj.nodeType = 3 and obj.parentNode.nodeName = "title" Then 14 : MsgBox obj.parentNode.nodeName & " : " & obj.nodeValue 15 : End If 16 : If obj.hasChildNodes Then 17 : procDispDatas obj.childNodes 18 : End If 19 : Next 20 : End Sub ---------------------------------------------- 上記の記述ではサブプロシージャprocDispDatas(objNode) にて、<title>タグの要素の数だけMsgBoxでタイトル名の メッセージボックスが表示されるかと思います。 これをひとつのメッセージでまとめるて表示するはどのように 記述すればよいでしょうか。 下記のメッセージの表示が理想です。 メッセージ ---------------------------------------------- title:XML入門-第1巻 title:XML入門-第2巻 title:XML入門-第3巻 ---------------------------------------------- お手数をおかけしますが、ご存知の方 ご教授いただけませんでしょうか>< よろしくお願いいたします。

    • 締切済み
    • XML
  • クリックすると文字が出るスクリプト

    function showIt(src) { var child, parent, childNum = 0; if ("B" == src.tagName) { parent = src.parentNode; for (var i=0; i < parent.childNodes.length; i++) { if (parent.childNodes[i].nodeType != 1) { continue; } if (childNum != 1) { childNum++; continue; } else { child = parent.childNodes[i]; } } if (child != null && "LI" == parent.tagName && "UL" == child.tagName) { parent.className = ("close" == parent.className ? "open" : "close"); child.className = ('expanded' == child.className ? 'none' : 'expanded'); } } } このサイトのソースです。http://home.impress.co.jp/books/urawaza/tipsbook2/068/ ここのスクリプトがさっぱりわからないので詳しく説明していただけると嬉しいです。 少し例を言うとまずBというのはなんでしょうか?変数でもないようですし、タグのような気もしますが タグに何かを代入というのはできるのでしょうか? またparentNode,childNodesというのはなんでしょうか?手元の本には載っていませんでした。 parent.childNodesとなってますがparentは変数ですよね?変数のプロパティというのが いまいちわかりません。 長くなってしまいましたがわかる範囲でけっこうですのでご回答していただければ幸いです。

  • 確認ページからフォームページに「戻る」時の入力内容の保持

    ラジオボタンと連動したチェックボックスがあります。 ラジオボタンを選択し、さらにチェックボックスに入力後、「確認」をクリックして確認ページから「戻る」の時にチェックボックスの入力内容の値が保持されておらず、困っています。 Firefoxではきちんと動作するのですが、IEなど他のブラウザでは動作しません。 入力内容を保持する方法はありますでしょうか? <script> window.onload=function(){ var f0=document.getElementById("f0"); try{ f0.addEventListener("click",function(e){func(e)},true); }catch(e){ f0.attachEvent("onclick",function(e){func(e)}); } } function func(e){ var obj= (e.srcElement || e.target); if(obj.nodeName!="INPUT") return false; switch(obj.type){ case "radio": setRadio(obj); break; case "checkbox": setCheckbox(obj,"シルク","Kind04[]","SELECT"); break; } } function setRadio(obj){ var n=obj.parentNode.firstChild; while(n){ if(n.nodeName=="INPUT" && n.type=="checkbox"){ n.disabled=obj.value!="アリ"; n.checked=false; } if(n.nodeName=="SELECT"){ n.disabled=true; n.selectedIndex=0; } n=n.nextSibling; } } function setCheckbox(obj,v,n,nn){ if(obj.value!=v) return false; var node=obj.parentNode.firstChild; while(node){ if(node.nodeName==nn && node.name==n){ node.disabled=!obj.checked; node.selectedIndex=0; } node=node.nextSibling; } } </script> </head> <body> <form action="./postmail.cgi" name="f0" method="post" id="f0"> <fieldset> <legend>■分類</legend> <input type="radio" value="ナシ" name="print" class="print" checked>ナシ <input type="radio" value="アリ" name="print" class="print" >アリ  ( <input type="checkbox" value="銀シールド" name="Kind04[]" class="Kind04" disabled>銀シールド <input type="checkbox" value="銀ペースト" name="Kind04[]" class="Kind04" disabled>銀ペースト <input type="checkbox" value="銅ペースト" name="Kind04[]" class="Kind04" disabled>銅ペースト <input type="checkbox" value="シルク" name="Kind04[]" class="Kind04" disabled>シルク  色 <SELECT name="Kind04[]" class="Kind04" disabled> <OPTION SELECTED VALUE="---">--- <OPTION VALUE="白">白 <OPTION VALUE="黒">黒 <OPTION VALUE="他">他 </SELECT> ) </fieldset><br> <input type="submit" value="確認する" />  <input type="reset" value="リセット" /> </form> </body> </html>

  • xmlのデータ取得方法について

    WshでXMLの取り込みをしているのですが、あるタグにくるとエラーが出ます。 どのように処理をすればよろしいのでしょうか? ■ ソース(抜粋) objNode.Load("ファイル名") For Each tmp In objNode.getElementsByTagName("東京都") For Each tmp2 In tmp.ChildNodes If tmp2.hasChildNodes Then For Each tmp3 In tmp2.getElementsByTagName("新宿区") For Each tmp4 In tmp3.ChildNodes If tmp4.nodeName = "AAA" Then n1 = tmp4.firstChild.nodeValue End If If tmp4.nodeName = "BBB" Then n2 = tmp4.firstChild.nodeValue End If Next Next End If Next Next ■ XMLデータ <東京都> <新宿区> <AAA> "大人の町" </AAA> <BBB /> <----------この形式のタグでエラーが出ます。 </新宿区> </東京都> <BBB />は、値が無いので、firstChildではエラーになるみたいです。("tmp4.firstChildはオブジェクトがありません。"とでます。) 以上ご教授よろしくお願いします。

  • VBAでxmlから特定の文字を変数に入れたい

    VBAからXMLを取得したくて方法を検索し、以下のコードで何とか取得ができました。 Sub httpRequest() Dim HttpReq As MSXML2.XMLHTTP Dim DomDoc As MSXML2.DOMDocument Dim targetURL As String targetURI = "http://www.drk7.jp/weather/xml/14.xml" 'HTTP GET Set HttpReq = CreateObject("MSXML2.XMLHTTP") HttpReq.Open "GET", targetURI, False HttpReq.send (Null) 'XML PARSE Set DomDoc = CreateObject("MSXML2.DOMDocument") DomDoc.LoadXML (HttpReq.responseText) dumpDomDoc DomDoc.ChildNodes Set HttpReq = Nothing Set DomDoc = Nothing End Sub Sub dumpDomDoc(objNode) Dim obj For Each obj In objNode MsgBox obj.ParentNode.nodeName & " : " & obj.NodeValue If obj.HasChildNodes Then dumpDomDoc obj.ChildNodes End If Next End Sub このコードですと、読み込んだXMLを一行づつメッセージボックスに延々と表示するだけなのですが、 例えば行先のXMLファイルにある<description>と</description>に囲まれた部分だけを変数に格納するにはどのように記述すればよろしいのでしょうか? ググってはみましたが知識不足の為、解説も理解できず困っております。 大変お手数ですがご教示いただけますようお願いします。

  • XMLの要素の内容の中に要素

    VisualBasic6.0にて、XMLを作成するプログラムを作っています。 XMLの作成、編集はMSXMLを使用しており、編集保存はできたのですが、下記のような要素の出力の仕方がわかりません。 <Node1>  あいうえお  <Node1-1>abcde</Node1-1>  かきくけこ </Node1> このように要素の文字列の途中に子要素を作成したいです。 「Node1」要素に、子要素「Node1-1」を追加するサンプルです。 Cドライブ直下に以下の内容のXMLファイル「test.xml」を作成 <?xml version="1.0" encoding="shift_jis"?> <Node1> </Node1> VB6にて、参照設定に「Microsoft XML V6.0」を追加し以下のコードを作成。 Private Sub Command1_Click() Dim xDoc As MSXML2.DOMDocument Set xDoc = New MSXML2.DOMDocument Dim node As IXMLDOMNodeList Dim Addnode As IXMLDOMNode Dim obj As IXMLDOMNode If xDoc.Load("C:\test.xml") Then Set node = xDoc.documentElement.selectNodes("/Node1") For Each obj In node Set Addnode = obj.appendChild(xDoc.createNode(NODE_ELEMENT, "Node1-1", "")) Addnode.Text = "abcde" Next xDoc.save ("C:\test.xml") End If Set xDoc = Nothing End Sub

  • 中身が一部しかわかっていないXMLの読み方

    XML例 <A> <B> bbb </B> <C> <D> ddd </D> </C> </A> C#でXMLを読み、特定のタグの中身を書き換える処理を実装しようしています。 ただしXMLファイルの中に書き換えたいタグ以外にどんなタグがあるかがわかっていません。 上記の例の場合、 「<A> - <C> - <D>のdddを書き換えたい」ということはわかっています。 この場合どのように行うのがよいでしょうか? ネットでのソースを参考に書き換えたい値のタグが見つかるまで再帰処理を行い タグが見つかった場合値を書き換えるような処理を書いてみました。 よくあるやり方や、もっとスマートな方法が有りましたらご教授お願いします。 また直接関係なくともヒントとなるようなものでも結構です。 よろしくお願いします。 void test() { XmlDocument document = new XmlDocument(); // ファイルから読み込む document.Load(filePath); readXML(document.DocumentElement); } void readXML(XmlNode node) { // if(node.Name == "D") // 書き換えたい値のタグか判定する //{ // 値を書き換える処理 //} if (node.HasChildNodes) { node = node.FirstChild; while (node != null) { readXML(node); node = node.NextSibling; } } }

専門家に質問してみよう