В процессе эксплуатации систем на базе 1С:ERP Управление предприятием часто возникает необходимость создания кастомных отчетов для анализа дебиторской задолженности. Однако нередко программисты сталкиваются с тем, что данные в таких отчетах расходятся с типовой Оборотно-сальдовой ведомостью (ОСВ) по счету 62.01. В данной статье мы подробно разберем, почему возникают такие расхождения, проанализируем структуру запроса и выясним, как правильно обрабатывать специфические документы, такие как Сторно и Отчет давальцу.
Рассмотрим ситуацию: в самописном отчете сумма задолженности по конкретному контрагенту в два раза превышает сумму, указанную в ОСВ по счету 62.01. При детальном изучении выясняется, что в отчет попадают два документа Отчет давальцу, хотя по логике бухгалтерского учета один из них должен был быть исключен или сторнирован. Наша задача — разобраться, как работает механизм расчета задолженности в запросе и где кроется техническая ошибка.
Проанализируем программный код запроса, который используется для формирования отчета. Запрос состоит из нескольких пакетов временных таблиц. Первый пакет ВТ_Долг получает остатки по счету из виртуальной таблицы РегистрБухгалтерии.Хозрасчетный.Остатки.
ВЫБРАТЬ
ХозрасчетныйОстатки.Субконто1 КАК Контрагент,
ХозрасчетныйОстатки.Субконто2 КАК Договор,
ХозрасчетныйОстатки.СуммаОстатокДт КАК СуммаЗадолженности,
ХозрасчетныйОстатки.Счет КАК Счет
ПОМЕСТИТЬ ВТ_Долг
ИЗ
РегистрБухгалтерии.Хозрасчетный.Остатки(&Дата2, , ,
Субконто1 ССЫЛКА Справочник.Контрагенты
И Субконто2 ССЫЛКА Справочник.ДоговорыКонтрагентов) КАК ХозрасчетныйОстатки
На этом этапе мы получаем корректное сальдо. Проблема начинается в последующих пакетах, где разработчик пытается распределить этот общий долг по конкретным документам-регистраторам, используя алгоритм, похожий на FIFO (First In, First Out). Для этого во второй таблице ВТ_Документы собираются все движения (обороты по дебету), которые теоретически могли сформировать этот долг.
Рассмотрим пакет ВТ_Попорядку. Здесь используется внутреннее соединение таблицы документов самой с собой для вычисления поля СуммаПосле. Это поле должно содержать сумму всех документов, которые возникли после текущего документа, чтобы понять, покрывает ли текущий остаток задолженности данный конкретный регистратор.
Важный технический момент: в коде используется сравнение по полю Номер:
КОГДА а.Период = ДокументыПосле.Период И а.Номер >= ДокументыПосле.Номер
ТОГДА 0
Выясним причину, почему это плохо. В системе 1С поле Номер является строковым. Сравнение строк происходит посимвольно. Кроме того, у разных типов документов (например, РеализацияТоваровУслуг и ОтчетДавальцу) нумерация независимая. Если два документа попали в одну секунду (одинаковый Период), сравнение по номеру может выдать непредсказуемый результат. В нашем случае это приводит к тому, что условие соединения срабатывает некорректно, и суммы начинают дублироваться.
Проанализируем ситуацию с документом Сторно. Если бухгалтер сторнировал документ Отчет давальцу, то в регистре бухгалтерии появляются записи с отрицательными суммами или обратными знаками, но с сохранением аналитики. Если в запросе к таблице ДвиженияССубконто не установлена фильтрация по признаку Активность или не учитывается знак суммы, алгоритм распределения задолженности "ломается".
Когда в выборку попадает и основной документ, и его сторно, запрос в блоке СУММА(ВЫБОР...) может ошибочно посчитать их как два независимых события, увеличивающих или уменьшающих "очередь" долга. Чтобы исправить это, необходимо предварительно "схлопывать" сторнируемые записи с их исправлениями в отдельной временной таблице до того, как начинать расчет накопительного итога.
Для того чтобы привести самодельный отчет в соответствие с ОСВ, рекомендуем придерживаться следующего алгоритма действий:
РасчетыСКлиентами. Проверьте типовой отчет "Ведомость расчетов с клиентами". Если там сумма совпадает с ОСВ, а в вашем отчете нет — проблема в запросе. Если же и в типовом отчете сумма не совпадает с ОСВ, значит, была введена "ручная операция" (документ ОперацияБух), которая сделала проводку по 62 счету, но не сделала движений по регистрам накопления.Период + Номер для упорядочивания документов в запросе всегда используйте МоментВремени. В запросах это реализуется через поле Период и Ссылка. Это гарантирует уникальную последовательность документов даже внутри одной секунды.СуммаОстатокДт. Если по договору висит аванс на 62.02, то общая дебиторская задолженность по контрагенту (сальдо по 62 счету в целом) будет меньше, чем сумма по 62.01. Убедитесь, что логика отчета соответствует требованиям бизнеса: нужно ли им видеть "чистый" долг или долг за минусом авансов.Рассмотрим, как можно изменить логику формирования накопительной суммы, чтобы избежать задвоений. Вместо использования ВНУТРЕННЕЕ СОЕДИНЕНИЕ, которое при больших объемах данных работает крайне медленно, в современных версиях 1С можно использовать оконные функции (если версия платформы позволяет) или более строгую группировку.
Посмотрим на пример правильного условия для соединения в пакете расчета очереди:
ПО а.Счет = ДокументыПосле.Счет
И а.Контрагент = ДокументыПосле.Контрагент
И а.Договор = ДокументыПосле.Договор
И (а.Период < ДокументыПосле.Период
ИЛИ (а.Период = ДокументыПосле.Период И а.Регистратор < ДокументыПосле.Регистратор))
Здесь сравнение а.Регистратор < ДокументыПосле.Регистратор работает со ссылками, что в рамках одной секунды позволяет однозначно определить последовательность записей в базе данных и исключить ситуацию, когда один и тот же документ соединяется сам с собой несколько раз в разных условиях.
Выявление расхождений в отчетах по счету 62 требует комплексного подхода: от аудита бухгалтерских проводок до глубокого анализа логики запроса. Помните, что 1С:ERP — это система с приоритетом оперативного учета. Использование только регистра бухгалтерии для сложных отчетов по задолженности часто чревато ошибками, связанными с ручными корректировками и спецификой проведения документов. Всегда проверяйте активность записей и используйте корректные методы упорядочивания данных в запросах.