ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[分享] “信任对VBA工程对象模型的访问”、“宏的安全等级”设置代码笔记

[复制链接]

TA的精华主题

TA的得分主题

发表于 2017-11-10 15:17 | 显示全部楼层 |阅读模式
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 microyip 于 2017-11-11 09:45 编辑

最近,因为其他设置需求,对“信任对VBA工程对象模型的访问”、“宏的安全等级”进行了研究学习,对前人提供的经验及当下版本Excel的差异进行总结,把心得记下以供参考。在编写过程中,多谢joforn(南宫飘雪)的指出错误之处,令我有机会查找其他资料去纠正错误,在此点名致谢。如有不当之处敬请指正。

     笔记目录
一、WindowsOffice版本号、位数
二、“宏的安全等级”设置
三、“信任对VBA工程对象模型的访问”设置
四、工程修复为默认
Z818U[L]5EJ9FWB848W]~[T.png

如果不想看下面的废话描述可以直接下载附件,附件里有部分描述。 “信任对VBA工程对象模型的访问”、“宏的安全等级”设置代码笔记.rar (71.06 KB, 下载次数: 189)

评分

5

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2017-11-10 15:18 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 microyip 于 2017-11-11 09:02 编辑

一、WindowsOffice版本号、位数
平时,有可能根据不同Windows的位数注册不同的DLL文件或OCX文件,所有有必要对Windows的位数进行获取。判断系统的位数需要通过GetNativeSystemInfo获取信息,从而获得Processor Architecture值,假如是6PROCESSOR_ARCHITECTURE_IA64)或者9PROCESSOR_ARCHITECTURE_AMD64),那么Windows系统就是64位。参考代码如下:(返回的是位数的数值)
  1. '--------------------------------------------------------------------------
  2. '****Windows位数判断***开始
  3. Private Type SYSTEM_INFO
  4.     wProcessorArchitecture As Integer
  5.     wReserved As Integer
  6.     dwPageSize As Long
  7.     lpMinimumApplicationAddress As Long
  8.     lpMaximumApplicationAddress As Long
  9.     dwActiveProcessorMask As Long
  10.     dwNumberOrfProcessors As Long
  11.     dwProcessorType As Long
  12.     dwAllocationGranularity As Long
  13.     wProcessorLevel As Integer
  14.     wProcessorRevision As Integer
  15. End Type

  16. Private Declare Sub GetNativeSystemInfo Lib "kernel32" (lpSystemInfo As SYSTEM_INFO)
  17. Private Declare Function GetCurrentProcess Lib "kernel32" () As Long

  18. Private Function Windows_Digit() As Integer
  19. 'Windows位数
  20.     Const PROCESSOR_ARCHITECTURE_AMD64 As Integer = 9
  21.     Const PROCESSOR_ARCHITECTURE_IA64 As Integer = 6
  22.     Dim windowsInfo As SYSTEM_INFO
  23.    
  24.     GetNativeSystemInfo windowsInfo
  25.     Windows_Digit = (1 - (si.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64 Or si.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_IA64) * 1) * 32
  26. End Function
  27. '****Windows位数判断***结束
  28. '--------------------------------------------------------------------------
复制代码


由于Windows版本太多,在VBA编程方面用得也少,所以暂没做具体研究。有兴趣可以到网上找找资料。
Office不同版本引起了很多VBA编程语句的差异,故此判断不同版本的Office作出对应应对措施是很有必要。例如:SQL语句、日期控件应用等。参考代码如下:(返回的是版本的文字描述)
  1. '--------------------------------------------------------------------------
  2. '**** Office的版本判断***开始
  3. Private Function Office_Version() As String
  4. 'Office版本
  5.    Dim sVer As String
  6.    
  7.    sVer = Application.Version
  8.    If sVer = "8.0" Then
  9.        Office_Version = "2003版"
  10.    ElseIf sVer = "12.0" Then
  11.        Office_Version = "2007版"
  12.    ElseIf sVer = "14.0" Then
  13.        Office_Version = "2010版"
  14.    ElseIf sVer = "15.0" Then
  15.        Office_Version = "2013版"
  16.    ElseIf sVer = "16.0" Then
  17.        Office_Version = "2016版"
  18.    Else
  19.        Office_Version = "未知或唯有记录的版本"
  20.    End If
  21. End Function
  22. '**** Office的版本判断***结束
  23. '--------------------------------------------------------------------------
