0

我正在尝试将电子表格数据捕获到二维数组中。我正在使用 VSTO。

int rc = 1048576;
int cc = 1638;

string[,] arr = new string[rc, cc];

最后一行抛出内存不足异常。我想显示消息告诉用户只能捕获“X”元素。

检查 MSDN 并提到行数限制为 16,777,216。数据表没有列数限制。无法找到二维数组的限制。

我的问题不在于为什么例外。我正在寻找的是,如果您正在进行 VSTO 开发,并且必须在 DataTable 中捕获工作表以执行 In-Memory 连接等,您将需要这样做:

string[,] arr = new string[rc, cc]; 
Microsoft.Office.Interop.Excel.Range selection 
arr = selection.Value as string[,]; 

然后将该数组中的数据复制到数据表中。现在,用户应该选择的元素数量的理想限制是什么。所以我可以设置行数/列数限制并在选择超过此条件时显示消息。

4

2 回答 2

16

让我们算一下。您正在尝试分配一个包含 1048576 * 1638 = 1717567488 个元素的二维字符串数组。x64 上的字符串引用大小为 8 字节 => 总共 1717567488 * 8 = 13740539904 字节。这大约是13 GB的连续内存空间。CLR 的单个分配的最大大小为 2GB,因此您将收到 OutOfMemoryException,因为无法分配这样的单个块。

请注意,即使所有字符串都是 1-2 个字符长,这样数量的字符串也会占用 30GB 的字符串值以及引用。除了OutOfMemoryException你期望得到的还有什么?

于 2012-10-10T16:09:54.923 回答
0

Aleks,您要求限制您的内存分配。让我建议改变你的观点并 限制你的输入

  • 1.1 仅使用用户选择的单元格
  • 1.2 仅使用 xl.worksheet 中确实使用过的单元格

除了您的问题,我建议您注意和的区别Range.ValueRange.Value2Range.Value 包含用户输入,例如公式=SUM(A1:B10),而 Range.Value2 包含该公式的结果,例如10

1.1 仅使用用户选择的单元格如此
所述使用 1.2 仅使用 xl.worksheet 中确实使用的单元格 使用该属性。 也许会更好。 代码示例:Range userSelectedRange = Application.Selection;


Worksheet.Cells.SpecialCells
Worksheet.UsedRange

int lastUsedRowIndex = xlWorksheet.Cells.SpecialCells(XlCellType.xlCellTypeLastCell).Row;
int lastUsedColIndex = xlWorksheet.Cells.SpecialCells(XlCellType.xlCellTypeLastCell).Column;
string rangeString = string.Format("A0:{0}{1}", SomeIndexToExcelColConverterFunc(lastUsedColIndex), lastUsedRowIndex));
Xl.Range range = xlWorksheet.Range[rangeString];
object[,] objectMatrix = range.Value2 as object[,];
Marshal.ReleaseComObject(range);    
// convert to string here if needed
于 2013-01-14T10:54:31.593 回答