Преамбула:
Задача заключается в следующем:
Необходимо достать из базы сохраненную книгу Excel, потом оттуда же достать список некоторых на текущий момент чисел с координатами, и положить числа по координатам в книгу Excel (Отчет). При этом используется Microsoft.Office.Interop.Excel.
Вариант выгружать данные в Excel по ячейке:
range = sourceSheetValues.get_Range("A1", "A1");
range.Value2 = someValue;
не устраивает, так как существуют большие отчеты с более чем 5000 ячеек — при выгрузке данных это все сурово тормозит.
Выгружать матрицами
range = sourceSheetValues.get_Range("A1", "С3");
range.Value2 = some3x3matrix;
тоже не устраивает так как в "теле" блока с данными может быть форматирование, текст и т.д. При записи матрицы все это будет перетерто.
Найден такой выход (общий смысл):
1) Выгрузить данные блоком на вспомогательный лист Excel.
2) Скопировать данные с него в буфер обмена Excel.
3) Вставить данные из буфера на лист отчета при помощи метода PasteSpecial с пропуском пустых значений (skip blanks). В этом случае содержание ячеек на которые не настроена выгрузка значений остается нетронутым.
Примерный код (выполняется для каждого листа отчета):
Range range;
try
{
//Вставляем блок с данными на вспомогательный лист
range = sourceSheetValues.get_Range(Utils.GetCellAddress(ruCell), Utils.GetCellAddress(ldCell));
range.Value2 = sheetValues;
//при помощи спец вставки копируем форматирование с листа приемника
range = targetSheet.get_Range(Utils.GetCellAddress(ruUsedRangeCell), Utils.GetCellAddress(ldUsedRangeCell));
range.Copy(Type.Missing);
range = sourceSheetFormats.get_Range(Utils.GetCellAddress(ruUsedRangeCell), Utils.GetCellAddress(ldUsedRangeCell));
range.PasteSpecial(XlPasteType.xlPasteFormats, XlPasteSpecialOperation.xlPasteSpecialOperationNone, false, false);
////при помощи спец вставки копируем значения с листа источника
range = targetSheet.get_Range(Utils.GetCellAddress(ruCell), Utils.GetCellAddress(ldCell));
range.UnMerge();
range = sourceSheetValues.get_Range(Utils.GetCellAddress(ruCell), Utils.GetCellAddress(ldCell));
range.Copy(Type.Missing);
range = targetSheet.get_Range(Utils.GetCellAddress(ruCell), Utils.GetCellAddress(ldCell));
range.PasteSpecial(XlPasteType.xlPasteValues, XlPasteSpecialOperation.xlPasteSpecialOperationNone, true, false);
//при помощи спец вставки копируем форматирование с листа источника
range = sourceSheetFormats.get_Range(Utils.GetCellAddress(ruUsedRangeCell), Utils.GetCellAddress(ldUsedRangeCell));
range.Copy(Type.Missing);
range = targetSheet.get_Range(Utils.GetCellAddress(ruUsedRangeCell), Utils.GetCellAddress(ldUsedRangeCell));
range.PasteSpecial(XlPasteType.xlPasteFormats, XlPasteSpecialOperation.xlPasteSpecialOperationNone, false, false);
////удаляем все что можно с листа источника
range = sourceSheetValues.get_Range(Utils.GetCellAddress(ruCell), Utils.GetCellAddress(ldCell));
range.Clear();
range.ClearContents();
range.ClearFormats();
range = sourceSheetFormats.get_Range(Utils.GetCellAddress(ruUsedRangeCell), Utils.GetCellAddress(ldUsedRangeCell));
range.Clear();
range.ClearContents();
range.ClearFormats();
}
catch
{
errors = errors + "Ошибка при выгрузке значений. \r\n";
return;
}
Кроме того тут еще учитываются всякие нюансы типа объединенных ячеек и т.д.
Проблема заключается в следующем. Если многократно (15-20 раз) запустить данную процедуру для одного экземпляра отчета (обновлять его) то на методах PasteSpecial Excel начинает сурово тормозить, каждая следующая операция обновления занимает все больше времени и процесс Excel отжирает все больше памяти.
Кто-нибудь может подсказать в чем дело?