首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ExcelDNA在运行时动态注册UDF

ExcelDNA在运行时动态注册UDF
EN

Stack Overflow用户
提问于 2018-08-25 15:16:26
回答 1查看 973关注 0票数 0

我的目标是在运行时在ExcelDNA AddIn中动态构建和注册Excel用户定义的函数。

下面是一个例子由ExcelDNA作者提供,它突出了如何从简单的C#代码字符串编译UDF。

如您所见,这段代码是通过从AddIn的RegisterMyClass方法中调用AutoOpen来执行的;而且一切都很完美。

但是,如果将RegisterMyClass方法移动到(例如)丝带按钮的操作方法中,则动态UDF的注册不起作用,并导致以下错误:

代码语言:javascript
运行
复制
Registration [Error] xlfRegister call failed for function or command: 'MyDynamicAdd'

实际上,对ExcelIntegration.RegisterMethods的任何调用似乎都会在上面的错误消息中失败--除非它们是从AutoOpen方法中调用的。

我的问题是:

我如何在运行时动态注册一个新的UDF,并通过单击丝带按钮触发它呢?

为了完整性起见,引用了Gist代码:

代码语言:javascript
运行
复制
<DnaLibrary Name="ExcelDna Test Dynamic Method" Language="C#">
<Reference Name="System.Windows.Forms" />
    <![CDATA[
    using System;
    using System.CodeDom.Compiler;
    using System.Collections.Generic;
    using System.IO;
    using System.Reflection;
    using System.Windows.Forms;
    using Microsoft.CSharp;
    using ExcelDna.Integration;

    public class Test : IExcelAddIn
    {
        // Just to test that we are loaded.
        public static double MyAdd(double d1, double d2)
        {
            return d1 + d2;
        }

        public void AutoOpen()
        {
            RegisterMyClass();
        }

        public void AutoClose()
        {
        }

        private void RegisterMyClass()
        {
            string code = 
                @"
                public class Script 
                { 
                    public static double MyDynamicAdd(double d1, double d2)
                    {
                        return d1 + d2;
                    }
                }";

        CompilerParameters cp = new CompilerParameters();
        cp.GenerateExecutable = false;
        cp.GenerateInMemory = true;
        cp.TreatWarningsAsErrors = false;
        cp.ReferencedAssemblies.Add("System.dll"); //, "System.Windows.Forms.dll", "ExcelDna.Integration.dll" );
        CSharpCodeProvider provider = new CSharpCodeProvider();
        CompilerResults cr = provider.CompileAssemblyFromSource(cp, new string[] { code });
        if (!cr.Errors.HasErrors)
        {
            Assembly asm = cr.CompiledAssembly;
            Type[] types = asm.GetTypes();
            List<MethodInfo> methods = new List<MethodInfo>();

            // Get list of MethodInfo's from assembly for each method with ExcelFunction attribute
            foreach (Type type in types)
            {
                foreach (MethodInfo info in type.GetMethods(BindingFlags.Public | BindingFlags.Static))
                {
                    methods.Add(info);
                }
            }
            Integration.RegisterMethods(methods);
        }
        else
        {
            MessageBox.Show("Errors during compile!");
        }
    }
    }
]]>
</DnaLibrary>
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-25 16:12:03

注册函数的代码需要在C可用的上下文中。它不会在带状回调或任何其他COM事件处理程序中工作。

切换到call可用的宏上下文的一个选项是调用ExcelAsyncUtil.QueueAsMacro助手,并在传入的委托中运行注册代码。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52018596

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档