ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 34406|回复: 21

vba动态添加引用的两种方法

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2011-6-9 02:24 | 显示全部楼层 |阅读模式
本帖已被收录到知识树中,索引项:VBE环境开发
添加引用无非有两种方法,第一种是使用addfromfile 另外一种是使用addfromguid方法。 这两种方法的优缺点如下:
addfromguid方法可以避免判断应用程序的版本。 例如 Microsoft Excel's object model 的GUID 是 {00020813-0000-0000-C000-000000000046} 。无论是2007 2003还是2010 ,这个GUID是不会变化的。这时使用addfromguid方法避免了要对不同版本进行判断。就算用户将来使用2012 (地球末日版),也不需要修改VBA代码。
addfromfile 方法用在加载用户自定义组件,或者大型应用程序的某一个功能模块是比较有用。 在发布时,只需要拷贝相应的组件文件放在插件目录下,然后使用VBA动态获得插件所在目录就可以加载了。这样做的好处是显而易见的。 第一,你不用为了使用某一个程序的其中一个功能而安装整个程序。只需要复制其中一个组件就可以了。 第二,发布和更新也比较灵活, 插件可以放在任何地方。 更新时可以动态unload插件,然后使用vba下载更新后的组件并且覆盖旧组件。
以上两种方法只要综合利用一定能够使插件的升级更新变得简便。

另外附上两段代码:
Sub Grab_References()
Dim n As Integer
On Error Resume Next
For n = 1 To ThisWorkbook.VBProject.References.count
    Cells(n, 1) = ThisWorkbook.VBProject.References.Item(n).Name
    Cells(n, 2) = ThisWorkbook.VBProject.References.Item(n).Description
    Cells(n, 3) = ThisWorkbook.VBProject.References.Item(n).GUID
    Cells(n, 4) = ThisWorkbook.VBProject.References.Item(n).Major
    Cells(n, 5) = ThisWorkbook.VBProject.References.Item(n).Minor
    Cells(n, 6) = ThisWorkbook.VBProject.References.Item(n).fullpath
Next n
End Sub
这段代码可以获取当前文档所有引用的详细信息
Visual Basic For Applications        {000204EF-0000-0000-C000-000000000046}        4        0        C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6.DLL
Microsoft Excel 12.0 Object Library        {00020813-0000-0000-C000-000000000046}        1        6        C:\Program Files\Microsoft Office\Office12\EXCEL.EXE
Microsoft Forms 2.0 Object Library        {0D452EE1-E08F-101A-852E-02608C4D0BB4}        2        0        C:\WINDOWS\system32\FM20.DLL
OLE Automation        {00020430-0000-0000-C000-000000000046}        2        0        C:\WINDOWS\system32\stdole2.tlb
Microsoft Office 12.0 Object Library        {2DF8D04C-5BFA-101B-BDE5-00AA0044DE52}        2        4        C:\Program Files\Common Files\Microsoft Shared\office12\mso.dll
Microsoft Scripting Runtime        {420B2830-E718-11CF-893D-00A0C9054228}        1        0        C:\WINDOWS\system32\scrrun.dll
Microsoft ActiveX Data Objects 2.8 Library        {2A75196C-D9EB-4129-B803-931327F72D5C}        2        8        C:\Program Files\Common Files\System\ado\msado15.dll

第二段代码:使用addfromguid引用。
Sub AddReference()
   Dim RefItem(7, 3) As Variant
   
    RefItem(0, 0) = "{000204EF-0000-0000-C000-000000000046}"
    RefItem(0, 1) = 4
    RefItem(0, 2) = 0
   
    RefItem(1, 0) = "{00020813-0000-0000-C000-000000000046}"
    RefItem(1, 1) = 1
    RefItem(1, 2) = 6
   
    RefItem(2, 0) = "{0D452EE1-E08F-101A-852E-02608C4D0BB4}"
    RefItem(2, 1) = 2
    RefItem(2, 2) = 0
   
    RefItem(3, 0) = "{00020430-0000-0000-C000-000000000046}"
    RefItem(3, 1) = 2
    RefItem(3, 2) = 0
   
    RefItem(4, 0) = "{2DF8D04C-5BFA-101B-BDE5-00AA0044DE52}"
    RefItem(4, 1) = 2
    RefItem(4, 2) = 4
   
    RefItem(5, 0) = "{420B2830-E718-11CF-893D-00A0C9054228}"
    RefItem(5, 1) = 1
    RefItem(5, 2) = 0
   
    RefItem(6, 0) = "{2A75196C-D9EB-4129-B803-931327F72D5C}"
    RefItem(6, 1) = 2
    RefItem(6, 2) = 8
   
    Dim strGUID As String, theRef As Variant, I As Long
     
    On Error Resume Next
     
   For I = ThisWorkbook.VBProject.References.count To 1 Step -1
        Set theRef = ThisWorkbook.VBProject.References.Item(I)
        If theRef.isbroken = True Then
            ThisWorkbook.VBProject.References.Remove theRef
        End If
    Next I
     
    err.clear
     
   Dim errmsg As String
   
     For I = 0 To 6
      ThisWorkbook.VBProject.References.AddFromGuid GUID:=RefItem(I, 0), Major:=RefItem(I, 1), Minor:=RefItem(I, 2)
      Select Case err.Number
      Case Is = 32813
         '引用已经加载,无需做任何事情
      Case Is = vbNullString
         '成功加载
      Case Else
         '加载出现错误,保存错误信息
        errmsg = errmsg & RefItem(I, 0) & "出现错误错误"
    End Select
    Next I
