Excel VBA – 允许在XML中重复组节点?


介绍:


大家好,

我看着StackOverflow上的每个VBA XML主题都无济于事。 道歉,因为这个要求是相当大的,但我试图尽可能缓解stream量。

我需要有一个Excel到XML转换器与dynamic生成的模板/布局导入到一个网站。 这意味着我不能使用集成的Excel到XML,因为我将不得不提供一个模板,我需要脚本能够根据用户的意图生成。

为此,我正在使用CodeProject(2004)中Raymond Pang的Excel to XML脚本的修改版本。

该脚本使用“/”分隔符来定义节点的深度和path。


问题:


我现在的问题是,我不能让它生成重复组(即同名的多个子节点组)。 具体来说,网站的工作方式是我需要有多个部门/部门组。


例:


这里有一个示例Row with Repeating Group Nodes to generate in XML: 使用重复组节点以XML形式生成示例行

该脚本目前生成如下: 错误只有一个名为Section的组

虽然我需要它生成这样的: 正如我有两个科组

如果我的意思是不清楚,请让我知道,我会尽力详细说明。


剧本:


下面是用来从“ / suite / sections / section / section / section / section / section / name ”头部生成XML的脚本。

Function GenerateXMLDOM(rngData As Range, rootNodeName As String) With Worksheets("DATA") Const NODE_DELIMITER As String = "/" ' the default node delimiter Dim intColCount As Integer Dim intRowCount As Integer Dim intColCounter As Integer Dim intRowCounter As Integer Dim Location As String Location = "A1:C1" Dim rngCell As Range Dim rngCell2 As Range ' Create the XML DOM object Set ObjXMLDoc = CreateObject("Microsoft.XMLDOM") ObjXMLDoc.async = False ' NODE_PROCESSING_INSTRUCTION(7) --- reference http://www.devguru.com/Technologies/xmldom/quickref/obj_node.html Set Heading = ObjXMLDoc.createNode(7, "xml", "") ObjXMLDoc.appendchild (Heading) ' Set the root node Set top_node = ObjXMLDoc.createNode(1, rootNodeName, "") ObjXMLDoc.appendchild (top_node) Dim Nodes() As String 'Array storing the current splited node names Dim NodeStack() As String 'Array storing the last node names Dim new_nodes() ReDim NodeStack(0) ReDim new_nodes(0) With rngData ' The selected region on the DATA Excel Sheet passed in ' Discover dimensions of the data it will be dealing with... intColCount = .Columns.Count intRowCount = .Rows.Count Dim strColNames() As String ' The Array of column names ReDim strColNames(intColCount) ' First Row is the Field/Tag names ' Extract all the field names into array "strColNames" If intRowCount >= 1 Then ' Loop accross columns... and put names in array For intColCounter = 1 To intColCount ' Mark the cell under current scrutiny by setting ' an object variable... Set rngCell = .Cells(1, intColCounter) ' not support merged cells .. so quit If Not rngCell.MergeArea.Address = _ rngCell.Address Then MsgBox ("!! Cell Merged ... Invalid format") Exit Function End If strColNames(intColCounter) = rngCell.Text Next End If ' Loop down the table's rows For intRowCounter = 2 To intRowCount ReDim new_nodes(0) ReDim NodeStack(0) ' Loop accross columns... For intColCounter = 1 To intColCount ' Mark the cell under current scrutiny by setting ' an object variable... Set rngCell = .Cells(intRowCounter, intColCounter) ' Is the cell merged?.. If Not rngCell.MergeArea.Address = _ rngCell.Address Then MsgBox ("!! Cell Merged ... Invalid format") Exit Function End If ' divide the field name by the delimiter to get appropriate node names Nodes = Split(strColNames(intColCounter), NODE_DELIMITER) If UBound(Nodes) = 0 Then ReDim Nodes(1) Nodes(1) = strColNames(intColCounter) End If ' don't count it when no content If Trim(rngCell.Text) <> "" Then Dim i As Integer MatchAll = True For i = 1 To UBound(Nodes) If i <= UBound(NodeStack) Then If Trim(Nodes(i)) <> Trim(NodeStack(i)) Then 'not match MatchAll = False Exit For End If Else MatchAll = False Exit For End If Next ' match all means in same level as previous, so it needs to output for the last node If MatchAll Then i = i - 0 End If If UBound(new_nodes) < UBound(Nodes) Then ' enlong the array ReDim Preserve new_nodes(UBound(Nodes)) End If For t = i To UBound(Nodes) ' create uncommon nodes with the previous one Set new_nodes(t) = ObjXMLDoc.createNode(1, Nodes(t), "") Next For t = i - 1 To UBound(Nodes) - 1 If t >= 1 Then ' connect the nodes based on the hierarchy new_nodes(t).appendchild (new_nodes(t + 1)) End If Next Set Textcont = ObjXMLDoc.createTextNode(Trim(rngCell.Text)) new_nodes(UBound(Nodes)).appendchild (Textcont) If i = 1 Then top_node.appendchild (new_nodes(1)) End If NodeStack = Nodes End If Next ' finished a column Next End With ' Return the XMLDOM Set GenerateXMLDOM = ObjXMLDoc End With End Function 

故障排除:


我相信问题在于我添加子笔记并立即回到根目录。

节点(t)总是“/ Suite /” 在这里输入图像说明

我相信一个解决办法是给脚本记住父节点,并认为之后的任何内部都是组。

除了事实上我没有编写代码,我也不能有所有的部分/部分创build组的实例,因为我可能有部分/部分/部分/部分/部分/部分/部分/部分/名称数据所需要的深度。 也许通过检查目录的名称,如果标题以“/ Section”结尾,它会创build一个组,如果在“/ Section”之后还有别的东西继续下去的话? 任何其他方式来做到这一点?

非常感谢任何帮助,暗示和尝试解决这个问题。


请求的数据:


编辑:有太多的模块和一个Startform交织在一起,以得到这个一个一个高效地工作。 因此,我已经将相关file upload到了我的Google云端硬盘中,您可以轻松查看。

道歉,如果这是不允许的,我曾环顾四周,没有发现任何反对它。 但是我意识到我不可能有效地分享这个项目,否则,除非我做一个大的破解来简化它,否则结果可能会失效。

https://drive.google.com/open?id=0B4nBtjoQSKsSSVRhVEp6dklDYlU

这是另一个脚本将从用户input的数据生成的头的示例。 这通常在数据表的第一行,每行下面的单元格包含信息(名称,描述等),您可以input任何内容。 我还没有find一种方法来成功地粘贴这些,道歉。

这些是上面截图中展示的两组相同的path,我需要将第二组与前面的/ sections /节点中的第一组分开。

 /suite/sections/section/sections/section/name /suite/sections/section/sections/section/description /suite/sections/section/sections/section/sections/section/name /suite/sections/section/sections/section/name /suite/sections/section/sections/section/description /suite/sections/section/sections/section/sections/section/name