2012-07-16 63 views
6

因此,我正在使用VBA加載C++ dll的Excel項目。我想要做的是能夠將沒有特定類型(數據可以是數字或分類)的Excel範圍傳遞給C++ dll(我能描述我的Excel範圍的最佳方式是variant類型)。在VBA和dll之間傳遞任意類型的數據

所以步驟可能包括:

  1. 負載在VBA的dll
  2. 發送Excel範圍到DLL(範圍可包含數字和/或字符串列的列)
  3. 操縱來自excel的dll文件中的數據

我想使用excel變體和C++變體。但是我不清楚如何使用C++變體,因爲我找不到任何好的文檔。

我收到的另一個建議是使用COM編程。

我的問題:

  • 可能是一種靈魂可能提供有關如何繼續爲我指點? (例如,通過提供C++原型,以及如何處理該變體的一個簡單示例)
  • 有誰知道有關使用C++變體(也可能與VBA一起使用)的任何良好的文檔/教程?
  • 如果速度有問題,是否使用COM更適合使用VARIANTS?
  • 正在使用C API的一個選項?

UPDATE:

  • 我需要操作範圍的大小可以是大的(〜50萬行)。
  • 速度是一個因素,因此,我想盡可能避免不必要的複製。

回答

2

只要你只想數據的dll傳遞(而不是指向實際的Excel對象如Range),你有兩個基本的選擇:

  1. 你有龐大的數據集,並希望儘可能避免複製。
    在這種情況下,您可能希望通過調用Range.Value來獲得相同的Variant數組。爲了做到這一點,你將不得不寫一個小的TLB來引用VB,其中你將把你導出的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看起來就像是:

    [ 
        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++函數只接受int[]並在VB中聲明它接受arr() as Long。在VB端,在Long s上分配一個數組,並從Range.Value數組中將元素複製到該數組中。

+0

謝謝!如果我沒有弄錯,編寫TLB涉及到COM編程,對吧?那麼這是否會限制應用程序的可移植性(特別是在Linux機器上)? – SMir 2012-07-16 18:25:23

+1

@SMir不,它本身不涉及COM編程。您只需編寫TLB以便VB能夠理解您的C++函數簽名。除此之外,該函數是一個普通的,非COM的經典風格導出函數。 – GSerg 2012-07-16 18:28:12

+0

感謝您的及時迴應。使用'Variant'是否允許我將混合類型傳遞給DLL?或者它只允許有一個類型(不管是字符串還是數字等)。 – SMir 2012-07-16 18:32:40