Excel 如何仅在模块上限制VBA功能
我对VBA知之甚少,并试图学习它。我制作了一个VBA脚本,如下所示:Excel 如何仅在模块上限制VBA功能,excel,vba,Excel,Vba,我对VBA知之甚少,并试图学习它。我制作了一个VBA脚本,如下所示: Function doIt() Dim c As int... ............. ............. ............. c = callFunction ............... .............. End Function Function callFunction(byVal num As Int) .......... .......... .......... End Fu
Function doIt()
Dim c As int...
.............
.............
.............
c = callFunction
...............
..............
End Function
Function callFunction(byVal num As Int)
..........
..........
..........
End Function
正如您所看到的,callFunction是一个从主函数doIt调用的函数。假设callFunction计算一个整数的平方。整个VBA脚本保存在C驱动器中相应加载项文件夹下的加载项模块中。当从excel工作表调用时,函数doIt工作正常。但问题是,如果我从工作表调用函数callFunction,它也可以工作。如何将callFunction仅限于addIn模块,以便只有模块可以使用它,并且如果有人从工作表调用callFunction(2),它将不会在工作表中给出2的平方
注意:即使我将其设置为私有,它仍然可以从工作表中调用。我认为您不能阻止允许在VBA和Excel单元格中访问它的函数功能 不过,我有一些变通方法,允许您创建函数,当在单元格中调用时,该函数会给出不同的结果,例如,可以返回一些信息(或标准错误),而不是计算结果 下面是展示此功能的代码。我认为这是非常清楚和可以理解的,所以你不需要额外的评论
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答案(但有点不完整)的启发,我将丹尼尔和我的解决方案混合在一起。因此,新的、相当完整的代码:
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函数/子例程中使用,无论调用的位置(间接使用),这两种解决方案都将给出
num^num
结果。在Excel单元格中调用时,它将给出错误
值(直接使用) 使用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
关于应用程序。来电者:我认为您的解决方案不完整。如果在另一个函数(B)中使用函数(A),然后在工作表单元格中调用函数(B),它将返回
无效过程
,而不是(B)结果。感谢KazJaw提供的解决方案。它运行良好。但我感到惊讶的是,为什么即使将函数声明为私有函数,也可以从模块外部调用它。那么,在VBA中,私有、友元函数类型的用途/作用是什么?这将是我的荣幸,作为一名新手,如果你向我解释函数类型的用法,将有助于学习私有、友元函数类型。你不能使用friend
关键字,因为根据vba帮助,它是…“仅在类模块中使用”。然而,private
关键字应该起作用。如果我用Private
启动任何函数,我无法从其他模块中function
的任何sub
调用它。但在这种情况下,Private关键字不起作用。我声明了callFunction private,但它也可以从工作表中调用,并且返回了正确的值。您可以从工作表中调用private Function
。在这种情况下,Private
关键字的唯一好处是,在单元格中输入函数名称时,不会列出或建议函数。