用VBA代码打开xls文件时,判断被打开的xls文件是否含VBA代码并禁止其运行

  • 说明
  • 需求背景
  • 禁止被打开文件中的vba运行
  • 判断打开的文件中是否含vba代码
    • 先取得打开的文件中有多少个components
    • 利用取得的对象数量, 取得每个对象中的代码行数
    • 需要注意的几个问题:
  • 附完整代码
  • 结语

说明

本文为原创,引用请注明出处,谢谢!

需求背景

公司在迁移质控体统的文件控件系统,新文控系统不支持老版的office文件(xls, doc, ppt等), 需要将其升版成新的xlsx, docx, pptx格式。
显然,用vba代码处理是最便捷的。只要打开原文件,另存为新格式,再删除旧文件就行了。
但是在执行时,发现一个问题,就是老版的office文件,含不含vba代码(宏macro),其文件后缀是一样的。有些文件的vba代码中文件打开、文件保存会触一些功能。因此需要禁止被打开文件中的vba被触发运行。另一方面,因为新版office中带有vba代码的文件,其后缀是不一样的(xlsm, docm, pptm), 所以需要根据原文件中是否含vba代码来决定升级成相应类型的文件。

禁止被打开文件中的vba运行

这个相对简单,只需要设置application对象的AutomationSecurity 属性就可以了,Excel, Word, PowerPoint都一样。
这个属性有3个选项:

  • msoAutomationSecurityLow
  • msoAutomationSecurityByUI
  • msoAutomationSecurityForceDisable

实际上这是预定义的常量,从上到下分别是1,2,3。
在打开文件前,将属性设为 msoAutomationSecurityForceDisable 即可.
当然,考究一点,可以先保存当前的设置,然后在最后再恢复。

处理之前:

intPreviousSetting = Application.AutomationSecurity
Application.AutomationSecurity = msoAutomationSecurityForceDisable 'Excel
objWordApp.AutomationSecurity = msoAutomationSecurityForceDisable 'Word
objPowerPointApp.AutomationSecurity = msoAutomationSecurityForceDisable 'PowerPoint```

处理完毕:

Application.AutomationSecurity = intPreviousSetting

判断打开的文件中是否含vba代码

