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

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

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

Как документ перемещения формирует движения в регистрах накопления

Проанализируем механику работы документа ПеремещениеТоваров в типовых конфигурациях (например, 1С:Управление торговлей). При проведении документа в регистре накопления ТоварыНаСкладах (а также в партионных регистрах, таких как ПартииТоваровНаСкладах) формируются две отдельные записи:

  1. Расход — списание количества со склада-отправителя (ВидДвиженияНакопления.Расход).
  2. Приход — оприходование аналогичного количества на склад-получатель (ВидДвиженияНакопления.Приход).

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

Ошибки исходного подхода: почему нельзя читать физические таблицы

Рассмотрим типичные ошибки при ручном расчете остатков и оборотов:

  1. Чтение реальных таблиц документов и регистров: выборка из табличных частей Документ.РеализацияТоваровУслуг.Товары или прямая выборка из таблицы движений РегистрНакопления.ТоварыНаСкладах приводит к игнорированию итогов, замедлению работы базы данных и ошибкам при наличии нескольких складов в одном документе.
  2. Поиск цен вручную: срез цен через группировку по максимальной дате работает медленно и неэффективно по сравнению со срезом последних.
  3. Множественные запросы в цикле: выгрузка во временные таблицы значений и поиск методом Найти() внутри цикла вывода макета создают избыточную нагрузку на сервер.

Правильный подход: использование виртуальной таблицы «ОстаткиИОбороты»

Для корректного получения начального остатка, прихода, расхода и конечного остатка по каждому складу следует использовать виртуальную таблицу РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты. Платформа 1С автоматически рассчитывает итоги и распределяет расход склада-отправителя и приход склада-получателя.

Если в отчете требуется выделить перемещения в отдельные колонки (отделив их от обычных закупок и продаж), используем конструкцию с условием ВЫБОР КОГДА и периодичностью по регистратору:


ВЫБРАТЬ
	ТоварыНаСкладах.Склад КАК Склад,
	ТоварыНаСкладах.Номенклатура КАК Номенклатура,
	ТоварыНаСкладах.КоличествоНачальныйОстаток КАК НачальныйОстаток,
	ВЫБОР
		КОГДА ТоварыНаСкладах.Регистратор ССЫЛКА Документ.ПоступлениеТоваровУслуг
			ТОГДА ТоварыНаСкладах.КоличествоПриход
		ИНАЧЕ 0
	КОНЕЦ КАК ПриходПоставщик,
	ВЫБОР
		КОГДА ТоварыНаСкладах.Регистратор ССЫЛКА Документ.ПеремещениеТоваров
			ТОГДА ТоварыНаСкладах.КоличествоПриход
		ИНАЧЕ 0
	КОНЕЦ КАК ПриходПеремещение,
	ВЫБОР
		КОГДА ТоварыНаСкладах.Регистратор ССЫЛКА Документ.ПеремещениеТоваров
			ТОГДА ТоварыНаСкладах.КоличествоРасход
		ИНАЧЕ 0
	КОНЕЦ КАК РасходПеремещение,
	ВЫБОР
		КОГДА ТоварыНаСкладах.Регистратор ССЫЛКА Документ.РеализацияТоваровУслуг
			ТОГДА ТоварыНаСкладах.КоличествоРасход
		ИНАЧЕ 0
	КОНЕЦ КАК Продажи,
	ТоварыНаСкладах.КоличествоКонечныйОстаток КАК КонечныйОстаток
ИЗ
	РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(
			&НачПериода,
			&КонПериода,
			Авто,
			,
			) КАК ТоварыНаСкладах

Как работает вывод данных и метод «Заполнить()» в макете

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

  1. Явное присвоение параметров: когда имена колонок выборки не совпадают с именами параметров в макете.
    
    ОбластьДанные = Макет.ПолучитьОбласть("Строка");
    ОбластьДанные.Параметры.Склад = Выборка.Склад;
    ОбластьДанные.Параметры.КоличествоПриход = Выборка.ПриходПоставщик;
    ТабДок.Вывести(ОбластьДанные);
    
  2. Использование метода Заполнить(): метод ОбластьДанные.Параметры.Заполнить(Выборка) сопоставляет имена параметров области макета с именами полей в переданной выборке или структуре. Если имя параметра в ячейке макета в точности совпадает с псевдонимом поля в запросе (например, Склад, ПриходПеремещение, КонечныйОстаток), значение подставляется автоматически без ручного написания строк присвоения.

Важный момент: если вы добавляете в запрос новое поле (например, выделенное перемещение), убедитесь, что в макете создан параметр ячейки с точно таким же именем, либо явно передайте его значение перед вызовом ТабДок.Вывести().

← На главную