如何限制模块上的VBAfunction

我对VBA知之甚less,试图学习它。 我做了一个这样的VBA脚本:

Function doIt() Dim c As int... ............. ............. ............. c = callFunction ............... .............. End Function Function callFunction(byVal num As Int) .......... .......... .......... End Function 

正如你所看到的,callFunction是一个从主函数doIt调用的函数。 假设callFunction计算一个整数的平方。 整个VBA脚本保存在C驱动器的AddIns文件夹下的addIn模块中。 函数doIt在excel工作表中调用的时候效果很好。 但问题是,如果我从工作表中调用函数callFunction它也可以。 我怎样才能限制callFunction只有addIn模块,以便只有模块可以使用它,如果有人从工作表调用callFunction(2)它不会在工作表中2的平方?

注意:即使我将其设置为“ Private ,仍然可以从工作表中调用。

我不认为你可以阻止function的function,它允许访问它在VBA和Excel单元格。

但是,我有一些解决方法的想法,它允许您创build函数,它会在单元格中调用时给出不同的结果,例如可能返回一些信息(或标准错误),而不是计算结果。

这里是展示这个function的代码。 我认为这是非常清楚和可以理解的,所以你不需要额外的评论。

 Function callFunction(ByVal num As Integer) On Error Resume Next Dim tmpAdd tmpAdd = Application.ThisCell.Address If Err.Number = 0 Then If Left(Application.ThisCell.Formula, 13) = "=callFunction" Then 'called from excel cell, but this function is called! 'returns any type of standard function error callFunction = CVErr(XlCVError.xlErrNull) Exit Function End If End If 'called from VBA/IDE environment or from other function 'standard calculation callFunction = num ^ num End Function 

编辑灵感来自@DanielDusek答案(但有点不完整)我把丹尼尔和我的解决scheme混合成一个。 所以,新的和相当完整的代码:

 Function callFunction(ByVal num As Integer) If TypeName(Application.Caller) = "Range" Then If Left(Application.ThisCell.Formula, 13) = "=callFunction" Then 'called from excel cell, but this function is called! 'returns any type of standard function error callFunction = CVErr(XlCVError.xlErrNull) Exit Function End If End If 'called from VBA/IDE environment or from other function 'standard calculation callFunction = num ^ num End Function 

如果在任何调用的地方(间接使用)中使用任何VBA函数/子例程,两种解决scheme都会给出num ^ num结果。 在Excel单元格中调用时会给出Error值(直接使用)。

有了Application.Caller属性,你可以确定谁调用了你的函数,如果它是从工作表中调用的,你可以引发错误或者返回你想要的,但不同于你提供的计算结果。

 Private Function callFunction(ByVal num As Integer) As Variant If (TypeName(Application.Caller) = "Range") Then ' function was called from worksheet callFunction = "Invalid procedure call" ' or raise error Err.Raise Number:=5 Exit Function End If ' continue ... callFunction = num * num End Function 

关于Application.Caller: http : //msdn.microsoft.com/en-us/library/office/ff193687.aspx