excel - Excel 2007 UDF:如何添加函数说明,参数帮助?

标签 excel excel-udf com-server

说明

我正在COM服务器中编写几个Excel UDF。我想获得按fx时获得的标准帮助(“插入功能”对话框)。是的,我可以在类别下拉列表中看到我的COM服务器,但是


我还看到了Equals,GetHashCode,GetType和ToString(这对于公开给Excel用户是非常不希望的),
选择我的COM服务器将显示* Function Arguments * [1]对话框,其中没有参数信息,也没有函数描述。


这是我的the行:

Insert Function dialog http://www.iwebthereforeiam.com/files/Insert%20function%20dialog.gif

Excel Function Arguments dialog http://www.iwebthereforeiam.com/files/Function%20Arguments%20dialog.gif

问题

我可以在方法上添加.NET属性以将其传递给Excel吗?


我可以提供功能说明吗?
我可以提供参数说明吗?
我可以为我的函数提供一个类别名称,以便获得比ProgID更好的东西吗?


(我发现在ExcelDNA中看起来很容易做到,但我没有走这条路。模拟govert的代码[自定义属性,某种加载程序等]看起来会很困难。)



其他背景

如果您以前没有使用过Excel + COM Server,那么这里有一些有用的资源可以帮助您快速入门:

以前的StackOverflow问题:
How to get COM Server for Excel written in VB.NET installed and registered in Automation Servers list?
How Add a COM-Exposed .NET Project to the VB6 (or VBA) References Dialog?

其他资源:
Writing user defined functions for Excel in .NET
Build and Deploy a .NET COM Assembly
Writing Custom Excel Worksheet Functions in C#



编辑2009-10-20 14:10

我尝试在Application.MacroOptions中调用Sub New()


没有子New()
半可接受的:功能在类别ProgID下列出。
共享子New()
不可接受:构建时错误。无法注册程序集“ ... \ Foo.dll”。
调用的目标已引发异常。
子New()
不可接受:在“插入函数”对话框中未列出类别。


我怀疑这对于MacroOptions以及Charles建议的更复杂的路线都是一个问题。



编辑2009-10-20 14:55

从好的方面来说,Mike建议创建一个要实现的接口确实消除了暴露的恼人的额外方法。



编辑2009-10-20 15:00

