Когда в системе не ведется полноценный партионный учет, но для бизнес-задач (например, поиска брака, оценки срока хранения или определения себестоимости) требуется понять, какие именно приходы «лежат» в остатке, мы сталкиваемся с непростой задачей. Давайте разберем, как подойти к этому вопросу, используя возможности языка запросов 1С:Предприятие.
Основная сложность заключается в том, что в обычном регистре остатков ТоварыНаСкладах хранится только итоговое количество. Чтобы узнать «первоисточник» товара, нам нужно мысленно или программно восстановить историю списаний по методу FIFO (первым пришел — первым ушел). Попытка сделать это одним запросом на базе с десятилетней историей — задача нетривиальная, так как она требует выполнения тета-соединений, что на больших объемах данных может существенно замедлить работу системы.
Разберем подробный алгоритм, который позволяет «раскрутить» остатки обратно до документов поступления. Наш путь будет состоять из нескольких этапов работы с временными таблицами.
тета-соединение приходов самих с собой, чтобы посчитать Сумму приходов, которые произошли ранее или одновременно с текущим документом. Это поможет нам понять, когда именно суммарное количество приходов покрывает наш остаток.Рассмотрим пример запроса, который позволяет собрать такую цепочку данных:
ВЫБРАТЬ
ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура,
ТоварыНаСкладахОстатки.ВНаличииОстаток КАК Остаток
ПОМЕСТИТЬ ВТ_Остатки
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(&Момент, Номенклатура В (&СписокНоменклатуры)) КАК ТоварыНаСкладахОстатки
;
ВЫБРАТЬ
ТоварыНаСкладах.Период КАК Период,
ТоварыНаСкладах.Регистратор КАК Регистратор,
ТоварыНаСкладах.Номенклатура КАК Номенклатура,
ТоварыНаСкладах.ВНаличии КАК Приход
ПОМЕСТИТЬ ВТ_Приходы
ИЗ
РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах
ГДЕ
ТоварыНаСкладах.Номенклатура В(&СписокНоменклатуры)
И ТоварыНаСкладах.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)
;
ВЫБРАТЬ
ВТ_Приходы.Регистратор,
ВТ_Приходы.Период,
ВТ_Приходы.Номенклатура,
СУММА(ВТ_Приходы1.Приход) КАК НакопленныйПриход
ПОМЕСТИТЬ ВТ_ФИФО
ИЗ
ВТ_Приходы КАК ВТ_Приходы
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Приходы КАК ВТ_Приходы1
ПО ВТ_Приходы.Номенклатура = ВТ_Приходы1.Номенклатура
И ВТ_Приходы.Период >= ВТ_Приходы1.Период
СГРУППИРОВАТЬ ПО
ВТ_Приходы.Регистратор,
ВТ_Приходы.Период,
ВТ_Приходы.Номенклатура
Чтобы ваш отчет не «вешал» базу данных, важно соблюдать следующие правила:
1С при правильном использовании оптимизируют выборку. Убедитесь, что поля, по которым вы соединяете таблицы (Номенклатура, Период), проиндексированы.1С уже оптимизирована для этих задач, и попытки «изобрести велосипед» через SQL-запросы на больших базах всегда приводят к проблемам с производительностью.РегистрСведений с привязкой партий. Это перенесет нагрузку с момента формирования отчета на процесс проведения документов.Задача определения поступлений по остаткам — это классическая проблема «квазипартионного учета». Мы с вами разобрали, что ее можно решить через накопленные итоги во временных таблицах, но это всегда компромисс между гибкостью отчета и нагрузкой на СУБД. Всегда начинайте с анализа объема данных и возможности использования типовых механизмов, прежде чем приступать к написанию сложных многоэтапных запросов.