复制代码

Office不同位数对我个人编程来说影响暂时不是很大,也用不多,但语句比较简单,所以也记录下来了。注意判断语句里必须含有#号。参考代码如下:(返回位数的数值)
  1. '--------------------------------------------------------------------------
  2. '**** Office位数判断***开始
  3. Private Function Office_Digit() As Integer
  4. 'Office的位数
  5.    #If Win64 Then
  6.        Office_Digit = 64
  7.    #Else
  8.        Office_Digit = 32
  9.    #End If
  10. End Function
  11. '**** Office位数判断***结束
  12. '--------------------------------------------------------------------------
复制代码


TA的精华主题

TA的得分主题

 楼主| 发表于 2017-11-10 15:19 | 显示全部楼层
本帖最后由 microyip 于 2017-11-11 09:46 编辑

二、“宏的安全等级”设置

历史以来,很多朋友都会遇到给客户(或朋友或公司内部)写了VBA,但客户告知操作不了,原因很简单,是因为没有启用宏,都是因为Office默认宏的安全等级为高引起的,但教客户操作修改,也是一件比较麻烦的事情。网上有很多教程,总结起来基本上就是对注册表进行修改。网上资料中,基本上是基于Excel2003进行编写的,到了Excel2007以上可能就发现不好使了。原因是,Excel2007以上使用的不是安全等级的概念,而是警告方式。
Excel2003的安全等级的注册表在
HKEY_CURRENT_USER\Software\Microsoft\Office\8.0\Excel\Security\Level
“Level”项的值1,2,3分别表示宏的安全级别为低、中、高。

Excel2007的安全等级的注册表在
HKEY_CURRENT_USER\Software\Microsoft\Office\具体版本号\Excel\Security\ VBAWarnings
“VBAWarnings”项的值1,启用所有宏;2,禁用所有宏,并发出通知;3,禁用无数字签署的所有宏;4,禁用所有宏,并且不通知
参考代码如下:(返回安全等级的数值)
参考资料:http://blog.sina.com.cn/s/blog_715070f20100rtcw.html,用VBA宏自动改变Excel宏安全级别设置
  1. '--------------------------------------------------------------------------
  2. '*****检查宏的安全等级***开始
  3. Private Function Check_Marco_SecurityLevel() As Integer
  4. '检查宏的安全等级
  5.     Dim vRegVal As Variant

  6.     On Error Resume Next
  7.     With CreateObject("WScript.Shell")
  8.         If Val(Application.Version) < 12 Then 'Excel2003版以下
  9.             vRegVal = "HKEY_CURRENT_USER\Software\Microsoft\Office" & Application.Version & "\Excel\Security\Level"
  10.         Else 'Excel2007版以上
  11.             vRegVal = "HKEY_CURRENT_USER\Software\Microsoft\Office" & Application.Version & "\Excel\Security\VBAWarnings"
  12.         End If
  13.         vRegVal = .RegRead(vRegVal)
  14.     End With
  15.     If vRegVal = "" Then Debug.Print  '键位不存在
  16.     Check_Marco_SecurityLevel = Val(vRegVal)
  17. End Function
  18. '*****检查宏的安全等级***结束
  19. '--------------------------------------------------------------------------
复制代码

