use*_*245 2 excel vba excel-vba
我有一份电子表格,将分发给同事; 我希望尽可能使用户友好,所以为了运行宏,我有一个简单的按钮,可以自动完成所有内容.但是我不希望他们有权自己运行任何宏.
我已经成功地使用了这个
Option Private Module
Public Sub Run_Batch_Report()
'The actual script that works is here, cutting it to skip to the portion that won't work'
Call Misc_Doc
MsgBox ("Report finished.")
End Sub
Run Code Online (Sandbox Code Playgroud)
Public Sub Misc_Doc()所做的就是从另一个电子表格导入数据并对其进行格式化.
然后让命令按钮通过application.run调用模块
Private Sub CommandButton1_Click()
Application.Run "Batching_Module.Run_Batch_Report"
End Sub
Run Code Online (Sandbox Code Playgroud)
这样做那种工作的; 因为它似乎运行Run_Batch_Report子只是很好,但该子也调用同一模块中的其他子来完成作业.这些子程序将无法运行除非我在开发人员选项中解锁VB以进行查看和编辑.是否可以完整地运行子运行(包括在同一模块中调用其他子组件),或者我是否必须重构我的子组件以包含它所调用的所有其他子组件?
对不起,如果我随意措辞 - 我实际上正在开会,并在听老板的同时玩杂耍.
编辑:为了澄清,我已经锁定VB被查看.当我在脚本仍处于锁定状态时运行脚本时,它将不允许子调用该模块的其他部分.输入密码以解锁VB以供查看后,它就能正常工作.
假设"但我不想让他们有机会获得运行任何自己的宏的"代表"我不想宏在'宏’窗口中列出",你已经有了.
我无法重现你的"宏不会运行,除非项目解锁"问题,无论Application.Run是否涉及,不确定是什么.在任何情况下,您似乎都错误地认为密码保护您的项目会给它带来任何安全性.它没有.
VBA代码不安全.VBA项目密码保护实际上是一个笑话,它只会惹恼开发者(你!)并防止那些不知道如何处理VBE的无能用户,无论如何都要查看他们不理解的源代码 - 以及是否有人想要看到代码,相信我,他们会在几秒钟内完成.
如果有人可以打开主机文档,他们可以访问VBA代码.
用户可以运行宏,也可以不运行宏.如果用户可以单击按钮来调用某些VBA代码,则他们有权从任何地方调用该VBA代码.
将您的"隐藏"宏放在标准模块(.bas)中并Option Private Module指定:
Option Private Module
Option Explicit
Public Sub SomeHiddenMacro()
MsgBox "Hi"
End Sub
Run Code Online (Sandbox Code Playgroud)
然后你仍然可以通过输入宏的名称(它不会被列出,因为)来将宏分配给某个形状Option Private Module:

单击按钮,看到它的工作原理:

形状可以格式化为比任何ActiveX按钮更漂亮:

它不需要比这更复杂.
你是从VBA开始的,所以我认为你还没有玩过类模块.类模块的一个好处是它们的公共成员不能被调用为宏,因为类模块在运行时不存在 - 它们是类型,而不是模块.对于一个类型来表示任何东西,它需要被实例化 - 而宏运行器不会这样做.
所以把"worker"代码放在一个类模块中,比如说BatchReport:
Option Explicit
Public Sub Run()
'TODO: do your thing
End Sub
Run Code Online (Sandbox Code Playgroud)
现在在附加到按钮(或ActiveX按钮的Click处理程序)的宏中,您所做的就是使用New关键字创建该对象的实例,并调用其Run方法:
Option Private Module
Option Explicit
Public Sub RunBatchReport()
With New BatchReport
.Run
End With
End Sub
Run Code Online (Sandbox Code Playgroud)
在这里,我有一个With块保持对象引用.或者,您可以声明一个对象变量,并Set引用该类的New实例BatchReport:
Option Private Module
Option Explicit
Public Sub RunBatchReport()
Dim report As BatchReport
Set report = New BatchReport
report.Run
End Sub
Run Code Online (Sandbox Code Playgroud)