Почему долго формируется печатная форма УПД и Счета-фактуры в 1С:Управление торговлей 11?

Системный администратор 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

Рассмотрим распространенную ситуацию, с которой часто сталкиваются пользователи программ на базе новой архитектуры взаиморасчетов (1С:Управление торговлей 11, 1С:Комплексная автоматизация 2, 1С:ERP). После создания документа реализации и выписки счета-фактуры при первой попытке распечатать УПД или Счет-фактуру система замирает на 1–2 минуты. База зависает, в Журнале регистрации фиксируются долгие операции по расчету взаиморасчетов, а последующие формирования той же печатной формы проходят моментально. Разберем по шагам, почему возникает эта проблема и как ее решить.

Что происходит внутри системы при нажатии кнопки "Печать"

Проанализируем поведение системы на уровне программного кода. Задержка возникает не из-за самой генерации макета, а из-за подготовки данных для него.

  1. В модуле менеджера документа СчетФактураВыданный при формировании макета вызывается функция ПолучитьДанныеДляПечатнойФормыСчетФактура.
  2. Эта функция должна вывести в печатную форму актуальные данные по зачтенным авансам (номера и даты платежных поручений). Для этого система проверяет регистр сведений ЗаданияКРаспределениюРасчетовСКлиентами по текущему контрагенту.
  3. Если программа обнаруживает в этом регистре необработанные задания, она принудительно запускает механизм актуализации расчетов прямо в текущем сеансе пользователя.
  4. Пользователь вынужден ждать, пока система пересчитает все "хвосты" взаиморасчетов в фоне, что и вызывает "зависание" интерфейса.

Основные причины долгого расчета и зависаний

Выясним причину, почему пересчет может занимать столь длительное время (до нескольких минут на один документ).

1. Отсутствие регламентного обслуживания СУБД. Алгоритмы расчета взаиморасчетов строят большие временные таблицы и используют сложные пакетные запросы. Если на сервере (например, MS SQL Server) не выполняется регулярное обновление статистик или сильно фрагментированы индексы, оптимизатор запросов выбирает крайне неэффективный план выполнения. То, что должно рассчитываться доли секунды, заставляет сервер сканировать таблицы целиком.

2. Накопление "битых" заданий в очереди. Иногда в регистр заданий попадают записи с пустыми измерениями (незаполненный объект расчетов, пустой партнер или документ). Регламентное фоновое задание по расписанию не может корректно их обработать и завершается с ошибкой, а очередь из десятков тысяч записей продолжает расти. При попытке печати программа каждый раз безуспешно пытается их пересчитать.

3. Конфликт блокировок таблиц. В процедуре ЗаблокироватьРегистрЗаданий общего модуля РаспределениеВзаиморасчетовВызовСервера вызывается метод Блокировка.Заблокировать(). Если в момент печати фоновое задание пытается сделать то же самое, возникает конфликт блокировок, и сеанс пользователя уходит в режим ожидания.

Как решить проблему с зависанием печатных форм

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

Настройка обслуживания базы данных на сервере (MS SQL / PostgreSQL)

Это самое эффективное и правильное решение, которое часто сразу снимает симптом зависания. Настройте на сервере СУБД регулярные планы обслуживания (Maintenance Plans). Как минимум, необходимо настроить:

  1. Ежедневное обновление статистик. Для MS SQL это запуск стандартной процедуры sp_updatestats или задача "Update Statistics".
  2. Еженедельную дефрагментацию (реорганизацию или перестроение) индексов для таблиц базы данных 1С.

Как только статистика СУБД обновится, оптимизатор начнет правильно использовать индексы, и актуализация расчетов перед печатью будет выполняться за миллисекунды.

Очистка регистра заданий к распределению

Проанализируем состояние регистра сведений ЗаданияКРаспределениюРасчетовСКлиентами. Если в нем скопились тысячи старых зависших записей (например, с пустыми документами), их необходимо удалить. Вы можете создать простую внешнюю обработку с таким кодом:


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

После очистки "битых" записей регламентное задание начнет работать штатно и перестанет мешать пользователям в момент печати документов.

Программное отключение актуализации при печати (через расширение)

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

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

← На главную