При доработке типового отчета «Ведомость по партиям товаров на складах» в конфигурации «Управление торговлей 10.3» разработчики нередко сталкиваются с задачей вывода возраста остатка (количества дней с момента поступления номенклатуры). Однако при попытке добавить вычисляемое поле через РАЗНОСТЬДАТ колонка либо остается пустой, либо расчет выполняется только для единичных позиций. Разберем детально, почему это происходит и как правильно реализовать данный расчет.
Проанализируем технические и учетные причины, которые приводят к ошибкам при добавлении поля возраста номенклатуры:
ДокументОприходования в регистре накопления ПартииТоваровНаСкладах остается пустым для большинства строк (за исключением ручных оприходований или распределения дополнительных расходов). Из-за этого обращение к дате документа оприходования возвращает пустое значение.ИсточникДанных.Период для расчета разницы дат привязывает расчет только к интервалу формирования отчета. Если товар поступил до начала выбранного периода и в периоде отчета движений не было, дата первичного прихода в таблицу не попадет.УниверсальныйОтчет в обычных формах базируется на объекте ПостроительОтчета. Если вычисляемое поле добавлено в текст запроса, но не описано во всех обязательных служебных секциях построителя ({ВЫБРАТЬ ...}, {ИТОГИ ...}), отчет не сможет корректно отобразить и агрегировать данные.Если на предприятии включен партионный учет по методу ФИФО и измерение ДокументОприходования заполнено, расчет количества дней выполняется путем вычисления разницы между датой партии и датой окончания отчета.
Разберем по шагам, как настроить текст запроса и модуль объекта:
Дата документа оприходования:
ВЫБРАТЬ
ИсточникДанных.Номенклатура КАК Номенклатура,
ИсточникДанных.ДокументОприходования КАК ДокументОприходования,
РАЗНОСТЬДАТ(ИсточникДанных.ДокументОприходования.Дата, &ДатаКон, ДЕНЬ) КАК КоличествоДней
{ВЫБРАТЬ
Номенклатура.*,
ДокументОприходования.*,
КоличествоДней}
ИЗ
РегистрНакопления.ПартииТоваровНаСкладах.ОстаткиИОбороты(&ДатаНач, &ДатаКон, Авто, , ) КАК ИсточникДанных
{ГДЕ
ИсточникДанных.Номенклатура.*}
ИТОГИ
МАКСИМУМ(КоличествоДней)
ПО
ОБЩИЕ,
Номенклатура
{ИТОГИ ПО
КоличествоДней}
Обратим внимание: в секции итогов для количества дней следует использовать функцию МАКСИМУМ, а не СУММА, чтобы в итоговых строках по номенклатуре не происходило бессмысленного сложения дней разных партий.
УниверсальныйОтчет.мСтруктураПредставлениеПолей.Вставить("КоличествоДней", "Количество дней на складе");
УниверсальныйОтчет.ДобавитьПоказатель("КоличествоДней", "Количество дней на складе", Истина, "ЧЦ=10; ЧДЦ=0", "КоличествоДней", "Количество дней на складе");
Если менять учетную политику со «Средней» на «ФИФО» нельзя, партии в регистре отсутствуют. В таком случае срок нахождения товара можно оценить по дате его последнего фактического поступления на склад. Для этого в отчет добавляется левое соединение с регистром ТоварыНаСкладах.
Посмотрим на пример формирования подзапроса:
ВЫБРАТЬ
ТоварыНаСкладах.Номенклатура КАК Номенклатура,
ТоварыНаСкладах.Склад КАК Склад,
МАКСИМУМ(ТоварыНаСкладах.Период) КАК ДатаПоследнегоПрихода
ПОМЕСТИТЬ ВТ_ПоследниеПоступления
ИЗ
РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах
ГДЕ
ТоварыНаСкладах.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)
И ТоварыНаСкладах.Период <= &ДатаКон
СГРУППИРОВАТЬ ПО
ТоварыНаСкладах.Номенклатура,
ТоварыНаСкладах.Склад
;
ВЫБРАТЬ
ИсточникДанных.Номенклатура КАК Номенклатура,
ИсточникДанных.Склад КАК Склад,
РАЗНОСТЬДАТ(ЕСТЬNULL(ВТ_ПоследниеПоступления.ДатаПоследнегоПрихода, &ДатаКон), &ДатаКон, ДЕНЬ) КАК КоличествоДней
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(&ДатаКон, ) КАК ИсточникДанных
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ПоследниеПоступления КАК ВТ_ПоследниеПоступления
ПО ИсточникДанных.Номенклатура = ВТ_ПоследниеПоступления.Номенклатура
И ИсточникДанных.Склад = ВТ_ПоследниеПоступления.Склад
Данный подход позволяет получить корректный интервал времени с момента крайней поставки даже в тех базах, где списание себестоимости ведется «котловым» методом без детального учета партий.
Если руководство приняло решение о необходимости детального учета партий, выполним следующие действия: