Книга знаний

1С:Предприятие / Администрирование / Производительность

Исправление ошибки при экспорте в Excel (патчинг Moxel.dll)

При попытке сохранить в Excel большой таблицы 1С "подвисает", нагружая процессор на 100%. Попытаемся исправить этот недостаток 1С 7.7.Автор статьи: romix | Редакторы:
Последняя редакция №4 от 11.05.06 | История
URL: http://kb.mista.ru/article.php?id=219

Ключевые слова: тормоза, при сохранении в Excel


Отладчик SoftICE позволяет находить подобные "узкие места" в производительности программы, если просто запустить подопытную программу, сделать так, чтобы она начала тормозить (я создал большую таблицу, и стал сохранять ее в Excel), и нажать Ctrl-D. Велика (близка к 100%) вероятность, что указатель команды микропроцессора будет находиться в "грузящем" систему потоке, и таким образом, несколькими нажатиями F10, мы выйдем на цикл, который загружает нашу систему.

Вот этот цикл:

00029875: 57                           push        edi
00029876: 8BCE                         mov         ecx,esi
00029878: E813010000                   call        000029990  ---↓ (1)

0002987D: 8B54247C                     mov         edx,[esp][7C]
00029881: 85D2                         test        edx,edx
00029883: 7E08                         jle         00002988D  ---↓ (2)

00029885: 895C2464                     mov         [esp][64],ebx
00029889: 03D8                         add         ebx,eax
0002988B: EB0C                         jmps        000029899  ---↓ (3)

0002988D: 8B4C2464                     mov         ecx,[esp][64]
00029891: 8BD9                         mov         ebx,ecx
00029893: 2BC8                         sub         ecx,eax
00029895: 894C2464                     mov         [esp][64],ecx
00029899: 3B7C2478                     cmp         edi,[esp][78]
0002989D: 7404                         je          0000298A3  ---↓ (4)

0002989F: 03FA                         add         edi,edx
000298A1: EBD2                         jmps        000029875  ---↑ (5)


Это был дамп из программы Hiew.
В SoftICE вызов call выглядит так:
call Moxel!?GetRowHeight@CSheetGDI@@QAEHH@Z

Отладчик показывает, что вызов GetRowHeight() выполняется N-факториал раз. Поэтому
Для малого числа строк (100, 500) ничего особенного пользователь не замечает, но для большого числа строк (например, 10000) все "подвисает" (хотя, за ночь бурной работы, наверное, может, с грехом пополам, и выполниться).

Эта ошибка, кстати, достаточно распространенная и коварная: на малом числе итераций (повторений цикла) проблему не видно, а на большом - она растет экспоненциально.

Некоторое (приблизительное) решение проблемы дает следующая правка (в последней строке приведенного дампа):

000298A1: EBE2                         jmps        000029885  ---↑ (5)


После этой правки 1С перестает "подвисать" при сохранении в Excel, но, к сожалению, начинаются некие трудности при просмотре и редактировании таблицы. Поэтому применение патченной папки BIN - сформировать отчет и сохранить его в Excel. А основную работу выполнять в непатченной 1С.
Более удобный вариант патча, который задействуется только при записи в XLS, наверное, можно сделать, но я этим пока не занимался.


Другие варианты действий:
  • Поскольку в цикле вызывается GetRowHeight(), установить всем строкам отчета фиксированную (заранее прописанную) высоту. Недостаток - не будет работать "красивое" выравнивание ячеек по высоте.

  • Записывать в формат HTML (там этой ошибки почему-то нет).
  • Использовать программу "1С:Предприятие - Работа с файлами" для просмотра MXL и прочих файлов, которая распространяется фирмой 1С бесплатно, и подходить для файлов 7.7/8.0.

  • Переходить на 1С:Предприятие 8.0. :-)


Описание | Рубрикатор | Поиск | ТелепатБот | Захваченные статьи | Установки | Форум
© Станислав Митичкин (Волшебник), 2005-2025 | Mista.ru

Яндекс.Метрика