我有一份电子表格,将分发给同事;我希望尽可能使用户友好,所以为了运行宏,我有一个简单的按钮,可以自动完成所有内容。但我不希望他们有权自行运行任何宏。
我已经设法使用
做了一些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
Public Sub Misc_Doc()所做的就是从另一个电子表格导入数据并对其进行格式化。
然后让Command Button通过application.run
调用模块Private Sub CommandButton1_Click()
Application.Run "Batching_Module.Run_Batch_Report"
End Sub
做种的作品;因为它似乎运行Run_Batch_Report子只是很好,但该子也调用同一模块中的其他子来完成作业。这些子程序将无法运行除非我在开发人员选项中解锁VB以进行查看和编辑。是否有可能完整地运行子运行(包括调用同一模块中的其他子)或者我是否必须重构我的sub以仅包括它调用的所有其他子?
对不起,如果我随意措辞 - 我实际上正在开会,并在听老板的同时玩杂耍。
编辑:为了澄清,我已经锁定了VB被查看。当我在脚本仍处于锁定状态时运行该脚本时,它不会允许该子程序调用该模块的其他部分。输入密码以解锁VB以供查看后,它就能正常工作。
答案 0 :(得分:6)
假设"但我不希望他们有权自己运行任何宏"代表"我不希望宏被列在' Macros'窗口",你已经有了。
除非项目已解锁,否则我无法重现你的"宏不会运行#34;问题,无论有没有Application.Run
参与,都不确定这是什么。在任何情况下,您似乎都错误地认为密码保护您的项目会给它带来任何安全性。它没有。
VBA代码不安全。 VBA项目密码保护实际上是一个笑话,它只会惹恼开发者(你!)并防止无能为力的用户无论如何都不知道如何处理VBE,从查看他们无法理解的源代码 - 如果有人想看到代码,请相信我,他们会 - in a matter of seconds。
如果有人可以打开主机文档,他们可以访问VBA代码。
用户可以运行宏,也可以不运行宏。如果用户可以单击按钮来调用某些VBA代码,那么他们就有权从任何地方调用该VBA代码。
让你的"隐藏"指定了Option Private Module
的标准模块(.bas)中的宏:
Option Private Module
Option Explicit
Public Sub SomeHiddenMacro()
MsgBox "Hi"
End Sub
然后你仍然可以通过输入宏的名称来指定那个宏形状(它不会被列出,因为Option Private Module
) :
点击按钮,看看它是否正常工作:
可以将形状格式化为比任何ActiveX按钮更漂亮:
它不需要比这更复杂。
你从VBA开始,所以我认为你还没有玩过类模块。类模块的一个好处是它们的公共成员不能被调用为宏,因为类模块在运行时不存在 - 它们是类型 ,而不是模块。对于类型来表示任何内容,它需要实例化 - 并且宏运行器不会这样做。
所以把"工人"类模块中的代码,例如BatchReport
:
Option Explicit
Public Sub Run()
'TODO: do your thing
End Sub
现在,在附加到按钮的宏中(或在ActiveX按钮的Click
处理程序中),您所要做的就是使用{{1}创建该对象的实例}关键字,并调用其New
方法:
Run
这里我有一个Option Private Module
Option Explicit
Public Sub RunBatchReport()
With New BatchReport
.Run
End With
End Sub
块来保存对象引用。或者,您可以声明一个对象变量,并With
引用Set
类的New
实例:
BatchReport