2

バックグラウンド

VB によって作成された古い ActiveX コントロールがありました。この ActiveX コントロールを Excel ワークブックに追加し、いくつかのプロパティを設定しました。これらのプロパティは、ブックが保存されたときに保存されました。具体的には、VB コードで PropertyBag を使用して UserControl_WriteProperties 関数に保存されました。そのため、これらのプロパティはこれまでワークブックに保持されていました。

私の仕事

古いコントロールとの下位互換性を保つために、C++ を使用して新しい ActiveX コントロールを作成する必要があります。古い Excel ワークブックにある ActiveX コントロールに保持されているすべての情報が必要です。そこで、ActiveX コントロールに IPersistPropertyBag を実装します。

私の予想では、古い Excel ワークブックを開いたときに、PropertyBag を介してすべての情報を正しく取得する必要があります。

問題

Excel ワークブックに保存されている情報がストリーム形式であることがわかりました。新しい ActiveX コントロールに IPersistStreamInit を実装できますが、Excel ブックに保持されているストリームの形式がわかりません。そのため、Excel ワークブックに保存されている情報を取得できません。

VB コードで Propertybag 経由で保存された情報が、なぜ Stream 形式で保存されたのか疑問に思います。

質問

このシナリオで ActiveX コントロールに保持されているすべての情報を取得する方法はありますか? 2日間探しているのですが、方法が見つかりません。

4

2 に答える 2

1

このタスクを処理する VB6 COM dll を作成して、このタスクを実行しました。

Option Explicit
Dim objMyPropertyBag As PropertyBag

Public Sub Contents(a_content As Variant)
    objMyPropertyBag.Contents = a_content
End Sub

Public Function Read(key As String) As String
On Error GoTo Error_Handler
    Read = objMyPropertyBag.ReadProperty(key)
Error_Handler:
    MsgBox Err.Source & Err.Number
End Function

Private Sub Class_Initialize()
    Set objMyPropertyBag = New PropertyBag
End Sub

古い ActiveX オブジェクトを含む古い Excel ワークブックを開くと、次の手順を実行します。

  1. IStream を提供する IPersistStreamInit::Load 関数になります。
  2. このストリームを読み込み、コンテンツと呼ばれるVT_UI1(BYTEの配列に等しい)のSAFEARRAYのVARIANTにパースします。
  3. 「contentReader」と呼ばれる VB6 COM dll のインスタンスを作成します。
  4. contentReader->Contents(content) を呼び出します (作成した SAFEARRAY をそれに渡します)。

これで、contentReader->Read([in] key, [out] value) を使用して、PropertyBag 内の任意のキーを読み取ることができます。

于 2013-01-24T04:43:33.120 に答える
1

プロパティ バッグはストリームに保存されます。それだけです。

あなたの C++ コントロールは IPersistStream を実装していると思われるので、Excel はそれを使用しようとしています。まず、C++ コントロールから IPersistStream、IPersistStreamInit、および IPersistStorage を取り除き、IPersistPropertyBag だけを残すことをお勧めします。

于 2012-12-20T16:56:24.817 に答える