返回类型的Application.Evaluate在异国情况下

时间:2013-05-13 22:15:23

标签: c# excel office-interop

我正在尝试在C#中编写一个方法,在Excel工作簿中给定命名范围的名称,检索该范围内的值。即使命名范围不是对范围的纯引用(例如=Sheet1!A1:A10),我也希望它能够工作,而是={1,2,3,4,5}=OFFSET(Sheet1!A1:A10,3)

我正在做以下事情:

Excel.Application xl = ...;
Excel.Name name = ...;

object value = xl.Evaluate(name.Value);
// if it's a range, turn it into an object[] or object[,]
if (value is Excel.Range) value = ((Excel.Range)value).Value2;

if (value is object[]) {
    // do stuff
} else if (value is object[,]) {
    // do slightly different stuff
}

我原以为像={1,2,3,4,5}这样的名称范围只会是object[]object[,],但事实并非如此。 value.GetType()只报告System.__ComObject(编辑:现在我收到System.Object[*],但无法重现System.__ComObject - 但它仍然没有投放到object[] 1}}),我无法进一步缩小范围。

我应该将value投射到哪个类型?

编辑:这里有一些测试代码和输出。这可能是一个更简单的问题:“System.Object[*]是什么,谷歌的变幻莫测不允许我搜索。

代码:

using System;
using Excel = Microsoft.Office.Interop.Excel;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Excel.Application xl = new Excel.Application();
            object value = xl.Evaluate("={1,2,3,4,5}");
            Console.WriteLine(value);
            Console.WriteLine(value is object[]);
            Console.WriteLine(value.GetType());
            Console.ReadLine();
            xl.Quit();
        }
    }
}

输出:

  

System.Object的[*]

     

     

System.Object的[*]

edit2:如果我改为评估"={1;2;3;4;5}",那么我会得到object[,]。咦。

1 个答案:

答案 0 :(得分:1)

我认为这是因为Excel创建的数组不是基于0的,而是基于1的,你可以像这样转换它:

object[] ints = ((Array)value).ToArray<object>();

使用此辅助方法扩展名:

public static T[] ToArray<T>(this Array array)
{
    if (array == null)
        return null;

    if (array.Rank != 1)
        throw new NotSupportedException();

    var newArray = new T[array.GetLength(0)];
    var lb = array.GetLowerBound(0);
    for (int i = 0; i < newArray.Length; i++)
    {
        newArray[i] = (T)array.GetValue(i + lb);
    }
    return newArray;
}

如果您使用.NET 4,则Evaluate的返回类型可能会被定义为dynamic。所以使用此代码:

dynamic value = xl.Evaluate("={1,2,3,4,5}"); // or var instead of dynamic

您将获得System.InvalidCastException: Unable to cast object of type 'System.Object[*]' to type 'System.Object[]'因为新的.NET 4互操作层将自动尝试创建标准数组。所以你需要这样做(就像你在代码中那样):

object value = xl.Evaluate("={1,2,3,4,5}");
object[] ints = ((Array)value).ToArray<object>();