Как построить отчет по остаткам номенклатуры с распределением по интервалам хранения в 1С?

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

При анализе складских запасов часто возникает задача построения отчета по старению номенклатуры (срокам хранения). Требуется вывести текущие остатки и суммы, распределив их по нескольким интервалам давности — например, «До 30 дней», «От 30 до 90 дней» и «Более 90 дней» (или по месяцам/кварталам).

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

Типичная ошибка: объединение срезов остатков на разные даты

Часто разработчики пытаются решить задачу простым объединением нескольких запросов к виртуальной таблице Остатки на даты 30, 90 и более дней назад. Выясним причину, почему этот подход неверен:

  1. Срез остатков на прошлую дату показывает общее состояние склада на тот момент, а не то, сколько дней лежит на складе текущий остаток товара.
  2. Если товар лежал на складе 90 дней назад, но 10 дней назад его полностью продали и привезли новую партию, срез на прошлую дату ошибочно посчитает старые данные, хотя на складе находится свежий товар.

Для корректного отчета по старению необходимо анализировать возраст конкретных остатков на текущую дату отчета.

Вариант 1. Партионный учет (в регистре есть измерение «Партия» или «ДокументОприходования»)

Рассмотрим наиболее распространенный и производительный вариант, когда в регистре накопления (например, ПартииУправленческогоУчета или ПартииТоваровНаСкладах) ведется учет по партиям или документам поступления.

В этом случае нам достаточно получить остатки на дату отчета, взять дату партии и вычислить количество дней между датой партии и датой формирования отчета с помощью функции РАЗНОСТЬДАТ.

Посмотрим на пример текста запроса для набора данных СКД:


ВЫБРАТЬ
	ПартииОстатки.Номенклатура КАК Номенклатура,
	ПартииОстатки.Партия КАК Партия,
	ПартииОстатки.КоличествоОстаток КАК Количество,
	ПартииОстатки.СуммаОстаток КАК Сумма,
	ВЫБОР
		КОГДА ПартииОстатки.Партия.Дата ЕСТЬ NULL ИЛИ ПартииОстатки.Партия.Дата = ДАТАВРЕМЯ(1, 1, 1)
			ТОГДА "4. Без даты"
		КОГДА РАЗНОСТЬДАТ(ПартииОстатки.Партия.Дата, &Период, ДЕНЬ) <= 30
			ТОГДА "1. До 30 дней"
		КОГДА РАЗНОСТЬДАТ(ПартииОстатки.Партия.Дата, &Период, ДЕНЬ) <= 90
			ТОГДА "2. От 30 до 90 дней"
		ИНАЧЕ "3. Свыше 90 дней"
	КОНЕЦ КАК Интервал
ИЗ
	РегистрНакопления.ПартииУправленческогоУчёта.Остатки(&Период, ) КАК ПартииОстатки

Также вычисление интервала можно вынести на вкладку Вычисляемые поля в СКД. Для этого в выражении поля указываем формулу:


Выбор 
	Когда РазностьДат(Партия.Дата, &Период, "ДЕНЬ") <= 30 Тогда "1. До 30 дней"
	Когда РазностьДат(Партия.Дата, &Период, "ДЕНЬ") <= 90 Тогда "2. От 30 до 90 дней"
	Иначе "3. Свыше 90 дней" 
Конец

Вариант 2. Партионный учет не ведется (распределение по ФИФО)

Если в регистре отсутствует измерение партии и остатки хранятся только в разрезе номенклатуры и складов, применяется алгоритм обратного распределения остатка по принципу ФИФО:

  1. Запрашиваются актуальные остатки номенклатуры на дату отчета.
  2. Выбираются документы поступления товаров в обратном хронологическом порядке (от даты отчета вглубь истории).
  3. Текущий остаток последовательно закрывается последними поступлениями:
    1. Количество, покрытое приходами за последние 30 дней, относится к интервалу «1. До 30 дней».
    2. Количество, покрытое приходами в промежутке от 30 до 90 дней назад, попадает в «2. От 30 до 90 дней».
    3. Непокрытый остаток (поступивший более 90 дней назад либо входящее сальдо) относится к интервалу «3. Свыше 90 дней».

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

Настройка структуры отчета в СКД

Разберем по шагам, как настроить отображение данных в виде кросс-таблицы:

  1. Переходим на вкладку Ресурсы и добавляем поля Количество и Сумма с функцией Сумма(Количество) и Сумма(Сумма).
  2. Переходим на вкладку Настройки. В окне структуры отчета добавляем элемент Таблица.
  3. В ветку Строки таблицы добавляем группировку Номенклатура (при необходимости с иерархией).
  4. В ветку Колонки таблицы добавляем группировку Интервал.
  5. В состав выбранных полей таблицы добавляем ресурсы Количество и Сумма.
  6. На вкладке Сортировка для группировки колонок задаем сортировку по полю Интервал (по возрастанию). Нумерация в названиях интервалов («1.», «2.», «3.») гарантирует правильный порядок колонок слева направо.

Важные нюансы и краевые случаи

  1. Точность параметра даты: Для виртуальной таблицы Остатки значение параметра &Период рекомендуется устанавливать на конец дня (например, через выражение параметра КонецПериода(&Период, "ДЕНЬ")), чтобы движения за текущую дату корректно попадали в расчет.
  2. Пустые значения партий: Если документ партии не заполнен или создан вручную без даты, функция РАЗНОСТЬДАТ вернет неверное или пустое значение. В запросе обязательно нужно обрабатывать условие Партия.Дата ЕСТЬ NULL.
  3. Отрицательные остатки: При наличии пересортицы или списаний в минус остатки могут исказить распределение по колонкам, поэтому отрицательные позиции целесообразно контролировать в отборе отчета.
← На главную