使用C#将excel范围转换为数组

时间:2014-03-31 11:37:58

标签: c# excel

我想使用C#

将excel范围转换为数组
System.Array MyRange = (System.Array)range.cells.value;
    for (int k = 0; k <= MyRange.Length; k++)
    {
        List<service_name> _ml = new List<service_name>();
        for (int j = 1; j < dataitems.Count; j++)
        {
            // enter code here
        }
    }

如何循环迭代 但是这段代码不起作用并调用错误:

  

&#34;无法转换类型为&#39; System.String&#39;的对象输入&#39; System.Array&#39;。&#34;

6 个答案:

答案 0 :(得分:6)

根据Microsoft here提供的帮助,这就是我在Excel中读写数组的方法。

var xlApp=new Microsoft.Office.Interop.Excel.Application();
var wb=xlApp.Workbooks.Open(fn, ReadOnly: false);
xlApp.Visible=true;
var ws=wb.Worksheets[1] as Worksheet;
var r=ws.Range["A2"].Resize[100, 1];
var array=r.Value;
// array is object[1..100,1..1]
for(int i=1; i<=100; i++)
{
    var text=array[i, 1] as string;
    Debug.Print(text);
}
// to create an [1..100,1..1] array use
var array2=Array.CreateInstance(
    typeof(object), 
    new int[] {100, 1}, 
    new int[] {1, 1}) as object[,];

// fill array2
for(int i=1; i<=100; i++)
{
    array2[i, 1] = string.Format("Text{0}",i);
}
r.Value2=array2;

wb.Close(SaveChanges: true);
xlApp.Quit();

Debug Excel

答案 1 :(得分:2)

原始帖子中的错误消息发生在范围恰好由一个单元格组成时,因为结果值的类型是variant,实际上可以是array,double,string,date和null。

一种解决方案可以是检查细胞计数,并在恰好一个细胞的情况下采取不同的行动。

我的解决方案创建了一个单元格数组。即使一个或多个单元格为空,这也会起作用,这可能会导致null对象。 (当范围的所有单元格都为空时,Range.Cells.Value为空。)

System.Array cellArray = range.Cells.Cast<Excel.Range>().ToArray<Excel.Range>();

如果您更喜欢Lists over Arrays(就像我一样),您可以使用以下代码:

List<Excel.Range> listOfCells = range.Cells.Cast<Excel.Range>().ToList<Excel.Range>();

范围可以是一维或二维。

最后,如果你肯定需要一个字符串数组,那么它是:

string[] strArray = range.Cells.Cast<Excel.Range>().Select(Selector).ToArray<string>();

其中Selector函数如下所示:

public string Selector(Excel.Range cell)
{
    if (cell.Value2 == null)
        return "";
    if (cell.Value2.GetType().ToString() == "System.Double")
        return ((double)cell.Value2).ToString();
    else if (cell.Value2.GetType().ToString() == "System.String")
        return ((string)cell.Value2);
    else if (cell.Value2.GetType().ToString() == "System.Boolean")
        return ((bool)cell.Value2).ToString();
    else
        return "unknown";
}

我包括&#34;未知&#34;对于这种情况,我不记得Value2可以返回的所有数据类型。如果您发现任何其他类型,请改进此功能。

答案 2 :(得分:1)

错误意味着该值是一个字符串,因此您无法将其直接转换为数组。

如果值是例如逗号分隔的字符串,则可以使用Split来获取数组:

string[] MyRange = (range.Cells.Value + "").Split(',');
for (int k = 0; k < MyRange.Length; k++)
{
    //...loop here...
}

同样修复了你的循环,你将获得Index Out of Bounds错误。

答案 3 :(得分:0)

谈话的后期,但这是一种方法:

static string[][] GetStringArray(Object rangeValues)
{
    string[][] stringArray = null;

    Array array = rangeValues as Array;
    if (null != array)
    {
        int rank = array.Rank;
        if (rank > 1)
        {
            int rowCount = array.GetLength(0);
            int columnCount = array.GetUpperBound(1);

            stringArray = new string[rowCount][];

            for (int index = 0; index < rowCount; index++)
            {
                stringArray[index] = new string[columnCount-1];

                for (int index2 = 0; index2 < columnCount; index2++)
                {
                    Object obj = array.GetValue(index + 1, index2 + 1);
                    if (null != obj)
                    {
                        string value = obj.ToString();

                        stringArray[index][index2] = value;
                    }
                }
            }
        }
    }

    return stringArray;
}

呼叫:

string[][] rows = GetStringArray(range.Cells.Value2);

答案 4 :(得分:0)

注意:此示例仅适用于一个单元以上的范围。如果Range仅是单个单元格(1x1),则Excel将以特殊方式对其进行处理,而range.Value2将不会返回二维数组,而是一个单个值。这些特殊情况类型将使您发疯,以及零和非零数组下限:

using Excel = Microsoft.Office.Interop.Excel;

private static void Test()
{
    Excel.Range range = Application.ActiveWorkbook.ActiveSheet.Range["A1:B2"]; // 2x2 array

    range.Cells[1, 2] = "Foo"; // Sets Cell A2 to "Foo"
    dynamic[,] excelArray = range.Value2 as dynamic[,]; // This is a very fast operation
    Console.Out.WriteLine(excelArray[1, 2]); // => Foo

    excelArray[1, 2] = "Bar";
    range.Value2 = excelArray; // Sets Cell A2 to "Bar", again a fast operation even for large arrays
    Console.Out.WriteLine(range.Cells[1, 2]); // => Bar

请注意,excelArray的行和列下限为1:

    Console.Out.WriteLine("RowLB: " + excelArray.GetLowerBound(0)); // => RowLB: 1
    Console.Out.WriteLine("ColLB: " + excelArray.GetLowerBound(1)); // => ColLB: 1

但是,如果您在C#中声明newArray并将其赋值,则下界将为0,但仍将起作用:

    dynamic[,] newArray = new dynamic[2, 2]; // Same dimensions as "A1:B2" (2x2)
    newArray[0, 1] = "Foobar";
    range.Value2 = newArray; // Sets Cell A2 to "Foobar"
    Console.Out.WriteLine(range.Cells[1, 2]); // => Foobar

获取该值超出范围将为您提供下限为0的原始数组:

    range.Cells[1, 2] = "Fubar";

    dynamic[,] lastArray = range.Value2 as dynamic[,];
    Console.Out.WriteLine(lastArray[0, 1]); // => Fubar

    Console.Out.WriteLine("RowLB: " + lastArray.GetLowerBound(0)); // => RowLB: 0
    Console.Out.WriteLine("ColLB: " + lastArray.GetLowerBound(1)); // => ColLB: 0
}

使用Excel Interop可能会令人生畏,因为在代码库中有许多类似的特殊情况,但是我希望这至少有助于弄清这一情况。

答案 5 :(得分:0)

问题是因为,当您的范围变成单个单元格时,“ range.value” /“ range.cell.value”表示字符串值,因此无法将该字符串放入对象数组。 因此,请检查您的范围是否只有一个或多个单元格,并按照该条件进行操作