Почему 1С 7.7 аварийно завершает работу на методе Таб.Показать() при пакетной печати и как это исправить?

Программист 1С v7.7 1C:Бухгалтерия Бухгалтерский учет Торговля и дистрибуция
← На главную

При организации пакетной печати первичных документов в платформе 1С:Предприятие 7.7 часто используется подход с объединением нескольких печатных форм в один результирующий объект типа Таблица. Это позволяет отправить на принтер сразу сотни документов без необходимости открывать каждый из них в отдельном окне. Однако при добавлении новых сложных макетов (например, транспортной накладной) разработчики нередко сталкиваются с ситуацией, когда платформа внезапно и без вывода каких-либо сообщений об ошибках завершает работу прямо при вызове метода Таб.Показать().

Разберем детально, почему возникает такое поведение платформы, какие скрытые дефекты макетов к этому приводят и как по шагам восстановить стабильную работу групповой печати.

Анализ механизма возникновения ошибки

В момент выполнения метода Показать() табличный процессор 1С 7.7 производит рендеринг документа в графической подсистеме Windows (GDI) и обращается к установленному в системе драйверу принтера по умолчанию для пересчета межстрочных интервалов, метрик шрифтов и границ страниц. Если в структуре макета содержатся повреждения, движок платформы может вызвать критическое исключение (Access Violation).

Выделим основные причины, приводящие к падению процесса 1cv7s.exe:

  1. Повреждение бинарной структуры макета или скрытые графические примитивы. В процессе многократного редактирования типовых и внешних печатных форм в таблицах могут накапливаться скрытые OLE-объекты, рамки с отрицательными или нулевыми координатами, а также разрушенные связи объединенных ячеек. При объединении множества таких секций в одну большую таблицу внутренний парсер координат ячеек дает сбой.
  2. Конфликт драйвера печати и расчета страниц. Платформа 7.7 рассчитывает виртуальную разбивку на страницы на основе драйвера принтера по умолчанию. Если драйвер сетевой или универсальный (UPD), сложная многостраничная форма может приводить к переполнению буфера при визуализации.
  3. Непечатные управляющие символы. Попадание в текстовые параметры символов с кодами меньше 32 (например, Симв(0)) способно разрушить строковый поток отрисовки таблицы.
  4. Исчерпание системных дескрипторов GDI. Формирование массивного отчета с десятками различных шрифтов и стилей рамок может упереться в лимит дескрипторов Windows, что приводит к мгновенному падению при попытке создать окно формы.

Решение 1. Пересоздание макета печатной формы с чистой таблицы

Как показывает практика, наиболее частой причиной спонтанных падений является накопленная ошибка в самом файле макета (.mxl или макете внутри внешней обработки .ert). Обычное разъединение ячеек проблему не решает, так как поврежденные дескрипторы остаются внутри структуры документа.

Разберем по шагам алгоритм восстановления макета:

  1. Откроем проблемную внешнюю печатную форму в Конфигураторе.
  2. Создадим в обработке абсолютно новую, чистую таблицу макета.
  3. Посекционно скопируем рабочие области из старой таблицы в новую (шапку, строки, подвал). При этом перенос следует делать блоками, без захвата пустых краевых областей.
  4. Назначим для всех ячеек стандартные системные шрифты (например, Arial или Tahoma) без экзотических начертаний.
  5. Удалим исходный поврежденный макет и переименуем новый созданный макет в штатное имя.
  6. Сохраним обработку и выполним тестовое формирование пакета документов.

Решение 2. Печать без визуального отображения (в обход Таб.Показать)

Если задача заключается исключительно в отправке пакета на печать, вызов метода Таб.Показать() является избыточным шагом, нагружающим графический интерфейс. Отправку сформированного объекта Таблица можно производить напрямую в спулер печати.

Посмотрим на пример кода, позволяющего отправить документы на принтер минуя экранное отображение:


// Формируем сводный табличный документ
ТабОбщая = СоздатьОбъект("Таблица");

Пока ВыборкаДокументов.ПолучитьДокумент() = 1 Цикл
    // Вызываем процедуру печати конкретного документа, выводящую секции в ТабОбщая
    ПечатьДокументаВТаблицу(ВыборкаДокументов.ТекущийДокумент(), ТабОбщая);
    ТабОбщая.НоваяСтраница();
КонецЦикла;

// Вместо ТабОбщая.Показать() отправляем напрямую на печать:
// Параметр 0 - печать без вывода диалога настройки
// Параметр 1 - печать с выводом стандартного диалога выбора принтера
ТабОбщая.Напечатать(0);

Решение 3. Настройка системного окружения и пакетная разбивка

Если объем печатаемой первички исчисляется сотнями страниц, рекомендуется оптимизировать процесс вывода данных системно:

  1. Установка стабильного локального принтера по умолчанию. На сервере или рабочей станции установим принтером по умолчанию виртуальный PDF-принтер со стандартным драйвером (например, Microsoft Print to PDF). Это исключит сбои при расчете геометрии нестандартных таблиц.
  2. Пакетная обработка порциями. Вместо накопления 100–200 накладных в один гигантский объект Таблица разобьем процесс на батчи по 20–30 документов. После отправки каждой пачки на печать будем пересоздавать объект через ТабОбщая = СоздатьОбъект("Таблица"), что гарантированно освободит оперативную память и дескрипторы GDI.
← На главную