既然知道了注册表的设置位置,对其进行修改成安全等级为低即可,这样无需每次打开带宏的Excel时都会有提示,甚至不能使用宏了。注意的是,由低改高,肯定是没问题的,但由高改低,在运行本代码前,必须在提示启用宏的时候选择启用。参考代码如下:(参数nLevel是提供给有不同需求的开发者进行方便使用的)
  1. '--------------------------------------------------------------------------
  2. '*****设置宏的安全等级***开始
  3. Private Sub Set_Marco_SecurityLevel(ByVal nLevel As Integer)
  4. '设置宏的安全等级
  5.     With CreateObject("WScript.Shell")
  6.         If Val(Application.Version) < 12 Then
  7.             If nLevel = 0 Or nLevel > 3 Then nLevel = 3
  8.             .RegWrite "HKEY_CURRENT_USER\Software\Microsoft\Office" & Application.Version & "\Excel\Security\Level", nLevel, "REG_DWORD"
  9.         '"Level"项的值1,2,3分别表示宏的安全级别为低、中、高。
  10.         Else
  11.             If nLevel = 0 Or nLevel > 3 Then nLevel = 2
  12.             .RegWrite "HKEY_CURRENT_USER\Software\Microsoft\Office" & Application.Version & "\Excel\Security\VBAWarnings", nLevel, "REG_DWORD"
  13.         End If
  14.     End With
  15.     '"VBAWarnings"项的值1,启用所有宏;2,禁用所有宏,并发出通知;3,禁用无数字签署的所有宏;4,禁用所有宏,并且不通知
  16. End Sub
  17. '*****设置宏的安全等级***结束
  18. '--------------------------------------------------------------------------
复制代码

如果觉得操作麻烦,也可以改写一个注册表文件,直接运行注册表文件进行修改。

TA的精华主题

TA的得分主题

 楼主| 发表于 2017-11-10 15:21 | 显示全部楼层
本帖最后由 microyip 于 2017-11-11 09:48 编辑

三、“信任对VBA工程对象模型的访问”设置
平时编写动态控件时时常发现明明写得内容没错,但又不能执行到结果,而网上资料显示都是这么写,为何?主要是因为Office默认不允许对VBA工程对象进行直接处理访问,也就是“信任对VBA工程对象模型的访问”没开启。而控制这个是否开启,也是通过注册表进行控制的。
HKEY_CURRENT_USER\Software\Microsoft\Office\版本号\Excel\Security\AccessVBOM
AccessVBOM”项的值为1代表开启,0表示关闭“信任对VBA工程对象模型的访问”
检查“信任对VBA工程对象模型的访问”开启状态的参考代码如下:(返回状态的逻辑值)
参考资料:http://club.excelhome.net/thread-883006-1-1.html,用VBA代码开启“信任对VBA工程对象模型的访问”的方法
  1. '--------------------------------------------------------------------------
  2. '*****检查“信任对VBA工程对象模型的访问”状态***开始
  3. Private Function Check_AccessVBOM() As Boolean
  4. '检查"信任对VBA工程对象模型的访问"是否已开启
  5.     Dim vRegVal As Variant

  6.     On Error Resume Next
  7.     vRegVal = CreateObject("WScript.Shell").RegRead("HKEY_CURRENT_USER\Software\Microsoft\Office" & Application.Version & "\Excel\Security\AccessVBOM")
  8.     If vRegVal = "1" Then
  9.         Check_AccessVBOM = True
  10.     Else
  11.         If vRegVal = "" Then Debug.Print  '键位不存在
  12.         Check_AccessVBOM = False
  13.     End If
  14. End Function
  15. '*****检查“信任对VBA工程对象模型的访问”状态***结束
  16. '--------------------------------------------------------------------------
复制代码