If errmsg <> "" Then
MsgBox errmsg
End If
    On Error GoTo 0
   
End Sub

[ 本帖最后由 citypanther 于 2011-6-9 02:29 编辑 ]

评分

2

查看全部评分

TA的精华主题

TA的得分主题

发表于 2011-6-9 07:50 | 显示全部楼层
谢谢楼主分享,贴上以前收集的一篇类似文章,仅供参考。
原帖由 yinchao13 于 2008-11-16 8:13:11发表 http://bbs.vsharing.com/ArticleList.aspx?cid=2040
VBA中代码加载引用方法实践

       因为excel使用范围广泛,VBA编程极大方便了数据的处理及提供了很好的方便易用的编程环境,但也许你在编程项目处理中经常会遇到这样的情况:编写好的程序有时候在客户的电脑无法正常运行,这很大一部分原因是因为客户的电脑没注册你使用的控件和对象引用。当然你也可以指导客户通过“工具”——“引用”等手工设置解决问题。

      那能不能通过代码自动完成这样的操作?如果能实现,则就可以实现VBA程序文件真正的共享?答案是肯定的,下面笔者参考网上一些资料和实践经历谈下如何自动加载可使用的引用中需要加载的对象。这里暂时没涉及VBA控件的自动注册。

      一,首先不同的引用(包括版本)是不同的,唯一标识的是GUID号,而且相同版本的引用在不同的机器上这个也是确定的。所以第一步我们必须获取我们使用的该引用的GUID,Major,和 Minor三个参数。

           方法可以是:

            Private Sub aas()
                '遍历所有已使用的引用

               Dim i As Integer
                i = 2
                With Sheet1
              For Each refed In ThisWorkbook.VBProject.References
                    .Cells(i, 1) = refed.Name
                    .Cells(i, 2) = refed.GUID
                    .Cells(i, 3) = refed.Major
                    .Cells(i, 4) = refed.Minor
                    i = i + 1
              Next
             End With
              End Sub

        二,获得上面三个参数后,在初始化代码中通过ThisWorkbook.VBProject.References.AddFromGuid 加载该引用。

        下面以加载ado2.6为例,代码如下:

      Public Sub LoadFrom()
     '首先检查ADO又没安装
    Dim bolFindAdo As Boolean
   
    On ERR GoTo ERRHandle
    For Each refed In ThisWorkbook.VBProject.References
        If refed.Name = "ADODB" Then
           If refed.isbroken Then
              ThisWorkbook.VBProject.References.Remove refed'如引用已损坏,删除
           Else
              bolFindAdo = True
              Exit For
           End If
        End If
    Next
    If bolFindAdo = False Then
       '还没安装,现在安装ado2.6
       ThisWorkbook.VBProject.References.AddFromGuid _
       GUID:="{00000206-0000-0010-8000-00AA006D2EA4}", Major:=2, Minor:=6
    End If
    FrmPrint.Show 0
    Exit Sub
ERRHandle:
    msgbox(ERR.Description & "加载失败,请联系管理员!")
    Exit Sub
End Sub

   三,至此引用加载完毕,在客户机器上就可以安全使用该引用。这些经过笔者昨晚测试,初步成功,在这里总结出来,希望能给大家提供一个简单可行的操作实践线索。有疑问或不同见解,欢迎交流。

          至于VBA控件的自动注册,以后经实践确认后总结再放上。

[ 本帖最后由 baomaboy 于 2011-6-9 07:54 编辑 ]

TA的精华主题

TA的得分主题

发表于 2011-6-9 09:06 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
还没有到这地步,先收起来,总有一天会明白的

TA的精华主题

TA的得分主题

发表于 2011-6-9 09:21 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
如果是自己用vb编写的DLL也可以用下面的方式饮用
  Public qqq As Object
Set qqq = CreateObject("DLL名称.DLL中与E表无缝连接的类名")   
这样引用不是太麻烦,缺点是控件必须是自己编写或者正规发布的控件

TA的精华主题

TA的得分主题

 楼主| 发表于 2011-6-10 00:04 | 显示全部楼层
原帖由 望江婷 于 2011-6-9 09:21 发表
如果是自己用vb编写的DLL也可以用下面的方式饮用
  Public qqq As Object
Set qqq = CreateObject("DLL名称.DLL中与E表无缝连接的类名")   
这样引用不是太麻烦,缺点是控件必须是自己编写或者正规发布的控件


这样的dll是不是需要先进行注册才能用这种方法? 如果需要注册的话还是比较麻烦的。

TA的精华主题

TA的得分主题

发表于 2012-5-7 16:02 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2012-5-25 18:38 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2013-10-5 21:29 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2013-10-5 21:44 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2013-10-5 22:06 | 显示全部楼层
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-12-31 01:56 , Processed in 0.029839 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表