Как правильно получить фактический остаток долга клиента из регистра «Расчеты с клиентами по срокам» в 1С

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

При разработке отчетов, выгрузок или кастомных механизмов в конфигурациях 1С:ERP, 1С:Комплексная автоматизация 2 или 1С:Управление торговлей 11 разработчики часто сталкиваются с задачей получения реального долга покупателя. Попытка написать простой запрос к виртуальной таблице остатков регистра накопления РасчетыСКлиентамиПоСрокам «в лоб» часто приводит к неожиданным результатам. Запрос может возвращать две строки по одному контрагенту, задваивать суммы или показывать долг без учета уплаченного клиентом аванса.

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

Выясняем причину: почему двоятся или не сходятся суммы?

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

Выделим три основные причины, по которым простой запрос может возвращать неверные данные:

  1. Разделение ресурсов на «Долг» и «Предоплату». В регистре РасчетыСКлиентамиПоСрокам нет одного универсального поля сальдо. Вместо этого в нем разделены два ключевых состояния: ресурс ДолгОстаток (дебиторская задолженность клиента перед нами) и ресурс ПредоплатаОстаток (наш долг перед клиентом, то есть полученный аванс). Если по контрагенту одновременно есть и отгрузка, и аванс, система вернет обе эти суммы.
  2. Влияние измерения «Объект расчетов». В ERP-системах взаиморасчеты ведутся с высокой детализацией — в разрезе договоров, заказов или конкретных накладных. Это измерение называется ОбъектРасчетов. Если по одному заказу клиент внес предоплату, а по другому у него возник долг, и при этом в системе еще не выполнена регламентная операция зачета оплат, виртуальная таблица остатков вернет две разные строки по этим объектам расчетов.
  3. Накладывание условий в секции ГДЕ. Это классическая ошибка при работе с виртуальными таблицами 1С. Если мы пишем условие по контрагенту или партнеру в секции ГДЕ, система сначала рассчитывает остатки по абсолютно всем аналитикам (включая все объекты расчетов всех контрагентов базы данных), а уже потом фильтрует результат. Это приводит к колоссальным потерям производительности и дублированию строк из-за разной детальной аналитики.

Рассмотрим, как пошагово исправить эти ошибки и составить корректный запрос.

Шаг 1. Переносим отборы в параметры виртуальной таблицы

Проанализируем типичный некорректный запрос, который часто пишут на начальном этапе:


ВЫБРАТЬ
    РасчетыСКлиентамиПоСрокамОстатки.ДолгОстаток КАК ДолгОстаток
ИЗ
    РегистрНакопления.РасчетыСКлиентамиПоСрокам.Остатки КАК РасчетыСКлиентамиПоСрокамОстатки
ГДЕ
    РасчетыСКлиентамиПоСрокамОстатки.АналитикаУчетаПоПартнерам.Партнер = &Контрагент

Этот запрос не только работает медленно, но и возвращает неверные результаты, так как он не группирует данные по контрагенту в целом, а выгружает их с детализацией до внутренних ключей аналитики. Нам необходимо перенести отбор непосредственно в параметры виртуальной таблицы остатков. При этом важно понимать разницу между Партнером и Контрагентом.

В современных конфигурациях 1С используется разделение на управленческий учет (справочник Партнеры) и регламентированный учет (справочник Контрагенты). Измерение АналитикаУчетаПоПартнерам хранит в себе ключ, который связывает обе эти сущности. Если наша задача — получить долг конкретного юридического лица, мы должны наложить отбор именно на реквизит Контрагент внутри этого ключа аналитики:

&ПараметрОтбора = АналитикаУчетаПоПартнерам.Контрагент = &Контрагент

Шаг 2. Сальдируем долг и предоплату

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

Математически формула выглядит следующим образом:

Фактический долг = ДолгОстаток - ПредоплатаОстаток

Если полученное значение больше нуля — это чистый долг клиента перед нами. Если значение меньше нуля — это наша задолженность перед клиентом (переплата/аванс).

Шаг 3. Исключаем лишние измерения и группируем данные

Поскольку остатки в регистре хранятся в разрезе объектов расчетов, нам необходимо «схлопнуть» эти данные. Для этого мы не будем выбирать измерение ОбъектРасчетов в секции ВЫБРАТЬ, а применим агрегатную функцию СУММА ко всей нашей выборке. Это позволит сложить все долги и вычесть все авансы по всем сделкам контрагента, выдав единое итоговое число.

Разберем готовое решение.

Готовое решение: корректный запрос для получения фактического долга

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


ВЫБРАТЬ
    ЕСТЬNULL(СУММА(ВзаиморасчетыОстатки.ДолгОстаток - ВзаиморасчетыОстатки.ПредоплатаОстаток), 0) КАК ФактическийДолг
ИЗ
    РегистрНакопления.РасчетыСКлиентамиПоСрокам.Остатки(
        &Период,
        АналитикаУчетаПоПартнерам.Контрагент = &Контрагент
            И АналитикаУчетаПоПартнерам.Организация = &Организация
    ) КАК ВзаиморасчетыОстатки

Рассмотрим подробнее особенности этого запроса:

Важный нюанс: регламентные задания по проведению взаиморасчетов

Даже если ваш запрос написан абсолютно верно, вы можете столкнуться с ситуацией, когда данные в отчете расходятся с тем, что вы видите в первичных документах. В 1С:ERP и 1С:Комплексная автоматизация используется механизм отложенных расчетов.

Это означает, что при проведении документов (например, накладной или платежного поручения) фактические движения по регистру РасчетыСКлиентамиПоСрокам могут записываться в упрощенном (плановом) виде, а окончательное распределение оплат по объектам расчетов происходит в фоновом режиме.

Чтобы ваши запросы всегда возвращали актуальную информацию, убедитесь в следующем:

  1. В базе данных настроено и регулярно выполняется регламентное задание «Выполнение отложенных движений по расчетам с клиентами».
  2. При ручной проверке данных перед выполнением запроса была запущена обработка «Проведение документов по расчетам с клиентами» (ее можно найти в разделе закрытия месяца).

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

← На главную