在VBA和dll之间传递任意types的数据

所以我正在使用VBA加载一个C ++ dll的Excel项目。 我想要做的是能够传递一个没有特定types(数据可以是数字或分类)的Excel范围到C ++ DLL(我可以描述我的Excel范围的最佳方式是typesvariant )。

所以这些步骤可能涉及:

  1. 在VBA中加载dll
  2. 发送excel范围到dll(范围可能包含数字和/或string的列的列)
  3. 在Excel文件中处理Excel中的数据

我正在考虑使用Excel变体和C ++变体。 但是我不清楚如何使用C ++变体,因为我找不到任何好的文档。

我收到的另一个build议是COM编程。

我的问题:

  • 一个善良的灵魂可能会为我提供关于如何进行的指针? (例如通过提供C ++原型,以及如何处理变体的简单示例)
  • 有没有人知道有关使用C ++变体(也可能与VBA共同使用)的良好文档/教程?
  • 如果速度是一个问题,是否使用COM更适合使用VARIANTS?
  • 是使用C API的一个选项?

更新:

  • 我需要操作的范围的大小可能很大(〜500,000行)。
  • 速度是一个因素,因此,我想尽可能避免不必要的复制。

如果你只想传递数据到dll(而不是指向实际的Excel对象,如Range ),你有两个基本的select:

  1. 你有大量的数据集,并希望尽可能避免复制。
    在这种情况下,您可能需要通过调用Range.Value来传递相同的Variant数组。 为了做到这一点,你将不得不编写一个从VB引用的小TLB,其中你将描述你导出的C ++函数为期望的SAFEARRAY(VARIANT)* 。 这是因为Declare运算符不会让你实际传递一个SAFEARRAY *。
    该function将如下所示:

     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 ++函数接受一个纯粹的int[] ,并在VB中声明它接受arr() as Long 。 在VB端,在Long s上分配一个数组,并从Range.Value数组中复制元素。