Excel中VBA读取XML到TreeView时出现Error 13类型不匹配错误的问题求助
你好!我在Excel里做了一个带TreeView控件的小表单,引用了OLE Automation、Microsoft Forms 2.0、Microsoft Windows Common Controls 6.0 (SP6)和Microsoft XML, v6.0这些库。
我在UserForm_Initialize()里调用LoadTreeViewFromXmlFile方法,传入了有效的XML文件路径和TreeView控件,代码是这样的:
Call LoadTreeViewFromXmlFile("C:\Users\...\my.xml", TreeView1)
但运行时在AddChildrenToTreeView子程序的For Each循环那里报了Error 13 类型不匹配的错误,我实在搞不懂原因,能不能帮我分析一下?提前谢谢大家了!
我的代码如下:
Private Sub LoadTreeViewFromXmlFile(ByVal file_name As String, ByVal trv As TreeView) Dim xml_doc As DOMDocument60 ' Load the XML file into the DOMDocument. Set xml_doc = New DOMDocument60 xml_doc.Load file_name ' Add the root node's children to the TreeView. TreeView1.Nodes.Clear AddChildrenToTreeView trv, Nothing, _ xml_doc.DocumentElement End Sub ' Add this XML node's children to the indicated TreeView ' node. Private Sub AddChildrenToTreeView(ByVal trv As TreeView, ByVal treeview_parent As Node, ByVal xml_node As IXMLDOMElement) Dim xml_child As IXMLDOMElement Dim new_node As Node ' Examine each XML child. Error 13 Type mismatch - why? For Each xml_child In xml_node.ChildNodes ' Add the child to the TreeView. If treeview_parent Is Nothing Then Set new_node = trv.Nodes.Add(, , , _ xml_child.nodeName) Else Set new_node = trv.Nodes.Add(treeview_parent, _ tvwChild, , xml_child.nodeName) End If new_node.EnsureVisible ' Add the child's children. AddChildrenToTreeView trv, new_node, xml_child Next xml_child End Sub
问题原因分析
出现类型不匹配的核心原因是:xml_node.ChildNodes返回的是IXMLDOMNodeList集合,这个集合里的节点不只有IXMLDOMElement类型(也就是我们要的XML元素节点),还可能包含文本节点、注释节点、空白节点等其他类型的XML节点。而你声明的循环变量xml_child是IXMLDOMElement类型,当循环到非元素类型的节点时,就会触发类型不匹配错误。
解决方法
我们可以修改循环逻辑,先把循环变量声明为通用的IXMLDOMNode类型,然后在循环内部判断节点类型,只处理元素节点(节点类型常量NODE_ELEMENT的值是1)。修改后的AddChildrenToTreeView代码如下:
Private Sub AddChildrenToTreeView(ByVal trv As TreeView, ByVal treeview_parent As Node, ByVal xml_node As IXMLDOMElement) Dim xml_child As IXMLDOMNode ' 改为通用节点类型 Dim new_node As Node Dim element_child As IXMLDOMElement ' 用于转换元素节点 ' 遍历所有子节点 For Each xml_child In xml_node.ChildNodes ' 只处理元素类型的节点 If xml_child.NodeType = NODE_ELEMENT Then Set element_child = xml_child ' 转换为元素节点类型 ' Add the child to the TreeView. If treeview_parent Is Nothing Then Set new_node = trv.Nodes.Add(, , , _ element_child.nodeName) Else Set new_node = trv.Nodes.Add(treeview_parent, _ tvwChild, , element_child.nodeName) End If new_node.EnsureVisible ' Add the child's children. AddChildrenToTreeView trv, new_node, element_child End If Next xml_child End Sub
这样修改后,循环会跳过非元素类型的节点,只处理我们需要的XML元素,就能避免类型不匹配的错误了。
备注:内容来源于stack exchange,提问作者Nick

