7

そのため、VBA を使用して C++ dll をロードする Excel プロジェクトに取り組んでいます。私がやりたいのは、特定の型のない Excel 範囲 (データは数値またはカテゴリである可能性があります) を C++ dll に渡すことができるようにすることです (私の Excel 範囲を説明できる最良の方法は型ですvariant)。

したがって、手順にはおそらく次のものが含まれます。

  1. dll を VBA にロードする
  2. Excel の範囲を dll に送信します (範囲には、数値の列および/または文字列の列が含まれる場合があります)
  3. dll ファイルで Excel のデータを操作する

ExcelバリアントとC++バリアントを使用することを考えています。しかし、C++ バリアントに関する適切なドキュメントが見つからなかったため、C++ バリアントの使用方法が明確ではありません。

私が受け取った別の提案は、COM プログラミングを使用することでした。

私の質問:

  • 親切な魂は、私がどのように進むべきかについての指針を提供してくれるでしょうか? (たとえば、C++ プロトタイプと、バリアントの処理方法の簡単な例を提供することにより)
  • C++バリアントの使用に関する(そしておそらくVBAとの)優れたドキュメント/チュートリアルを知っている人はいますか?
  • 速度が問題になる場合、VARIANT を使用するよりも COM を使用することをお勧めしますか?
  • C API の使用はオプションですか?

アップデート:

  • 操作する必要がある範囲のサイズは大きくなる可能性があります (~ 500,000 行)。
  • 速度が重要な要素であるため、不要なコピーはできるだけ避けたいと考えています。
4

1 に答える 1

3

データのみを dll に渡したい場合 (および などの実際の Excel オブジェクトへのポインターは渡さないRange場合)、次の 2 つの基本的なオプションがあります。

  1. 巨大なデータ セットがあり、可能な限りコピーを避けたい場合。この場合、 を呼び出して取得したの
    と同じ配列を渡したいと思うかもしれません。そのためには、VB から参照するための小さな TLB を作成する必要があります。その中で、エクスポートされた C++ 関数が. これは、オペレーターが実際に SAFEARRAY* を渡すことを許可しないためです。 関数は次のようになります。VariantRange.ValueSAFEARRAY(VARIANT)*Declare

    LONG __stdcall ReturnArrLowerBound(SAFEARRAY** ppArr)
    {
        if (ppArr == NULL) return -1;
        SAFEARRAY* pArr = (*ppArr);
    
        LONG res = 0;
        SafeArrayGetLBound(pArr, 1, &res);
    
        return res;
    }
    

    TLB の記述は次のようになります。

    [
        uuid(A686B138-D8CE-462e-AEF2-75DA4DBF1C75)
    ]
    library foo
    {
        [
            dllname("TestSafearray.dll")
        ]
        module vb
        {
            [entry("ReturnArrLowerBound")]
            LONG __stdcall ReturnArrLowerBound(SAFEARRAY(VARIANT)* ppArr);
        }
    }
    

    C++ プロジェクトには明らかに def ファイルが含まれます。

    LIBRARY "TestSafearray"
    
    EXPORTS
        ReturnArrLowerBound
    
  2. データ セットのサイズは適切で、多少のコピーは問題ありません。
    次に、C++ 関数が単なる a を受け入れるようint[]にし、VB でそれを受け入れるとして宣言しarr() as Longます。VB 側では、Longs に配列を割り当て、配列から要素をコピーしますRange.Value

于 2012-07-16T17:04:46.880 に答える