1

ラッパー クラスを使用して、VBA で XML ドキュメントの非同期読み込みと解析を調整しようとすると、エラーが発生します。

MSXML2.XMLHTTP40.send メソッドの非同期処理で完全に機能したこの msdn 記事このチュートリアルで説明されているアイデアに従って、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時に呼び出されるはずです。domDoconreadystatechange

しかし、私が呼び出すとき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に設定することだけだと思います。私の100kxmlファイルはおそらく非常に高速に実行されるため、イベントが制御を放棄することはありません。しかし、十分に大きなxmlファイルがある場合は、「second」の前に「first」を取得すると思います。

于 2013-03-13T17:34:17.030 に答える