我在尝试使用包装器类在VBA中安排异步加载和解析XML文档时遇到错误。
遵循this msdn article和this tutorial中描述的完全用于异步处理MSXML2.XMLHTTP40.send方法的想法,我尝试为DOMDocument.loadXML做类似的事情。
以下是包装类DOMMonitor
Private domDoc As MSXML2.DOMDocument
Public Event onXmlLoadComplete(d As MSXML2.DOMDocument)
Public Sub loadXML(XmlFilePath As String)
Set domDoc = CreateObject("MSXML2.DOMDocument")
domDoc.async = True
domDoc.onreadystatechange = Me ' error occurs here
domDoc.Load XmlFilePath
End Sub
Public Sub onLoadComplete()
If domDoc.readyState = "4" Then
RaiseEvent onXmlLoadComplete(domDoc)
End If
End Sub
我通过设置VB_UserMemId = 0使onLoadComplete
成为默认方法,因此应该在domDoc
触发onreadystatechange
时调用它。
但是当我调用loadXML
Dim dm As DomMonitor
Set dm = New DomMonitor
dm.loadXML txtXMLData
我在此行中收到以下运行时错误:
domDoc.onreadystatechange = Me
此对象无法接收'onreadystatechange'事件。编组对象的IDispatch接口时发生错误
我做错了什么,这里有一个好的解决方法吗?
提前致谢。
P.S。我重新发布该事件的原因是我不一定要为此目的使用最终订户的默认方法。然而,就目前情况而言,我甚至没有达到那个阶段。
答案 0 :(得分:3)
我读到msdn文章的方式是将包装类分配给readystatechange,该对象必须是IXMLHTTPRequest或IServerXMLHTTPRequest对象(项目符号3)。由于您的对象是DOMDocument,因此readystatechange不接受对象。
但是,我猜你可以实例化一个DOMDocument WithEvents(项目符号2),另一方面是多余的。我没有足够大的xml文件来测试,但我认为这应该有效。我假设如果该类失去了范围,所有的赌注都会关闭,所以我把它变成了一个全局变量。
在标准模块中
Public clsDOMMonitor As CDOMMonitor
Sub test()
Set clsDOMMonitor = New CDOMMonitor
clsDOMMonitor.loadXML "C:\Users\dkusleika\Downloads\wurfl-2.3.xml"
End Sub
在CDOMMonitor类中
Private WithEvents mDoc As MSXML2.DOMDocument
Private Sub mDoc_onreadystatechange()
If mDoc.readyState = 4 Then
MsgBox "second"
End If
End Sub
Public Sub loadXML(XmlFilePath As String)
Set mDoc = New MSXML2.DOMDocument
mDoc.async = True
mDoc.Load XmlFilePath
MsgBox "first"
End Sub
我认为将async设置为True是正常工作所需的全部内容。我的100k xml文件可能做得太快,以至于事件永远不会放弃控制。但是如果你有一个足够大的xml文件,我想你会在“第二个”之前得到“第一个”。
答案 1 :(得分:0)
在延迟绑定时将类的Instancing属性从Private
更改为PublicNotCreatable
,同时还应用您提到的调整。
在早期绑定时使用上面的示例(如您的情况)。