Microsoft.Office.Interop.Excel PasteSpecial тормозит работy
От: Trockiy  
Дата: 20.09.10 10:14
Оценка:
Преамбула:
Задача заключается в следующем:
Необходимо достать из базы сохраненную книгу 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 отжирает все больше памяти.
Кто-нибудь может подсказать в чем дело?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.