1

我在尝试使用包装类在 VBA 中安排异步加载和解析 XML 文档时遇到错误。

按照这篇 msdn 文章本教程中描述的想法,这些想法对于 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

onLoadComplete通过设置 VB_UserMemId = 0 设置了默认方法,因此应该在domDocfires时调用它onreadystatechange

但是,当我调用loadXML

Dim dm As DomMonitor
Set dm = New DomMonitor
dm.loadXML txtXMLData

我在这一行中收到以下运行时错误:

domDoc.onreadystatechange = Me

此对象无法接收“onreadystatechange”事件。编组对象的 IDispatch 接口时发生错误

我做错了什么,这里有一个好的解决方法吗?

提前致谢。

PS我重新发布事件的原因是我不一定要为此使用最终订阅者的默认方法。然而,就目前的情况来看,我什至没有达到那个阶段。

4

2 回答 2

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 文件,我认为您会在“第二”之前获得“第一”。

于 2013-03-13T17:34:17.030 回答
0

将类的 Instancing 属性从后期绑定更改为,同时还应用您提到的调整PrivatePublicNotCreatable

早期绑定时使用上面的示例(如您的情况)。

于 2015-09-11T11:47:42.670 回答