这个略曲折。需要利用office 文件对象中VBProject对象下的VBComponents对象综合处理。

  • 先取得打开的文件中有多少个components

    这里的 components, 就是VBE编辑器中左侧对象列表中的对象。如下图,test.xlsx 文件有2个对象,分别是"ThisWorkbook"和"Sheet1", 另一个xlsm文件有3个对象,多了一个"Modules1"

    这个数量可以用count属性获取:

      intObjects = objExcelFile.VBProject.VBComponents.Count`
    
  • 利用取得的对象数量, 取得每个对象中的代码行数

    在VBComponents对象下, 有个Item对象,每个item就对应一个具体的Component对象。Component对象下有个CodeModule对象,可以利用它的CountOfLines属性,来取得该模块中有多少行代码。如果代码行数不为0,则说明文件中有VBA代码。

    'Has vba code or not
    blNoMacro = False
    For intTemp = 1 To objExcelFile.VBProject.VBComponents.Count   'How many objectsIf objExcelFile.VBProject.VBComponents.Item(intTemp).CodeModule.CountOfLines > 0 ThenblNoMacro = TrueExit ForEnd IfNext
    'save file
    objExcelFile.SaveAs IIf(blNoMacro, strPath & "\" & strFileName & ".xlsm", strPath & "\" & strFileName & ".xlsx")
    
  • 需要注意的几个问题:

  1. 对于Excel 文件,即使完全没有VBA代码,也会有2个components:Workbook" 和"Sheet1"; 对word, 会有1个:“ThisDocument”; 对于PowerPoint, 如果没有VBA代码,则component个数为0
  2. 对于模块中的空行, CountOfLines 也会统计在内。极端情况下,用户只是输入了些回车,并没有实质性代码,用这个方法也会被判定为含宏。如果确实要求非常精确,可以用类似的手段,取得每一行代码,判断是否为空。但这样会非常耗时,对于此项目并不需要到这么精确,所以就只做简单判断了。
  3. 使用这个方法的,需要在Word/Excel/PowerPoint中开启"Trust Access to the VBA project object model". 开启的方法与允许运行宏一样,都在信任中心那里设置

    否则的话,会收到如下提示:

附完整代码

Option Explicit
Sub test()'ExcelDim objExcelFile As Workbook'WordDim objWordApp As New Word.Application, objWordDoc As Word.Document'PowerPointDim objPptApp As New PowerPoint.Application, objPptFile As PowerPoint.PresentationDim strPath As String, strFileName As String, strNewFileName As String, intTemp As Integer, blNoMacro As BooleanobjWordApp.Visible = TrueobjPptApp.Visible = msoCTrue'Disable vba runningApplication.AutomationSecurity = msoAutomationSecurityForceDisable 'msoAutomationSecurityLow  '=msoAutomationSecurityByUI =  'msoAutomationSecurityForceDisableobjWordApp.AutomationSecurity = msoAutomationSecurityByUI ' = msoAutomationSecurityForceDisableobjPptApp.AutomationSecurity = msoAutomationSecurityForceDisable'open excel filestrPath = "C:\temp"strFileName = "test"Set objExcelFile = Application.Workbooks.Open(strPath & "\" & strFileName & ".xls")'Has vba code or notblNoMacro = FalseFor intTemp = 1 To objExcelFile.VBProject.VBComponents.Count   'How many objectsIf objExcelFile.VBProject.VBComponents.Item(intTemp).CodeModule.CountOfLines > 0 ThenblNoMacro = TrueExit ForEnd IfNext'Save fileobjExcelFile.SaveAs IIf(blNoMacro, strPath & "\" & strFileName & ".xlsm", strPath & "\" & strFileName & ".xlsx")'......objExcelFile.Close'open word fileSet objWordDoc = objWordApp.Documents.Open(strPath & "\" & strFileName & ".doc")'Has vba code or notblNoMacro = FalseFor intTemp = 1 To objWordDoc.VBProject.VBComponents.Count   'How many objectsIf objWordDoc.VBProject.VBComponents.Item(intTemp).CodeModule.CountOfLines > 1 ThenblNoMacro = TrueExit ForEnd IfNext'save fileobjWordDoc.SaveAs2 IIf(blNoMacro, strPath & "\" & strFileName & ".docm", strPath & "\" & strFileName & ".docx")objWordDoc.Close'open ppt fileSet objPptFile = objPptApp.Presentations.Open(strPath & "\" & strFileName & ".ppt")'Has vba code or notblNoMacro = FalseFor intTemp = 1 To objPptFile.VBProject.VBComponents.Count   'How many objectsIf objPptFile.VBProject.VBComponents.Item(intTemp).CodeModule.CountOfLines > 0 ThenblNoMacro = TrueExit ForEnd IfNext'save fileobjPptFile.SaveAs IIf(blNoMacro, strPath & "\" & strFileName & ".pptm", strPath & "\" & strFileName & ".pptx")objPptFile.CloseEXIT_SUB:Set objExcelFile = NothingSet objWordApp = NothingSet objWordDoc = NothingSet objPptApp = NothingSet objPptFile = NothingEnd Sub

结语

VBA目前已经势微,准确地说,可能从来没有火过。但是事实上,这真的是一门极其有用的语言。如果能够掌握,在日常工作中会带来巨大的便利。相信你能看到这里,说明你正在使用它并遇到了困难要解决,希望此文能帮上。

用VBA代码打开xls文件时,判断被打开的xls文件是否含VBA代码并禁止其运行相关推荐

  1. notepadd++打开文件时保留上次打开文件的解决办法

    用notepadd++打开文件时,总是打开上一次打开的文件,弄得我很烦 自从用了度娘,心情顿时好了,解决办法是这样的:

  2. python创建文件夹 覆盖_Python 创建新文件时避免覆盖已有的同名文件的解决方法...

    思路:创建文件时,先检查是否有同名文件(使用os.path.isfile),如果有,则在文件名后加上编号n来创建. 关键点: 1. 使用os.path.isfile判断文件是否存在 2. 使用递归函数 ...

  3. ae渲染出现错误是什么问题_After Effects错误:写入文件.....时发生渲染错误.输出模块失败.文件可能已损坏。(-1610153464)...

    我来回答一下,你在电脑里安装了其他下载的aex文件格式的插件,你只要把你这些插件删除掉,问题就可以解决,(安装插件不正确,或者有相同的插件也出现提示框)其实,这个提示不重要,你正常开启AE以后,正常使 ...

  4. 服务器上文件一直被打开吗,Python: 如何判断远程服务器上Excel文件是否被人打开...

    最近工作中需要去判断远程服务器上的某个Excel文件是否被打开,如果被人打开,则等待,如果没人打开使用,则去填写数据进Excel文件. 开始想的很简单,和其他语言一样,比如C#,打开文件,如果报错说明 ...

  5. 安装文件时显示不能打开要写入的文件该如何解决?

    前情概要 原先使用这台电脑的同事把电脑c盘下的用户名改成自己的名字,本人多次使用网上的教程没能更改成功,于是被迫将就用着,在这期间也下载了一些软件.不死心的我后面又琢磨着改掉这个名字(毕竟谁也不想一直 ...

  6. catia保存成stp文件时部件丢失_在线教学文件同步神器——坚果云

    教师在线办公期间,有教研组.备课组资源共享与协同办公的需求.在此推荐一款应用--坚果云[1],可以实现市面上绝大部分设备间的文件共享和同步,极高地提高在文件管理方面的效率. 推荐指数:★★★★★ ↓教 ...

  7. Java下载文件时文件名出现乱码(但文件内容正常)

    今天写文件下载时,发现以前忽略的问题,写个小记录 我们一般使用中文操作系统,所以要求的 文件名编码最好是utf-8,国际化一点 但是,似乎实际上不是这样 1. String fileName=new ...

  8. 下载文件时,浏览器是怎么知道文件名称的?

    当你在浏览器里下载一个文件时,浏览器是如何知道你所下载的文件的名称的呢?这或许是你从未考虑过的事情,但浏览器必须知道,否则,它就不知道如何保存文件. 1. Content-Disposition 首部 ...

  9. 打开Windows Powershell时出现 :. : 无法加载文件C:\user\...\profile.ps1。未对文件profile.ps1进行数字签名。无法在当前系统上运行该脚本 的解决办法

    想使用Windows Powershell命令时,打开后出现如下报错: . : 无法加载文件 C:\Users\arxc\Documents\WindowsPowerShell\profile.ps1 ...

  10. 打开PDF文件时,出现“打开本文档时发生错误。无法找到本文件。”解决办法,亲自尝试成功

    解决办法 1.拖动该文件,硬生生拖到桌面上,然后打开对应的桌面该文件,如果桌面该文件能打开,而原来文件夹的还是不能打开,进行第二步 注:有人尝试删除之前的文件,然后打开桌面文件,另存为原来位置之后,还 ...

最新文章

  1. linux基础(6)-shell编程
  2. 天草脱壳视频学习笔记
  3. 配置SMB共享 、 配置NFS共享
  4. C#异常处理机制初步
  5. (计算机组成原理)第二章数据的表示和运算-第二节1:定点数的表示(原码、反码、补码和移码)
  6. 不要在给自己不学习找借口了,否则…
  7. javascript 获取图片原始尺寸
  8. cf914F. Substrings in a String(bitset 字符串匹配)
  9. .net中 参数out,ref,params的区别
  10. y7000p屏幕亮度低_联想拯救者y7000p怎么样 评测结果揭晓屏幕优点
  11. python数据透视表对各列统计_python pandas数据分析基础入门2——(数据格式转换、排序、统计、数据透视表)...
  12. 《金狐系统维护盘》五周年纪念版【简洁易用,强大实用】
  13. Android开发 点滴
  14. 【攻防世界7-12题】题解和解题心得
  15. HFSS学习笔记—12.矩形微带贴片天线
  16. NTFS的忠实秘书—USN日志
  17. 怎么彻底关闭广告弹窗?
  18. 23.文件特殊权限之SUID权限、SGID权限、Sticky BIT权限和ACL权限
  19. 我也曾对架构师的力量一无所知
  20. python之LIST、Tuple、Dictionary用法总结

热门文章

  1. 基于C#的学生综合教务管理系统
  2. python3爬虫教程
  3. 优酷投屏显示无法连接服务器,无线投屏器为什么会连接不成功呢?
  4. matlab闰年问题,MATLAB中文上机作业.pdf
  5. 免费PDF阅读器都是坑?这些开源神器我可是恨不得所有人都知道
  6. 向日葵深度linux,完美使用向日葵远程软件
  7. java简单排序之选择排序(从小到大)
  8. 如何打开VS的命令行界面
  9. gp数据库 创建数据库 创建表 分区
  10. linux系统服务器如何登陆,linux系统如何登录到远程linux服务器