2012-07-16 14 views
6

私はVBAを使用してC++ dllをロードするExcelプロジェクトに取り組んでいます。私がしたいのは、特定のタイプ(データは数値またはカテゴリにすることができます)を持たないExcelの範囲をC++のdllに渡すことです(私のExcelの範囲を記述する最良の方法は、タイプvariantです)。VBAとdllの間で任意の型のデータを渡す

ので、手順はおそらく関与:

  1. DLLをロードVBA
  2. DLLにExcelの範囲を送信します(範囲は数字および/または文字列の列の列を含んでいてもよい)
  3. 操作dllファイルのExcelからのデータ

私はexcel variantとC++ variantを使用することを考えています。しかし、C++バリアントをどのように使用すればよいか分からないので、私には明らかではありません。

私が受け取った別の提案は、COMプログラミングです。

私の質問:

  • 種類の魂は、おそらく続行する方法上の私のための指針を提供してもらえますか? (例えば、C++プロトタイプを提供することによって、バリアントを扱う方法の簡単な例)
  • C++バリアントの使用に関するよくある文書/チュートリアルを知っていますか?
  • スピードが問題の場合は、VARIANTSを使用するよりもCOMを使用する方が好ましいですか?
  • C APIをオプションで使用していますか?

UPDATE:私は操作する必要がある範囲の

  • サイズが大きく(〜50万行)ことができます。
  • 速度は重要な要素ですので、できるだけ不要なコピーを避けたいと思います。あなただけ(などRangeなど、実際のExcelオブジェクトへのポインタではなく)DLLにデータを渡したい提供

答えて

2

、次の2つの基本的なオプションがあります。

  1. をあなたは巨大なデータセットを持っているとしたいです可能な限りコピーを避けてください。
    この場合、同じVariant配列をRange.Valueと呼ぶことで渡すことができます。これを行うには、VBから参照するための小さなTLBを書く必要があります。ここでは、エクスポートされたC++関数をSAFEARRAY(VARIANT)*と期待しています。これは、Declareオペレータが実際にSAFEARRAY *を渡すことができないためです。
    関数は次のようになります。

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

    そして、TLBのdescripionはそのようになります。

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

    そして、あなたのC++のプロジェクトは明らかにDEFファイルが含まれます

    あなたのデータセットは合理的なサイズであり、コピーは少しでも気になりません。
    次に、int[]を受け入れてVBで、arr() as Longを受け入れるようにC++関数を宣言します。 VB側では、Longに配列を割り当て、Range.Value配列からその要素をコピーします。

+0

ありがとうございます!誤解されていなければ、TLBを書くにはCOMプログラミングが必要です。そしてそれはアプリケーションの移植性を制限します(特にLinuxマシン)。 – SMir

+1

@SMirいいえ、COMプログラミング自体は含まれていません。あなたは、VBがあなたのC++関数の署名を理解できるようにTLBを書くだけです。それ以外の関数は、COMではない普通のスタイルのエクスポートされた関数です。 – GSerg

+0

迅速な対応に感謝します。 'Variant 'を使用すると、混合型をDLLに渡すことができますか?それとも、単一のタイプ(文字列か数字かなど)だけを持つことができます。 – SMir

関連する問題