Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在VSTO项目中从Excel工作簿读取50万条记录_C#_Excel_Vsto - Fatal编程技术网

C# 在VSTO项目中从Excel工作簿读取50万条记录

C# 在VSTO项目中从Excel工作簿读取50万条记录,c#,excel,vsto,C#,Excel,Vsto,我正在尝试使用VSTO并通过创建VisualStudio2010 Office工作簿项目在Excel中构建一个模拟工具。此工作簿中的一个工作表将包含大约50万条记录。理想情况下,我希望读取模拟中使用它们的所有记录,然后输出一些统计数据。到目前为止,当我尝试获取整个范围,然后一次性将单元格从中取出时,出现了OutOfMemory异常。有人对我如何阅读所有数据或建议有其他想法吗 这是我的代码: Excel.Range Range=Globals.shData.Range[“A2:AX500000”]

我正在尝试使用VSTO并通过创建VisualStudio2010 Office工作簿项目在Excel中构建一个模拟工具。此工作簿中的一个工作表将包含大约50万条记录。理想情况下,我希望读取模拟中使用它们的所有记录,然后输出一些统计数据。到目前为止,当我尝试获取整个范围,然后一次性将单元格从中取出时,出现了
OutOfMemory
异常。有人对我如何阅读所有数据或建议有其他想法吗

这是我的代码:

Excel.Range Range=Globals.shData.Range[“A2:AX500000”]


数组值=(数组)range.Cells.Value

这不是Excel的问题,而是一般的C#问题。与其收集内存中的所有行,不如生成行并迭代计算统计数据

比如说

class Program
{
    static void Main(string[] args)
    {
        var totalOfAllAges = 0D;
        var rows = new ExcelRows();

        //calculate various statistics
        foreach (var item in rows.GetRow())
        {
            totalOfAllAges += item.Age;
        }

        Console.WriteLine("The total of all ages is {0}", totalOfAllAges);
    }
}

internal class ExcelRows
{
    private double rowCount = 1500000D;
    private double rowIndex = 0D;

    public IEnumerable<ExcelRow> GetRow()
    {
        while (rowIndex < rowCount)
        {
            rowIndex++;
            yield return new ExcelRow() { Age = rowIndex };
        }
    }
}
/// <summary>
/// represents the next read gathered by VSTO
/// </summary>

internal class ExcelRow
{
    public double Age { get; set; }
}
类程序
{
静态void Main(字符串[]参数)
{
var totalOfAllAges=0D;
var rows=新的ExcelRows();
//计算各种统计数字
foreach(行中的var项。GetRow())
{
总居住面积+=项目使用年限;
}
WriteLine(“所有年龄段的总数为{0}”,totalOfAllAges);
}
}
内部类ExcelRows
{
私有双行计数=1500000D;
私有双行索引=0D;
公共IEnumerable GetRow()
{
while(行索引<行计数)
{
rowIndex++;
返回新的ExcelRow(){Age=rowIndex};
}
}
}
/// 
///表示VSTO收集的下一次读取
/// 
内部类ExcelRow
{
公共双年龄{get;set;}
}

如何分批获取,并在内存中组装一个内存稍少的模型

var firstRow = 2;
var lastRow = 500000;
var batchSize = 5000;
var batches = Enumerable
    .Range(0, (int)Math.Ceiling( (lastRow-firstRow) / (double)batchSize ))
    .Select(x => 
        string.Format(
            "A{0}:AX{1}",
            x * batchSize + firstRow,
            Math.Min((x+1) * batchSize + firstRow - 1, lastRow)))
    .Select(range => ((Array)Globals.shData.Range[range]).Cells.Value);

foreach(var batch in batches)
{
    foreach(var item in batch)
    {
        //reencode item into your own object collection.
    }
}

您是否通过将范围分配给数组收到异常?是的。我取回了System.Array中的Cells.Value属性向机器添加更多内存?我会尝试这里提供的解决方案:这可能也很相关:这对理解大小/内存限制也很有用,尽管在这种情况下,我指的是C++,实际上是想把数据存储在CSV中,然后用ADO加载它,这样我就可以使用光标并一次运行一个块的模拟。这与光标的净效果相同,并且避免了与另一个文件的额外工作。这是一个很好的主意。我想用ADO.Net来做这个。