Почему отчет «Задолженность клиентов по срокам» в УТ 11 формируется слишком долго и как это исправить?

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

Многие технические специалисты, работающие с конфигурациями 1С:Управление торговлей 11 (особенно версий 11.1, 11.2 и ранних 11.3), 1С:Комплексная автоматизация 2 или 1С:ERP, сталкиваются с проблемой: стандартный отчет «Задолженность клиентов по срокам» начинает формироваться крайне медленно. На крупных базах время ожидания может составлять несколько часов, а иногда процесс и вовсе завершается аварийно из-за нехватки памяти или переполнения TempDB на SQL-сервере.

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

Разберем причину: где скрывается «узкое место»?

Проблема кроется в алгоритме распределения авансов и оплат по документам отгрузки, который выполняется «на лету» в момент формирования отчета. Рассмотрим ситуацию: отчет строится на данных двух основных регистров накопления: РасчетыСКлиентами (общие остатки) и РасчетыСКлиентамиПоДокументам (детализация до конкретных накладных).

В модуле отчета вызывается функция ПолучитьТаблицуПлатежей, которая, в свою очередь, обращается к процедуре РассчитатьДатыПлатежаКлиента в общем модуле ВзаиморасчетыСервер. Основной «мазохизм» (как выразился автор темы) заключается в использовании цикла, внутри которого постоянно выполняется запрос к менеджеру временных таблиц.

Проанализируем фрагмент этого кода:


Результат = Запрос.Выполнить;
Счетчик = 0;
Пока Не Результат.Пустой Цикл
    Результат = Запрос.Выполнить;
    // Внутри этого цикла система пытается сопоставить остатки
    // и «вымыть» задолженность по алгоритму FIFO/LIFO
КонецЦикла;

Система создает временную таблицу ТаблицаОстатковКлиентов и начинает итерационно распределять суммы. Если у клиента накопилось огромное количество мелких документов, незакрытых копеечных остатков или возник «перекос» между регистрами (сумма по документам не сходится с общим итогом), количество итераций этого цикла начинает расти в геометрической прогрессии. С каждой новой итерацией менеджер временных таблиц разрастается, и SQL-серверу становится всё сложнее обрабатывать запросы.

Выясним причины замедления: «мусор» в данных и отсутствие индексов

Рассмотрим подробнее технические аспекты, которые заставляют этот код работать часами:

  1. Наличие нулевых остатков: Часто в регистре РасчетыСКлиентамиПоДокументам зависают записи, где СуммаОстаток равна нулю, но КОплатеОстаток или КОтгрузкеОстаток имеют ненулевые значения. Отчет пытается учесть эти «хвосты», что порождает лишние витки цикла.
  2. Отсутствие индексации во временных таблицах: Как видно из листинга кода типовой процедуры, временные таблицы индексируются не на каждом этапе. Когда объем данных велик, ЛЕВОЕ СОЕДИНЕНИЕ между неиндексированными временными таблицами убивает производительность.
  3. Отложенные движения: В УТ 11 используется механизм отложенного расчета взаиморасчетов. Если регламентное задание «Выполнение отложенных движений по расчетам с клиентами» не отработало или в нем возникли ошибки, отчет пытается выполнить эти расчеты самостоятельно в основном потоке, что крайне ресурсозатратно.

Способ 1: Оптимизация на уровне данных (гигиена регистров)

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

  1. Закрытие старых заказов: Проверьте наличие старых заказов клиентов со статусами, отличными от «Закрыт». Рекомендуем принудительно закрыть все заказы прошлых периодов, по которым нет реальных долгов. Это уменьшит количество аналитик, которые перебирает запрос.
  2. Корректировка задолженности: Воспользуйтесь обработкой Корректировка задолженности, чтобы «схлопнуть» встречные авансы и долги. Чем меньше строк в остатках регистров, тем быстрее отработает цикл распределения.
  3. Проверка итогов: Выполните в конфигураторе процедуру Тестирование и исправление с флагом Пересчет итогов. Иногда неверные итоги заставляют алгоритм FIFO «бесконечно» искать документы для распределения.

Способ 2: Техническая оптимизация кода (для программистов)

Если данные в порядке, а отчет всё равно тормозит, перейдем к модификации кода процедуры РассчитатьДатыПлатежаКлиента. Рассмотрим шаги, которые помогут ускорить процесс:

Добавление индексов. Во всех местах, где создаются промежуточные временные таблицы (например, ТаблицаОстатковКлиентов, НовыеОстаткиКлиентов), необходимо добавить явное индексирование по ключевым полям: АналитикаУчетаПоПартнерам, ЗаказКлиента, Валюта.

Пример добавления индекса в коде:


|ПОМЕСТИТЬ ТаблицаОстатковКлиентов
|ИЗ
| НовыеОстаткиКлиентов КАК Остатки
|ИНДЕКСИРОВАТЬ ПО
| АналитикаУчетаПоПартнерам,
| ЗаказКлиента,
| Валюта
|;

Ограничение итераций. В более свежих версиях программ (например, в КА 2.4 для Казахстана) разработчики 1С добавили ограничение счетчика цикла (например, до 1000 итераций). Это не решает проблему производительности полностью, но предотвращает «зацикливание» и бесконечный рост TempDB. Можно внедрить аналогичный предохранитель самостоятельно.

Способ 3: Переход на «Взаиморасчеты онлайн»

Важно понимать, что в версиях УТ 11.4 и выше архитектура взаиморасчетов была кардинально пересмотрена. 1С отказалась от сложного распределения «на лету» в пользу новой модели «Взаиморасчеты онлайн». В этой модели данные о сроках задолженности и датах платежа хранятся в готовом виде в специализированных регистрах (например, ПлановыеОплатыКлиентов).

Если ваша конфигурация позволяет, рассмотрим возможность включения опции Взаиморасчеты онлайн (НСИ и администрирование -> Казначейство и взаиморасчеты). Это потребует перепроведения документов, но навсегда устранит проблему медленного формирования отчетов по дебиторке.

Резюме

Проанализировав ситуацию, мы видим, что отчет «Задолженность клиентов по срокам» — это один из самых тяжелых узлов старой архитектуры УТ 11. Чтобы ускорить его работу, мы рекомендуем придерживаться следующего плана:

← На главную