myWorksheet.Range.Resize.Value = сбой массива при высоких номерах строк

Я унаследовал большой проект, который использует Office.Interop.Excel для вставки данных в электронную таблицу.

С точки зрения видимого взаимодействия, вы нажимаете кнопку, и появляется электронная таблица Excel со всеми уже вставленными данными. Я упоминаю об этом, потому что видел, как это делалось в другом месте, когда программа уже была открыта и в нее вставлялись значения. Программа, с которой я работаю, вставляет данные до появления Excel.

К сожалению, как только вставляется относительно большой объем данных, передача информации в Excel блокируется, и программа не может продолжать работу.

Во всяком случае, я провел небольшое расследование и нашел следующую строку:

myWorksheet.Range("A" & rowNumber).Resize(dataArray.GetUpperBound(0) + 1, columnCount).Value = dataArray

Это копирует все данные в dataArray непосредственно в группу ячеек на листе.

Я предположил, что проблема может быть вызвана попыткой одновременно передать такой большой объем данных, поэтому я изменил его, чтобы копировать данные построчно:

For horizIndex As Integer = 0 To dataArray.GetUpperBound(0)
    Dim subArr(0, arr.GetUpperBound(1)) As Object
    For columnIndex As Integer = 0 To dataArray.GetUpperBound(1)
        subArr(0, columnIndex) = dataArray(horizIndex, columnIndex)
    Next
    myWorksheet.Range("A" & (rowNumber + horizIndex)).Resize(horizIndex + 1, columnCount).Value = arr
Next

Это скопирует 350 или около того строк в Excel, а затем значение параметра строки просто перестанет возвращаться.

Может ли кто-нибудь предложить способ обойти это?

РЕДАКТИРОВАТЬ: Хорошо, я попробовал кучу того, что Лазарус предложил ниже, и вот где я сейчас:

Пока данные относительно короткие или типы данных достаточно простые (целые числа и т. д.), все варианты кода работают нормально. Исходное массовое копирование работает нормально, копирование построчно и копирование по ячейкам работает, если набор данных либо небольшой, либо простой.

Однако мой фактический набор данных относительно сложен и содержит несколько типов данных, включая строки.

Он падает после 350-ти рядов. Он падает на стороне кода Excel, поток уходит в Excel и никогда не возвращается.

Итак, есть еще идеи, кто-нибудь?


person Frosty840    schedule 04.02.2011    source источник


Ответы (1)


Я думаю, что проблема здесь в постоянно расширяющемся диапазоне сотовой связи.

Я бы переработал строку:

myWorksheet.Range("A" & (rowNumber + horizIndex)).Resize(horizIndex + 1, columnCount).Value = arr

читать

myWorksheet.Range("A" & (rowNumber + horizIndex)).Resize(1, columnCount).Value = subArr

РЕДАКТИРОВАТЬ

Учитывая, что вы эффективно перебираете каждую ячейку, почему бы не воспользоваться этим:

For horizIndex As Integer = 0 To dataArray.GetUpperBound(0)
    For columnIndex As Integer = 0 To dataArray.GetUpperBound(1)
        myWorksheet.Cells(horizIndex + 1, columnIndex + 1).Value = dataArray(horizIndex, columnIndex)
    Next
Next
person Lazarus    schedule 04.02.2011
comment
@Lazarus Я думаю, ты, наверное, прав. Теперь он завершается, но каждая строка такая же, как и первая. Я пойду расследовать это. - person Frosty840; 04.02.2011
comment
О, я дебил и каждый раз вставляю в него dataArray вместо subArr. Вижу, ты уловил это раньше меня. Отличная работа. - person Frosty840; 04.02.2011
comment
@Frost840: Не беспокойтесь, мы все сидели с клочьями волос в руках после нескольких часов, гоняясь за жуком, которого просто не может быть, только для того, чтобы коллега прогуливался и без усилий указывал на слона в комнате :) - person Lazarus; 04.02.2011
comment
Хорошо, изменив его на вставку subArr, он снова упадет примерно на 350 строк. :( - person Frosty840; 04.02.2011
comment
@Lazarus RE: Редактировать: я думал об этом, но я всегда немного опасался выполнять поиск по индексу массива, основываясь на какой-то уморительно ужасной производительности, которую я использовал для получения коллекций .net еще до того, как были введены дженерики. Попытка сделать это таким образом выдает очень раздражающее COMException, которое также, похоже, жалуется на позднее связывание. Я не уверен, является ли это прогрессом программы, которая просто сидит и ничего не делает, или нет o_O EDIT: выдает COMException на отметке 350 строк - person Frosty840; 04.02.2011
comment
Возможно, ответ заключается в том, чтобы отформатировать данные в формате CSV, сохранить их на диск и запустить Excel для загрузки. Это быстро и грязно, но пока вы не найдете более подходящее решение... - person Lazarus; 04.02.2011
comment
ГАХ! Глупые комментарии StackOverflow! Я никогда не вижу шестого. Да, я собираюсь попробовать это в понедельник, если никто не предложит ничего чудесного в выходные. - person Frosty840; 04.02.2011