从2007年初开始的This Microsoft article(通过Mike's link)对于该主题似乎是一个相当完整的答案:


自动化加载项和功能
巫师

每个自动化加载项都有自己的
Excel函数向导中的“类别”。
类别名称是针对的ProgID
加载项;您不能指定一个
自动化的不同类别名称
附加功能。另外,那里
无法指定功能
说明,参数说明,
或帮助自动化加载项
功能向导中的功能。




1呵呵,一个StackOverFlow错误。看起来您不能在显式HTML ul-list中的斜体字符串是斜体?

最佳答案

其中一些很容易纠正,而其他部分则很难。但是,如果您愿意花时间,所有这些都是可行的。

你写了:


我还看到了Equals,GetHashCode,
GetType和ToString(
暴露于
Excel用户)


是的,同意,这绝对是不可取的,但可以避免。发生这种情况的原因是,您的类像所有.NET类一样都是从“ System.Object”继承的,并且公开给COM的默认接口包括这些成员。例如,如果您使用“ ClassInterfaceAttribute”,并使用“ ClassInterfaceType.AutoDual”设置,则会发生这种情况。

例如。在C#中:

[ClassInterface(ClassInterfaceType.AutoDual)]


在VB.NET中:

<ClassInterface(ClassInterfaceType.AutoDual)>


但是,应避免使用“ ClassInterfaceType.AutoDual”,以防止暴露从“ System.Object”继承的成员(以及防止将来出现潜在的版本问题)。而是定义您自己的接口,在您的类中实现该接口,然后使用值为'ClassInterfaceType.None'的'ClassInterface'属性标记您的类。

例如,使用C#:

[ComVisible(true)]
[Guid("5B88B8D0-8AF1-4741-A645-3D362A31BD37")]
public interface IClassName
{
    double AddTwo(double x, double y);
}

[ComVisible(true)]
[Guid("010B0245-55BB-4485-ABAF-46DF4356DB7B")]
[ProgId("ProjectName.ClassName")]
[ComDefaultInterface(typeof(IClassName))]
[ClassInterface(ClassInterfaceType.None)]
public class ClassName : IClassName
{
    public double AddTwo(double x, double y)
    {
        return x + y;
    }
}


使用VB.NET:

<ComVisible(True)> _
<Guid("5B88B8D0-8AF1-4741-A645-3D362A31BD37")> _
Public Interface IClassName
    Function AddTwo(ByVal x As Double, ByVal y As Double) As Double
End Interface

<ComVisible(True)> _
<Guid("010B0245-55BB-4485-ABAF-46DF4356DB7B")> _
<ProgId("ProjectName.ClassName")> _
<ComDefaultInterface(GetType(IClassName))> _
<ClassInterface(ClassInterfaceType.None)> _
Public Class ClassName
    Implements IClassName

    Public Function AddTwo(ByVal x As Double, ByVal y As Double) As Double _
        Implements IClassName.AddTwo
        Return x + y
    End Function
End Class


通过使用值为“ ClassInterfaceType.None”的“ ClassInterfaceAtribute”,可以排除继承的“ System.Object”成员,因为该类的接口不是COM可见的。而是仅将已实现的接口(在此示例中为“ IClassName”)导出到COM。

上面还利用了'ComDefaultInterfaceAttribute'。这不是很重要,如果仅实现一个接口(如本例中所示),则什么也不做,但是如果以后添加一个接口(例如IDTExtensibility2),则是个好主意。

有关此的更多详细信息,请参见:

(1)安德鲁·怀特查佩尔(Andrew Whitechapel)的Managed Automation Add-ins

(2)Gabhan Berry的Writing Custom Excel Worksheet Functions in C#

好的,现在到了最困难的部分。你写了:


选择我的COM服务器将弹出
没有参数信息且没有的函数参数[1]对话框
功能说明。

我可以提供有关
功能?

我可以提供有关
参数?

我可以为我提供一个类别名称吗
功能,让我得到一些东西
比ProgID更好?


这里最简单的方法是利用Application.MacroOptions方法。此方法使您可以提供功能的描述,并指定要在其下显示的类别。不幸的是,这种方法不允许您为函数参数指定任何信息,但是允许您这样做的技术非常复杂,我将在后面介绍。 [更正:'Application.MacroOptions'方法仅适用于通过VBA创建的UDF,而不能用于自动化加载项。继续阅读以了解更复杂的方法来处理自动加载项中UDF容器的注册-Mike Rosenblum 2009.10.20]

请注意,help files for Excel 2003help files for Excel 2007指出可以将字符串提供给category参数,以便提供您选择的自定义类别名称。但是请注意, help files for Excel 2002 不会。我不知道这是Excel 2002帮助文件中的遗漏之处,还是Excel 2003中的一项新功能。我猜是后者,但是您必须进行测试才能确定。

将参数信息输入功能向导的唯一方法是使用涉及'Excel.Application.ExecuteExcel4Macro'方法的相当复杂的技术。但请注意:许多Excel MVP都在努力使用此方法,但未能产生可靠的结果。但是,最近,Jan Karel Pieterse(JKP)似乎已经解决了问题,并在此处发布了详细信息:Registering a User Defined Function with Excel

略读该文章,您会发现它不是为了胆小者。问题的一部分是他为VBA / VB 6.0编写的,因此所有这些代码都必须转换为VB.NET或C#。但是,关键命令是'Excel.Application.ExecuteExcel4Macro'方法,该方法在.NET中公开,因此一切正常。

但是,实际上,我非常喜欢使用“ Excel.Application.MacroOptions”方法,因为它既简单又可靠。它不提供参数信息,但是我还没有强烈的动机激励我采用“ ExecuteExcel4Macro”方法。

因此,祝您好运,但是我的建议是使用“ MacroOptions”,除非您按小时付费。 ;-)

-迈克

休的回信


我尝试打电话
子程序中的Application.MacroOptions
新()。

无Sub New()半可接受:函数
在类别ProgID下列出。

Shared Sub New()不可接受:
建立时错误。无法注册
程序集“ ... \ Foo.dll”。有例外
被一个目标扔了
调用。

Sub New()不可接受:类别为
未在“插入函数”对话框中列出。
我怀疑这都是一个问题
MacroOptions和更多涉及
查尔斯推荐的路线。


