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

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

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

Анализ исходной задачи и типичные ошибки

Рассмотрим типовую ситуацию: разработчик пытается получить последние движения по регистру СебестоимостьТоваров, упорядочивая выборку по дате и используя группировки. Если ограничиться конструкцией ВЫБРАТЬ ПЕРВЫЕ 1, запрос корректно отработает только для одной конкретной номенклатуры, переданной в параметрах. При попытке получить срез по массиву или справочнику целиком такой подход не сработает.

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

Способ 1. Пакетный запрос с временной таблицей максимальных дат

Классический и наиболее универсальный метод для платформы 1С:Предприятие заключается в использовании двух шагов в рамках одного запроса:

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

Посмотрим на пример реализации такого пакетного запроса:


ВЫБРАТЬ
	СебестоимостьТоваров.АналитикаУчетаНоменклатуры.Номенклатура КАК Номенклатура,
	МАКСИМУМ(СебестоимостьТоваров.Период) КАК МаксПериод
ПОМЕСТИТЬ ВТ_МаксимальныеДаты
ИЗ
	РегистрНакопления.СебестоимостьТоваров КАК СебестоимостьТоваров
ГДЕ
	СебестоимостьТоваров.Количество > 0
	И СебестоимостьТоваров.Регистратор ССЫЛКА Документ.ПриобретениеТоваровУслуг
СГРУППИРОВАТЬ ПО
	СебестоимостьТоваров.АналитикаУчетаНоменклатуры.Номенклатура
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ВТ_МаксимальныеДаты.Номенклатура КАК Номенклатура,
	СебестоимостьТоваров.Регистратор КАК Регистратор,
	СебестоимостьТоваров.Количество КАК Количество,
	СебестоимостьТоваров.Стоимость КАК СтоимостьУпр,
	СебестоимостьТоваров.СтоимостьРегл КАК СтоимостьРегл,
	ВЫБОР
		КОГДА СебестоимостьТоваров.Количество > 0
			ТОГДА СебестоимостьТоваров.Стоимость / СебестоимостьТоваров.Количество
		ИНАЧЕ 0
	КОНЕЦ КАК ЦенаУпр,
	ВЫБОР
		КОГДА СебестоимостьТоваров.Количество > 0
			ТОГДА СебестоимостьТоваров.СтоимостьРегл / СебестоимостьТоваров.Количество
		ИНАЧЕ 0
	КОНЕЦ КАК ЦенаРегл
ИЗ
	ВТ_МаксимальныеДаты КАК ВТ_МаксимальныеДаты
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.СебестоимостьТоваров КАК СебестоимостьТоваров
		ПО ВТ_МаксимальныеДаты.Номенклатура = СебестоимостьТоваров.АналитикаУчетаНоменклатуры.Номенклатура
			И ВТ_МаксимальныеДаты.МаксПериод = СебестоимостьТоваров.Период
ГДЕ
	СебестоимостьТоваров.Количество > 0
	И СебестоимостьТоваров.Регистратор ССЫЛКА Документ.ПриобретениеТоваровУслуг

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

Способ 2. Использование оконных функций (для платформы 8.3.20 и выше)

В современных версиях платформы 1С:Предприятие доступен механизм оконных функций. С его помощью задача решается без создания дополнительных временных таблиц и соединений через функцию ROW_NUMBER().

Разберем пример запроса с оконной функцией:


ВЫБРАТЬ
	Себестоимость.Номенклатура КАК Номенклатура,
	Себестоимость.Регистратор КАК Регистратор,
	Себестоимость.Количество КАК Количество,
	Себестоимость.ЦенаУпр КАК ЦенаУпр,
	Себестоимость.ЦенаРегл КАК ЦенаРегл
ИЗ
	(ВЫБРАТЬ
		СебестоимостьТоваров.АналитикаУчетаНоменклатуры.Номенклатура КАК Номенклатура,
		СебестоимостьТоваров.Регистратор КАК Регистратор,
		СебестоимостьТоваров.Количество КАК Количество,
		ВЫБОР
			КОГДА СебестоимостьТоваров.Количество > 0
				ТОГДА СебестоимостьТоваров.Стоимость / СебестоимостьТоваров.Количество
			ИНАЧЕ 0
		КОНЕЦ КАК ЦенаУпр,
		ВЫБОР
			КОГДА СебестоимостьТоваров.Количество > 0
				ТОГДА СебестоимостьТоваров.СтоимостьРегл / СебестоимостьТоваров.Количество
			ИНАЧЕ 0
		КОНЕЦ КАК ЦенаРегл,
		ROW_NUMBER() OVER(
			ПАРТИЦИЯ ПО СебестоимостьТоваров.АналитикаУчетаНоменклатуры.Номенклатура
			УПОРЯДОЧИТЬ ПО СебестоимостьТоваров.Период УБЫВ, СебестоимостьТоваров.Регистратор УБЫВ
		) КАК НомерСтроки
	ИЗ
		РегистрНакопления.СебестоимостьТоваров КАК СебестоимостьТоваров
	ГДЕ
		СебестоимостьТоваров.Количество > 0
		И СебестоимостьТоваров.Регистратор ССЫЛКА Документ.ПриобретениеТоваровУслуг) КАК Себестоимость
ГДЕ
	Себестоимость.НомерСтроки = 1

Оконная функция нумерует строки внутри группы каждой номенклатуры в порядке убывания даты, а внешний фильтр ГДЕ Себестоимость.НомерСтроки = 1 отсекает все предыдущие приходы, оставляя ровно одну актуальную запись.

Особенности работы с регистром «Себестоимость товаров»

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

  1. Зависимость от процедуры закрытия месяца: Окончательная себестоимость и регламентированная стоимость фиксируются только после выполнения регламентной операции расчета себестоимости. До закрытия месяца данные о стоимостной оценке могут быть неполными.
  2. Включение дополнительных расходов: В регистре отражается полная себестоимость с учетом транспортно-заготовительных расходов (ТЗР) и распределенных пошлин. Если вам нужна исходная контрактная цена поставщика, обращаться следует напрямую к табличным частям документов ПриобретениеТоваровУслуг или к регистру сведений цен номенклатуры.
  3. Фильтрация по типам операций: В регистр пишутся не только покупки, но и сборки, оприходования, перемещения и возвраты. Обязательно накладывайте отбор по типу регистратора или реквизиту хозяйственной операции, чтобы исключить искажение выборки другими движениями.
  4. Единицы измерения: Количество в регистре всегда приведено к базовой единице хранения. Рассчитанная цена (отношение суммы к количеству) будет соответствовать стоимости за одну базовую единицу.
← На главную