查看: 7701|回复: 2

怎样在VBA中调用C#写成的DLL

[复制链接]
论坛徽章:
0
跳转到指定楼层
1#
发表于 2008-2-27 22:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
tiger原创
转载请注明出处

在项目中遇到客户的一个需求,
需要在VBA中引用C#写成的DLL,并调用这个DLL中某个类的方法。
将VBA中计算得出的数据通过参数传给DLL。

经过调查,结论是:
.net做出的dll不同于AxtiveX,是不能直接调用的。但可以转换成COM。
关于这个可以参照
http://msdn2.microsoft.com/zh-cn/library/zsfww439.aspx

最后的实现方法如下:
1.        首先来编写能够被VBA调用的DLL,用Visual Studio创建一个ClassLibrary类型的project,步骤是New->Project->Visual C# Projects ->Class Library。将这个project命名为LMT_COMObject(举例说明,名字自己随便起)。
2.        在Project中写出的代码如下:
复制内容到剪贴板代码:
//**************************************************
//
//      www.itshaik.com
//
//      Author:tiger
//
//      MSN:beck10_999@hotmail.com
//
//**************************************************
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace LMT_COMObject
{
        [Guid("694C1820-04B6-4988-928F-FD858B95C880")]
        public interface LMT_Interface
        {        
                [DispId(1)]
                void LMT_test(string a);
        }

        // Events interface Database_COMObjectEvents
        [Guid("47C976E0-C208-4740-AC42-41212D3C34F0"),
        InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
        public interface LMT_Events
        {
        }

        [Guid("9E5E5FB2-219D-4ee7-AB27-E4DBED8E123E"),
        ClassInterface(ClassInterfaceType.None),
        ComSourceInterfaces(typeof(LMT_Events))]
        public class LMT_Class : LMT_Interface
        {
                public LMT_Class()
                {
                }

                public void LMT_test(string a)
                {
                        MessageBox.Show(a);
                }
        }
}
3.在编译之前,要首先将我们写的这个COM object 注册为COM Interop,这里使用的是.NET提供的SN.EXE。
开始->运行->CMD,调出DOS窗口。
在DOS窗口中进入到刚刚建立的LMT_COMObject这个Project的根目录下。(例如C:\Documents and Settings\Administrator\Desktop\LMT\LMT_COMObject)
然后执行命令sn -k LMT_COM_Key.snk
(注意,在执行此命令前,请确认你已经配置了.NET SDK Bin 的系统环境变量。
配置方法: 在系统环境变量的Path中加入C:\Program Files\Microsoft Visual Studio .NET\FrameworkSDK\Bin)
成功注册后,在LMT_COMObject这个Project的根目录下会生成一个名为LMT_COM_Key.snk的文件。
4.打开LMT_COMObject这个Project的AssemblyInfo.cs文件,
做出如下修改
[assembly: AssemblyKeyFile("LMT_COM_Key.snk")]
5.配置LMT_COMObject这个Project的属性,打开Project属性窗口,在Configuration Properties中的Build里,将Register for COM interop设置为True。
6.编译LMT_COMObject这个Project。会在 LMT_COMObject\bin\Debug下面生成3个文件。
LMT_COMObject.dll,LMT_COMObject.pdb,LMT_COMObject.tlb。LMT_COMObject.tlb就是我们将来要在VBA中引用的,通过它就可以引用LMT_COMObject.dll。
7.下面介绍如何在VBA中引用这个DLL。
首先,建立一个Excel文件,插入一个名为CommandButton1的button,双击此button添加事件,如下
Private Sub CommandButton1_Click()
   
End Sub
打开VBA的编辑窗口(快捷键为ALT+F11),在菜单栏中,Tools->References,弹出References窗口,点击Browse,找到LMT_COMObject\bin\Debug路径下的LMT_COMObject.tlb这个文件,选择它,然后点OK。
此时已经成功引用到LMT_COMObject.dll。
8.在VBA的Object Browser中可以看到Library中有LMT_COMObject,Class名为LMT_Class,Member为LMT_test。
如果看到以上信息,那么,就可以在VBA中调用了。
9.在
Private Sub CommandButton1_Click()
   
End Sub
加入调用,
Dim lmt As New LMT_COMObject.LMT_Class
Call lmt.LMT_test(result)
写好的代码效果为
复制内容到剪贴板代码:
Private Sub CommandButton1_Click()
    Dim lmt As New LMT_COMObject.LMT_Class
    Call lmt.LMT_test(“string returned from VBA”)
End Sub
10.在Excel中按下按CommandButton1,就会弹出窗体,显示string returned from VBA。
说明已经成功的在VBA中调用了LMT_COMObject.dll的LMT_Class类中的LMT_test方法,并将一个string类型的参数传给了LMT_test方法,LMT_test方法执行的结果就是将这个string类型的参数的值通过弹出窗体给显示出来。

传给LMT_test方法的这个string类型的参数,可以是在VBA中按照业务逻辑计算出的结果,从而实现了上面说到的需求。

以上,如果有什么问题欢迎加我MSN探讨。

附件中提供了
LMT_COMObject这个Project的源代码
(为了方便不同版本的环境,分为vs2002版本和vs2005版本两个版本。)
vba_test.xls提供了VBA的源代码
(里面我写了一个简单的示例,实现了将Excel每一行的第一列和第二列相加,得出的结果放到第三列,同时将这个结果通过调用LMT_COMObject.dll用windows的窗体弹出显示)

link:http://www.itshaik.com/bbs/viewthread.php?tid=2246
论坛徽章:
0
2#
发表于 2008-2-28 13:35 | 只看该作者
顶一下~!!

请问你的MSN在哪里???

使用道具 举报

回复
论坛徽章:
0
3#
 楼主| 发表于 2008-2-28 21:45 | 只看该作者
MSN:beck10_999@hotmail.com

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表