将用户定义的函数(UDF)添加到Excel中的内置类别

时间:2012-06-21 19:35:52

标签: excel excel-vba vba

当我向Excel中的标准代码模块添加公共函数时,它会显示在“全部”类别“用户定义”的“插入函数”向导中。

有没有办法:

  1. 保持函数公用(因此可以从其他模块调用)但是将其从Excel函数向导中隐藏?
  2. 使该功能显示在内置类别中(例如,“财务”,“统计”,“逻辑”)?
  3. 创建我自己的类别(例如,“荒谬”)并让我的功能出现在那里?
  4. 我只需要能够使上述案例中的一个起作用,但我很想知道每个案例是否可行。

    注意:如果社区认为更合适,我会很乐意将此分为三个单独的问题。我想可能只有一个答案,三个问题之间只有轻微的差异。

4 个答案:

答案 0 :(得分:4)

  

有没有办法[...]保持函数公开(所以可以从其他模块调用)但是将它从Excel函数向导中隐藏?

Option Private Module放在模块的顶部。完成。

http://msdn.microsoft.com/en-us/library/aa266185(v=vs.60).aspx

答案 1 :(得分:2)

Application.MacroOptions是您之后的命令

此示例将名为 TestMacro 的用户定义宏添加到名为我的自定义类别的自定义类别中。

Function TestMacro()
    MsgBox ActiveWorkbook.Name
End Function

Sub AddUDFToCustomCategory()
    Application.MacroOptions Macro:="TestMacro", Category:="My Custom Category"
End Sub

答案 2 :(得分:2)

我在a question about VBA Date functions的foonote中回答了这个问题:这是我在那里写的内容的直接复制和粘贴,使用VB'Attribute'语句创建函数描述和函数向导类别ID

  

针对仍在使用Excel 2003的人员的提示:

     

如果您(或您的用户)要从工作表中调用IsDateEx(),   使用a将这两行放在函数头的正下方   导出的.bas文件中的文本编辑器并重新导入该文件,因为   VB属性很有用,但代码无法访问它们   Excel的VBA IDE中的编辑器:

     

Attribute IsDateEx.VB_Description = "Returns TRUE if TestDate is a date, and is within ± 20 years of the system date.\r\nChange the defaulte default ± 20 years boundaries by setting values for LimitPastDays and LimitFutureDays\r\nIf you are checking an array of dates, ALL the values will be tested: set FirstColumnOnly TRUE to check the leftmost column only."

     

这就是一条线:看   out用于浏览器插入的换行符! ......这条线,哪条   将isDateEX放入“信息”类别的函数向导中,   与ISNUMBER(),ISERR(),ISTEXT()等一起:

     

Attribute IsDateEx.VB_ProcData.VB_Invoke_Func = "w\n9"

     

如果您希望在日期和时间范围内看到它,请使用“w \ n2”。时间功能:   在“使用过的定义”功能的泥潭中击败了地狱   来自您自己的代码,以及由之开发的所有第三方加载项   那些做不到足够帮助偶尔用户的人。

     

我不知道这是否仍适用于Office 2010。

......这就是我所能提出的建议。 VBA开发人员无法真正访问函数向导类别和关联的函数(和参数!)描述符。其中一些可供老派VB编码人员使用,他们可以在IDE中访问VB.Attribute语句;你可以通过一些文本文件操作将它分类到你的代码中。

答案 3 :(得分:2)

公共功能仅对Excel可见,公式栏中它们位于"常规" * .bas模块。属于类的公共函数对公式栏不可见。如果将这一点与我们可以模拟静态类的事实相加,则可以有效地隐藏函数。

如果您创建一个类模块然后将其导出,您将在标题中找到Attribute VB_PredeclaredId = False。将此设置为true会创建一个类的默认全局实例,该实例可以像更现代的语言中的静态类一样使用。

例如,创建一个名为Math的新类模块,并将此函数添加到其中。

Public Function Add(a As Integer, b As Integer) As Long
    Add = a + b
End Function

导出并删除文件,然后在记事本中打开它。将预先声明的Id更改为true。

VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
END
Attribute VB_Name = "Math"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False

保存并将文件导回到项目中。

现在,在常规模块中,您可以使用合格的调用来调用该函数。就像任何其他类方法一样。只有现在,我们有一个要使用的类的默认实例。 NewSet没有任何问题,它只是有效。

Sub Test()
    Debug.Print Math.Add(1,2)
End Test