从Excel中的用户隐藏macros,但仍然通过button调用?

我有一个电子表格,将分发给同事; 我想尽可能使用户友好,所以为了运行macros我有一个简单的button,自动化他们的一切。 但我不希望他们有权自己运行任何macros。

我已经设法使用一些这样做

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()所做的就是从另一个电子表格导入数据并对其进行格式化。

然后有一个命令button通过application.run调用模块

 Private Sub CommandButton1_Click() Application.Run "Batching_Module.Run_Batch_Report" End Sub 

做这种工作; 因为在它似乎运行Run_Batch_Report子就好了,但该子也调用同一模块内的其他潜艇完成工作。 这些潜艇将无法运行,除非我解锁开发人员的VB查看和编辑选项。 是否有可能让子运行的完整(包括调用同一模块内的其他潜艇),还是我必须重组我的潜艇,以包括所有其他潜艇调用以及?

对不起,如果我这样杂乱地说 – 我实际上是在开会的时候,一边听着老板的话一边玩杂耍。

编辑:澄清,我已经lockingVB被查看。 当我在脚本仍然locking的情况下运行脚本时,它不会允许该子程序调用模块的其他部分。 一旦我的密码input解锁VB查看,它的作品。

假设“但我不希望他们有权自己运行任何macros”代表“我不希望macros被列在”macros“窗口中”,那么您已经拥有了这些macros。

我不能重现你的“macros不运行,除非项目被解锁”的问题,有或没有Application.Run卷入,不知道这是关于什么。 无论如何,你似乎有一种错误的印象,即密码保护你的项目给了它任何的安全。 它不。

VBA代码不安全 。 VBA项目的密码保护实际上是一个笑话,它只会惹恼开发者(你!),并防止不知情的用户,不知道怎么用VBE,从查看他们不会理解的源代码 – 如果有人想要看代码,相信我,他们会 – 在几秒钟内 。

如果有人可以打开主机文档,他们可以获得VBA代码。

用户可以运行macros,或者他们不能。 如果用户可以点击一个button来调用一些VBA代码,那么他们有权从任何地方调用该VBA代码。

使用Option Private Module指定的标准模块(.bas)中有“隐藏的”macros:

 Option Private Module Option Explicit Public Sub SomeHiddenMacro() MsgBox "Hi" End Sub 

然后,你仍然可以通过键入macros的名称(这不会被列出,因为Option Private Module ),将该macros分配给某种形状

Excel的“分配宏”对话框

点击button,看看它的工作:

消息框显示出来

形状可以格式化看起来比任何ActiveXbutton更漂亮:

“运行批处理报告”按钮,带渐变阴影和3D斜角

这不需要比这更复杂。


优雅的解决scheme

你从VBA开始,所以我认为你没有太多的玩类模块。 关于类模块的好处之一是它们的公共成员不能被调用为macros,因为类模块在运行时不存在 – 它们是types ,而不是模块 。 对于一个types意味着什么,它需要被实例化 – 而macros观运动员不这样做。

所以把“worker”代码放到一个类模块中,比如说BatchReport

 Option Explicit Public Sub Run() 'TODO: do your thing End Sub 

现在,在附加到button(或ActiveXbutton的Click处理程序)中的macros中,只需使用New关键字创build该对象的实例,然后调用其Run方法:

 Option Private Module Option Explicit Public Sub RunBatchReport() With New BatchReport .Run End With End Sub 

在这里,我有一个With块保存对象引用。 或者,您可以声明一个对象variables,并将其引用SetBatchReport类的一个New实例:

 Option Private Module Option Explicit Public Sub RunBatchReport() Dim report As BatchReport Set report = New BatchReport report.Run End Sub