8

我正在编写一个 VBA 函数,我希望它可以在同一文档中的其他 VBA 模块中公开使用,但是我不希望它作为 UDF(用户定义的函数)提供。

如果我使用公共访问修饰符,那么我的函数也可以作为 UDF 公式使用,可以从工作簿中的单元格调用。我不想要这个。

是否有访问修饰符或其他方式可以帮助我获得这种“仅限 VBA”的行为?

亲切的问候

4

6 回答 6

10

如果您Option Private Module在该函数出现的模块中使用,则该函数可以声明为Public并在您的 VBA 项目中的任何其他模块中使用,但其他应用程序或项目(包括 Excel 本身)将无法访问该函数。

于 2016-12-13T21:26:11.857 回答
5

如果在 Excel 中使用,这将返回 #VALUE 错误。

Function VBAOnly() As Variant

    If TypeName(Application.Caller) <> "Range" Then
        VBAOnly = 1 'or some other return value
    Else
        VBAOnly = CVErr(xlErrValue)
    End If

End Function
于 2012-06-22T16:51:15.957 回答
1

而不是写 a Function,写 a Sub,然后通过ByRef参数设置返回值。这样,您的函数将对 Excel 不可见(通过 Alt F8 或开发人员选项卡 > 宏除外),并且不会出现在 Excel 的智能感知中。

代替

Function Add(Num1 As Double, Num2 As Double)
    Add = Num1 + Num2
End Function

利用

Sub AddInvisible(ByRef Result As Double, Num1 As Double, Num2 As Double)
    Result = Num1 + Num2
End Sub

笔记

  1. ByRef不是绝对必要的(因为参数在 VBA 中默认通过引用),但它可以作为一个有用的提示,Result携带返回值。
  2. 您需要对代码进行必要的更改,例如:

    z = Add(x,y)

会成为

AddInvisible z,x,y

如下所示:

Sub DemoAddInvisible()

    Dim Num1 As Double
    Dim Num2 As Double
    Dim Result As Double 'Result initialises to 0

    Num1 = 1
    Num2 = 2
    AddInvisible Result, Num1, Num2

    MsgBox Result ' See that Result has become 3

End Sub

所有这些的缺点是新代码有点难以理解。

于 2018-06-29T11:27:27.193 回答
0

答案之间有点混乱,所以这里有一个更全面的解释:

从技术上讲...如果输入了确切的公式,则可以调用标准 VBA 模块中的所有函数。甚至公式在Private Functions里面Private Modules

例子

Option Private Module
Private Function hiddenEverythingExample() As String
    hiddenEverythingExample= "NOPE!!!"
End Function

如果单元格有,仍将返回一个值=hiddenEverythingExample()

在此处输入图像描述

但是,我相信 OP 的目标是避免让 itellisense 在 Excel 公式栏中填充这些函数。

我最常用的方法是为所有 VBA-Only 函数创建一个特定Option Private Module的模块并放入模块定义(函数上方的区域)。

在此处输入图像描述

这确保了该模块中的所有功能都不会出现在 itellisense 中,但仍然可以与 itellisense 一起被其他模块访问。

定义 asPrivate Function也可以完成此操作,但是该功能的范围仅限于该模块,这可能是也可能不是要求。

请注意,YowE3K 推断一个函数必须是Private Function AND Option Private Module,但只有一个OR是消除 itellisense 所必需的。

于 2019-07-22T01:19:18.403 回答
-1

使用Private修饰符应该只允许在函数所在的模块中执行。

于 2012-06-22T20:12:39.060 回答
-1

传递一个参数,该参数仅在给定“魔术*”值时才允许该函数运行。

示例 - 这将给出错误#NAME!,除非您知道密钥是什么:

Function VBAOnly(key As Long)

If key <> 12345 Then
    VBAOnly = CVErr(xlErrName)
    Exit Function
End If

VBAOnly = True

End Function
于 2012-06-22T13:30:27.650 回答