0

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

我曾认为具有 like 值的命名范围={1,2,3,4,5}只会以object[]or的形式出现object[,],但事实并非如此。 value.GetType()只是报告System.__ComObject(编辑:现在我得到了System.Object[*],并且无法复制System.__ComObject- 但它仍然没有转换为object[]),我无法进一步缩小范围。

我应该投射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();
        }
    }
}

输出:

系统.对象[*]

错误的

系统.对象[*]

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

4

1 回答 1

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>();
于 2013-05-16T15:20:48.550 回答