当您将类暴露给COM时,不能使用共享(也称为“静态”)类或构造函数,因为COM不了解此概念,因此无法编译-如您所知!您可能可以将值为“ False”的“ COMVisibleAttribute”应用于共享构造函数,以至少允许其进行编译。但这在任何情况下都无济于事...

尝试通过自动化加载项本身注册自动化加载项可能会很棘手。我意识到,将其保留为单个独立组件是理想的,但可能无法实现。或至少这并不容易。

问题是自动化加载项是按需加载的。也就是说,直到Excel尝试从自动化加载项访问第一个工作表功能之前,它们才真正存在。有两个与此有关的问题:

(1)如果将注册代码放在类的构造函数中,则根据定义,直到第一次调用该函数时,函数向导信息才存在。

(2)当Excel尚未准备好接受自动化命令时,您的构造函数可能正在执行。例如,当用户开始键入自动化加载项中定义的用户定义功能(UDF)之一的名称时,通常会按需加载自动化加载项。结果是,当您的自动化加载项首次加载时,该单元格处于编辑模式。如果在编辑模式下构造函数中包含自动化代码,则许多命令将失败。我不知道'Excel.Application.MacroOptions'或'Excel.Application.Excel4Macro'方法是否存在问题,但是在单元格处于编辑模式下尝试执行时,许多命令会阻塞。而且,如果由于在打开功能向导时调用了自动加载项而第一次加载了自动化加载项,我不知道这些方法是否可以正常工作。

如果您希望自动化插件完全独立且没有其他支持,则没有简单的解决方案。但是,您可以创建一个托管的COM加载项,在Excel启动时将通过“ Excel.Application.MacroOptions”或“ Excel.Application.Excel4Macro”方法为您注册自动化加载项。托管COM外接程序类可以与自动化外接程序位于同一程序集中,因此您仍然只需要一个程序集。

顺便说一句,您甚至可以使用VBA工作簿或.XLA加载项执行相同操作-使用VBA中的Workbook.Open事件来调用注册代码。 Excel启动时,您只需要一些即可调用您的注册码。在这种情况下使用VBA的好处是,您可以按原样使用Jan Karel Pieterse的Registering a User Defined Function with Excel文章中的代码,而不必将其转换为.NET。


从好的方面来说,迈克的
建议创建一个界面
实施确实消除了烦人的事情
公开的其他方法。


大声笑,我很高兴有些工作!


这篇来自2007年初的Microsoft文章
(通过迈克的链接)似乎是一个相当
关于该主题的完整答案:

自动化加载项和功能
巫师

每个自动化加载项都有自己的
Excel函数向导中的“类别”。
类别名称是针对的ProgID
加载项;您不能指定一个
自动化的不同类别名称
附加功能。另外,那里
无法指定功能
说明,参数说明,
或帮助自动化加载项
功能向导中的功能。


这仅是对“ Excel.Application.MacroOptions”方法的限制。 (我道歉,我在上面写我的原始答案时,已经忘记了'Excel.Application.MacroOptions'方法对自动化加载项的限制。)比较复杂的'Excel.Application。但是,ExecuteExcel4Macro方法对于自动化加载项绝对有效。它也应该也适用于.NET(“托管”)自动化加载项,因为Excel不知道是否要加载通过VB 6.0 / C ++创建的COM自动化加载项,而不是加载使用VB 6.0 / C ++创建的COM自动化加载项。 VB.NET/C#。从Excel的角度来看,其机制完全相同,因为Excel不知道什么是.NET,甚至不知道.NET。

就是说,'Excel.Application.Excel4Macro'方法肯定是很多工作...

关于excel - Excel 2007 UDF:如何添加函数说明,参数帮助?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1592440/

相关文章:

c# - 为什么我的 XLL 比我的 UDF 慢?

Python COM 服务器抛出 'module' 对象没有属性 'VARIANT'

delphi - 我找到了 ComClass,现在如何引用它?

c# - Excel 在工作表中仍有事件的 RTD 公式时调用 IRTD.ServerTerminate

python - 收集子进程输出并在 python 中写入 excel

java - 如何使用java在Excel中的多个单元格中写入数据?

Javascript Excel 工作表

excel - 双击一个单元格以使用 VBA 显示来自 Excel 中链接的图片

vba - UDF 删除单元格中的特殊字符、标点符号和空格,为 Vlookups 创建唯一键

excel - 当工作簿移动到与加载项不同的文件夹时,如何保留对加载项 UDF 的引用?