使用InvokeMember通过C#在Excel中创建特定属性

时间:2016-05-11 23:16:22

标签: c# excel vsto cultureinfo invokemember

当我们通过C#中的COM调用Excel对象模型时,它总是使用en-US文化(这是几年前所做的更改,因此无论区域设置如何,插件都可以在所有计算机上运行。)

我想调用具有特定文化的Excel对象模型,根据Excel文档执行此操作的方法是使用InvokeMember并传递cultureInfo参数。 https://msdn.microsoft.com/en-us/library/bb157877.aspx

但是,每当我尝试使用en-US以外的语言环境时,我都会收到System.Reflection.TargetInvocationException。

因此,使用下面的示例代码,该调用将与en-US文化一起使用,但会使用fr-CA文化引发异常。请注意,更改区域设置中的当前区域性不会影响是否抛出异常。虽然根据区域设置使用Value2属性时,它将确定字符串是否被解释为数字。

我基于这个例子的代码,它在编写时似乎正在工作: https://social.msdn.microsoft.com/Forums/office/en-US/2aee0a8a-aaff-48a8-9364-edf1e3fbb9b4/setting-rangevalue2-behavior-changed-between-net-20-and-net-40-for-international-versions-of?forum=exceldev

是否有人知道我可以使用除en-US之外的特定文化调用Range.Value2会发生什么变化?

    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
        try
        {
            var excelApp = Globals.ThisAddIn.Application;
            var workbook = excelApp.Workbooks.Add();
            var worksheet = (Excel.Worksheet)workbook.Worksheets[1];
            var rangeA1 = worksheet.Range["A1"];
            var rangeB1 = worksheet.Range["B1"];
            string num1English = "1.1";
            string num1French = "1,1";

            rangeA1.GetType().InvokeMember("Value2", BindingFlags.Instance | BindingFlags.SetProperty | BindingFlags.Public, null,
                                            rangeA1, new object[] { num1English }, new CultureInfo("en-US"));

            rangeB1.GetType().InvokeMember("Value2", BindingFlags.Instance | BindingFlags.SetProperty | BindingFlags.Public, null,
                                            rangeB1, new object[] { num1French }, new CultureInfo("fr-CA"));
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString() + "\n\n" + ex.StackTrace);
        }
    }

2 个答案:

答案 0 :(得分:0)

HowTo: Fix “Old format or invalid type library” error (0x80028018)中查找示例。您可以在线使用任何VB.NET到C#代码转换器。

答案 1 :(得分:0)

您误读了文档。它说的是区域设置ID,而不是CultureInfo。这也是合乎逻辑的,Excel并不是使用.NET Framework编写的,而且COM技术的存在远比.NET本身早,并且具有比.NET本身更广泛的用法,因此该参数应可在不同的编程语言中工作。您应该传递的是CultureInfo实例的LCID属性。