0

我正在开发一个项目,该项目为用户构建数学模型,然后可以以不同的格式输出它们。现在我支持用 Python、Java、C++ 输出。这行得通,我只是自动生成代码并称之为一天。

但是,已经提出了新的要求。用户希望能够在 Excel 中使用模型。我做了一些搜索,发现http://richnewman.wordpress.com/2007/04/15/a-beginner%E2%80%99s-guide-to-calling-a-net-library-from-excel/

所以这是一个不错的开始,但我需要以编程方式执行此操作。模型作为对象存储在更大的程序中。如果用户选择导出为 Excel 的 DLL,我会采用一些样板代码并插入我想要使用的方法。

但是,似乎我需要注册 COM 互操作的代码。我的测试代码创建了一个 DLL,我可以使用它 C# 并访问它的方法。但是试图在 Excel 2000 中添加引用(我知道,我知道,公司很烂) VBA 不起作用。似乎没有创建 TLB 文件,因此没有任何内容可供加载。

如果我将生成的代码编译为独立代码并检查了使 COM 可见并注册了 com 互操作框,则会生成 TLB,但 Excel VBA 会引发自动化错误。

所以实际的问题。

1) 我怎样才能在运行时创建一个 COM 可见并为 COM 互操作重新注册的 DLL?

2)我如何让 Excel 玩得很好。

简单的示例 DLL 代码如下:

using System;
using System.Runtime.InteropServices;

namespace VSN
{

  [ComVisibleAttribute(true)]
  [ClassInterface(ClassInterfaceType.AutoDual)]
  public class VSNFunctions
  {
      public VSNFunctions()
      {
      }

      /// <summary>
      /// Adds 2 variables together.
      /// </summary>
      /// <param name=\"v1\">First Param</param>
      /// <param name=\"v2\">Second Param</param>
      /// <returns>Sum of v1 and v2</returns>
      public double Add2(double v1, double v2)
      {
          return v1 + v2;
      }
      public double Sub2(double v1, double v2)
      {
          return v1 - v2;
      }
      public double Mul2(double v1, double v2)
      {
          return v1 * v2;
      }
      public double div2(double v1, double v2)
      {
          return v1 / v2;
      }

      [ComRegisterFunctionAttribute]
      public static void RegisterFunction(Type t)
      {
          Microsoft.Win32.Registry.ClassesRoot.CreateSubKey("CLSID\\{"+t.GUID.ToString().ToUpper() + "}\\Programmable");
      }


      [ComUnregisterFunctionAttribute]
      public static void UnregisterFunction(Type t)
      {
          Microsoft.Win32.Registry.ClassesRoot.DeleteSubKey("CLSID\\{"+t.GUID.ToString().ToUpper() + "}\\Programmable");
      }
  }
}

以编程方式构建 DLL 的代码如下:

CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("CSharp");
CompilerParameters parameters = new CompilerParameters();
parameters.GenerateExecutable = false;
String exeName = String.Format(@"{0}\{1}.dll", System.Environment.CurrentDirectory, "VSNTest");
MessageBox.Show(exeName);
parameters.OutputAssembly = exeName;

parameters.CompilerOptions = "/optimize";

CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, DLLString);
4

1 回答 1

0

如何:在 Visual C# 项目中向 VBA 公开代码

若要使 VBA 代码能够调用 Visual C# 项目中的代码,请修改代码以使其对 COM 可见,然后在设计器中将 ReferenceAssemblyFromVbaProject 属性设置为 True。

于 2012-03-20T15:40:46.417 回答