При разработке отчетов по взаиморасчетам программисты часто сталкиваются с ситуацией, когда поле «Сумма долга на начало» отображается некорректно или остается пустым, если в выбранном периоде по конкретному документу не было движений. Особенно это актуально для самописных регистров, где необходимо отслеживать оплату каждой конкретной сделки (реализации). В этой статье мы подробно разберем, как работает механизм получения остатков, проанализируем ошибки в построении запросов и научимся правильно использовать возможности платформы 1С.
Рассмотрим ситуацию: у нас есть документ «Реализация ТМЗ» от 01.12.2020. Пользователь формирует отчет за период с 02.12.2020 по 31.12.2020. Несмотря на то что долг по реализации не погашен, в колонке «Начальный остаток» программа выдает 0. Почему так происходит? Выясним причину, изучив логику работы виртуальных таблиц.
Основная ошибка заключается в попытке «ручного» соединения списка документов с таблицей регистра. Если мы сначала выбираем документы РеализацияТоваровУслуг, которые попали в период отчета, а затем пытаемся соединить их с остатками, то документы, созданные до начала периода, просто не попадут в выборку. Следовательно, остатки по ним не будут отображены.
Для решения задачи нам не нужно объединять таблицы документов и регистров вручную. Платформа 1С предоставляет мощный инструмент — виртуальную таблицу ОстаткиИОбороты регистра накопления. Разберем по шагам, как правильно составить запрос к этой таблице.
Виртуальная таблица ОстаткиИОбороты сама умеет рассчитывать начальный остаток на любую дату, указанную в параметрах. Нам достаточно передать в нее &НачалоПериода и &КонецПериода. Проанализируем пример правильного обращения к регистру:
ВЫБРАТЬ
ВзаиморасчетыОстаткиИОбороты.Контрагент КАК Контрагент,
ВзаиморасчетыОстаткиИОбороты.ДокументОснование КАК ДокументОснование,
ВзаиморасчетыОстаткиИОбороты.СуммаНачальныйОстаток КАК ДолгНаНачало,
ВзаиморасчетыОстаткиИОбороты.СуммаПриход КАК УвеличениеДолга,
ВзаиморасчетыОстаткиИОбороты.СуммаРасход КАК ПогашениеДолга,
ВзаиморасчетыОстаткиИОбороты.СуммаКонечныйОстаток КАК ДолгНаКонец
ИЗ
РегистрНакопления.КонтрольДолга.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, Авто, , ) КАК ВзаиморасчетыОстаткиИОбороты
В данном случае поле СуммаНачальныйОстаток будет содержать сумму долга на 00:00:00 даты начала периода. Если реализация была 01.12.2020, а отчет строится со 02.12.2020, система автоматически возьмет итоги на границу периода и покажет актуальный долг.
Часто заказчик требует расшифровать, какими именно документами (ПКО, Платежное поручение, Возврат) закрывался долг. Для этого в параметрах виртуальной таблицы необходимо указать периодичность Авто или Регистратор. Однако здесь кроется подвох: если по документу-основанию не было движений в текущем периоде, но есть остаток, при использовании периодичности Регистратор такая строка может пропасть из детальных записей, если не настроены роли полей в СКД.
Посмотрим на пример обработки различных типов документов оплаты прямо в запросе для наглядности отчета:
ВЫБРАТЬ
Взаиморасчеты.ДокументОснование КАК Реализация,
Взаиморасчеты.Регистратор КАК ДокументДвижения,
ВЫБОР
КОГДА ТИПЗНАЧЕНИЯ(Взаиморасчеты.Регистратор) = ТИП(Документ.ПриходныйКассовыйОрдер)
ТОГДА Взаиморасчеты.СуммаРасход
ИНАЧЕ 0
КОНЕЦ КАК ОплатаНаличными,
ВЫБОР
КОГДА ТИПЗНАЧЕНИЯ(Взаиморасчеты.Регистратор) = ТИП(Документ.ВозвратТоваровОтПокупателя)
ТОГДА Взаиморасчеты.СуммаРасход
ИНАЧЕ 0
КОНЕЦ КАК СуммаВозврата
ИЗ
РегистрНакопления.КонтрольДолга.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, Авто, , ) КАК Взаиморасчеты
Обратите внимание, что использование ЛЕВОЕ СОЕДИНЕНИЕ с таблицей документов, как делал автор темы, излишне нагружает систему. Все необходимые данные (Контрагент, Организация, Сумма) уже должны содержаться в измерениях и ресурсах регистра накопления.
Если вы используете Систему компоновки данных (СКД), важно правильно настроить закладку «Роли» для полей остатков. Без этого СКД не сможет корректно «растянуть» начальный остаток по группировкам или вывести его для тех периодов, где не было оборотов.
СуммаНачальныйОстаток установите роль «Остатки», тип «Начальный». Укажите имя соответствующего поля конечного остатка.СуммаКонечныйОстаток установите роль «Остатки», тип «Конечный».Регистратор или ПериодДень) обязательно укажите роль «Период» с соответствующим номером (1, 2 и т.д.).Проанализируем ситуацию с отрицательными остатками. Если сумма оплат (Расход) превысила сумму реализации (Приход), то начальный остаток в следующем периоде будет отрицательным. В управленческом учете это интерпретируется как аванс или переплата. Чтобы отчет был понятным для бухгалтера, такие суммы иногда разделяют на «Дебиторскую» и «Кредиторскую» задолженность, используя функции ВЫБОР КОГДА.
Подведем итог. Чтобы поле «Сумма долга на начало» всегда заполнялось корректно:
ОстаткиИОбороты в качестве основного источника данных.&НачалоПериода и &КонецПериода непосредственно в виртуальную таблицу, а не фильтруйте результат в секции ГДЕ.Помните, что поле начального остатка в виртуальной таблице — это не просто значение из базы, а результат вычисления системы на конкретный момент времени. Правильное понимание границ периодов в 1С (использование объекта Граница при программном вызове) позволит вам избежать ошибок в расчетах даже в самых сложных отчетах.