既然怎么读注册表,就直接写注册表来处理开启模式咯!参考代码如下:
  1. '--------------------------------------------------------------------------
  2. '*****设置"信任对VBA工程对象模型的访问"***开始
  3. Private Sub Open_AccessVBOM(ByVal nStatus As Integer)
  4. '开启"信任对VBA工程对象模型的访问"
  5.     If nStatus < 0 Or nStatus > 1 Then nStatus = 1
  6.     CreateObject("WScript.Shell").RegWrite "HKEY_CURRENT_USER\Software\Microsoft\Office" & Application.Version & "\Excel\Security\AccessVBOM", nStatus, "REG_DWORD"
  7.     '"AccessVBOM"项的值为1代表开启,0表示关闭"信任对VBA工程对象模型的访问"
  8. End Sub
  9. '*****设置"信任对VBA工程对象模型的访问"***结束
  10. '--------------------------------------------------------------------------
复制代码


四、工程修复为默认
有了上面的基础,恢复到系统默认安装状态,应该不是什么难事了,注意一点的是,Excel2007以上版本虽然不是凭Level来判断等级,但也存在该键位,默认值为1;假如存在HKEY_LOCAL_MACHINE对应的键位,那么就会变灰,假如想不允许客户改动,可以考虑建立这个键位。参考代码如下:
  1. '--------------------------------------------------------------------------
  2. '****工程修复***开始
  3. Sub VBProject_Repair()
  4.     On Error Resume Next
  5.     With CreateObject("WSCRIPT.SHELL")
  6.         .REGDELETE "HKEY_LOCAL_MACHINE\Software\Microsoft\Office" & Application.Version & "\Excel\Security" '直接把注册表里HKEY_LOCAL_MACHINE的安全键位全部删除了,这个是令变灰的罪魁祸首
  7.         .RegWrite "HKEY_CURRENT_USER\Software\Microsoft\Office" & Application.Version & "\Excel\Security\AccessVBOM", 0, "REG_DWORD"
  8.         If Val(Application.Version) < 12 Then
  9.             .RegWrite "HKEY_CURRENT_USER\Software\Microsoft\Office" & Application.Version & "\Excel\Security\Level", 3, "REG_DWORD"
  10.         Else
  11.             .RegWrite "HKEY_CURRENT_USER\Software\Microsoft\Office" & Application.Version & "\Excel\Security\Level", 1, "REG_DWORD"
  12.             .RegWrite "HKEY_CURRENT_USER\Software\Microsoft\Office" & Application.Version & "\Excel\Security\VBAWarnings", 3, "REG_DWORD"
  13.         End If
  14.     End With
  15. End Sub
  16. '****工程修复***结束
  17. '--------------------------------------------------------------------------
复制代码

TA的精华主题

TA的得分主题

发表于 2017-11-10 15:27 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2017-11-10 15:39 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
分享是一种美德,点赞是一种道德。前排支持。。

TA的精华主题

TA的得分主题

 楼主| 发表于 2017-11-10 15:41 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
fxl447098457 发表于 2017-11-10 15:39
分享是一种美德,点赞是一种道德。前排支持。。

多谢兄弟你的支持

TA的精华主题

TA的得分主题

发表于 2017-11-10 17:32 来自手机 | 显示全部楼层
microyip 发表于 2017-11-10 15:21
三、“信任对VBA工程对象模型的访问”设置平时编写动态控件时时常发现明明写得内容没错,但又不能执行到结 ...

三、“信任对VBA工程对象模型的访问”设置

对于我这office2010不起作用!没得用,哈哈!

TA的精华主题

TA的得分主题

 楼主| 发表于 2017-11-10 17:37 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
duquancai 发表于 2017-11-10 17:32
三、“信任对VBA工程对象模型的访问”设置

对于我这office2010不起作用!没得用,哈哈!

你的office2010是你开发的?怎么会不起作用?

TA的精华主题

TA的得分主题

发表于 2017-11-10 17:44 来自手机 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
microyip 发表于 2017-11-10 17:37
你的office2010是你开发的?怎么会不起作用?

你不信拉倒,就是不起作用!哈哈
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

关闭

最新热点上一条 /1 下一条

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

GMT+8, 2024-4-25 09:21 , Processed in 0.049135 second(s), 15 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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