Разработка печатных форм в программе 1С:Управление торговлей 11 (УТ 11) часто преподносит сюрпризы начинающим программистам. Один из классических вопросов — как вывести себестоимость списываемого товара в макет акта о списании (например, при списании недостач). Попытка получить себестоимость «простым запросом» к остаткам регистра накопления часто оборачивается неудачей: запрос возвращает пустые значения или некорректные суммы.
В этой статье мы подробно разберем, почему так происходит, изучим внутреннюю архитектуру учета затрат в 1С v8.3 и рассмотрим несколько практических способов решения этой задачи: от простых точечных запросов до сложных универсальных механизмов, используемых в типовых конфигурациях.
Перед тем как писать программный код, выясним причину, по которой себестоимость в УТ 11 ведет себя иначе, чем в старых конфигурациях вроде УТ 10.3. Современные версии УТ 11, Комплексной автоматизации и ERP работают на базе концепции Расширенной аналитики учета затрат (РАУЗ).
Основные особенности этой системы:
СебестоимостьТоваров.Таким образом, если вы попытаетесь распечатать акт списания по документу, который создан в текущем (еще не закрытом) месяце, реальная себестоимость в регистре накопления будет равна нулю. Нам нужно научить систему корректно обрабатывать обе ситуации: когда месяц закрыт и когда расчет еще не произведен.
Если в вашей организации принято печатать акты списания строго после закрытия месяца (когда все стоимостные показатели уже рассчитаны), мы можем напрямую обратиться к регистру накопления СебестоимостьТоваров.
Для этого нам понадобится связать движения регистра с конкретным документом-регистратором. Разберем по шагам логику построения такого запроса.
Посмотрим на пример запроса, который выбирает рассчитанную себестоимость по конкретному документу списания и номенклатуре:
ВЫБРАТЬ
СебестоимостьТоваров.Регистратор КАК Док,
СебестоимостьТоваров.АналитикаУчетаНоменклатуры.Номенклатура КАК Номенклатура,
СУММА(СебестоимостьТоваров.Стоимость) КАК Стоимость,
СУММА(СебестоимостьТоваров.Количество) КАК Количество
ИЗ
РегистрНакопления.СебестоимостьТоваров КАК СебестоимостьТоваров
ГДЕ
СебестоимостьТоваров.АналитикаУчетаНоменклатуры.Номенклатура = &Ссылка
И СебестоимостьТоваров.Регистратор = &Док
СГРУППИРОВАТЬ ПО
СебестоимостьТоваров.Регистратор,
СебестоимостьТоваров.АналитикаУчетаНоменклатуры.Номенклатура
Важные нюансы этого запроса:
&Док).АналитикаУчетаНоменклатуры.Номенклатура, так как в регистре себестоимости аналитика хранения свернута в специальный ключ.СУММА), поскольку по одному документу может быть сделано несколько записей движений в зависимости от разделов учета (например, разные виды запасов).Что делать, если акт необходимо распечатать «здесь и сейчас», до регламентного закрытия периода? В этом случае реальной себестоимости в регистре накопления еще нет, но мы можем воспользоваться данными предварительного расчета.
Предварительный расчет себестоимости выполняется специальным регламентным заданием (которое обычно настраивается на ежевечерний запуск). Его результаты записываются в регистр сведений СтоимостьТоваров.
Рассмотрим, как вытащить эти данные с помощью запроса. Нам потребуется определить срез последних цен по состоянию на дату документа:
ВЫБРАТЬ
СтоимостьТоваров.АналитикаУчетаНоменклатуры.Номенклатура КАК Номенклатура,
СтоимостьТоваров.СтоимостьРегл КАК ПредварительнаяСтоимость
ИЗ
РегистрСведений.СтоимостьТоваров КАК СтоимостьТоваров
ГДЕ
СтоимостьТоваров.АналитикаУчетаНоменклатуры.Номенклатура = &Номенклатура
И СтоимостьТоваров.Период <= &ДатаДокумента
И СтоимостьТоваров.Организация = &Организация
Обратите внимание, что мы обязательно накладываем отбор по Организации, так как в разных юрлицах компании один и тот же товар может иметь разную закупочную и учетную стоимость.
Наиболее надежный и профессиональный подход — совместить оба источника данных. Именно по такому пути идет сама система 1С в своих типовых печатных формах.
Логика работы алгоритма следующая:
СебестоимостьТоваров по текущему регистратору.СтоимостьТоваров.Проанализируем пример комплексного запроса, реализующего эту схему:
ВЫБРАТЬ
РасчетСебестоимости.Ссылка.ПредварительныйРасчет КАК ПредварительныйРасчет,
Документ.Ссылка КАК Ссылка,
Документ.Организация КАК Организация
ПОМЕСТИТЬ ВтШапка
ИЗ
Документ.СписаниеНедостачТоваров КАК Документ
ЛЕВОЕ СОЕДИНЕНИЕ Документ.РасчетСебестоимостиТоваров.Организации КАК РасчетСебестоимости
ПО (РасчетСебестоимости.Ссылка.Дата МЕЖДУ НАЧАЛОПЕРИОДА(Документ.Дата, МЕСЯЦ) И КОНЕЦПЕРИОДА(Документ.Дата, МЕСЯЦ))
И РасчетСебестоимости.Ссылка.Проведен = ИСТИНА
И Документ.Organizatcya = РасчетСебестоимости.Организация
ГДЕ
Документ.Ссылка = &ДокументСсылка;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВидыЗапасов.Ссылка КАК Ссылка,
ВидыЗапасов.АналитикаУчетаНоменклатуры КАК АналитикаУчетаНоменклатуры,
ВидыЗапасов.Количество КАК Количество,
Шапка.ПредварительныйРасчет КАК ПредварительныйРасчет
ПОМЕСТИТЬ ВтВидыЗапасов
ИЗ
Документ.СписаниеНедостачТоваров.ВидыЗапасов КАК ВидыЗапасов
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВтШапка КАК Шапка ПО ВидыЗапасов.Ссылка = Шапка.Ссылка;
////////////////////////////////////////////////////////////////////////////////
// Источник 1: Данные предварительного расчета (Регистр сведений)
ВЫБРАТЬ
ВидыЗапасов.Ссылка КАК Ссылка,
ВидыЗапасов.АналитикаУчетаНоменклатуры КАК АналитикаУчетаНоменклатуры,
СтоимостьТоваров.СтоимостьРегл КАК Стоимость
ПОМЕСТИТЬ ЦеныПредварительные
ИЗ
ВтВидыЗапасов КАК ВидыЗапасов
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.СтоимостьТоваров КАК СтоимостьТоваров
ПО ВидыЗапасов.АналитикаУчетаНоменклатуры = СтоимостьТоваров.АналитикаУчетаНоменклатуры
И (ВидыЗапасов.ПредварительныйCalcul = ИСТИНА);
////////////////////////////////////////////////////////////////////////////////
// Источник 2: Данные окончательного расчета (Регистр накопления)
ВЫБРАТЬ
ВидыЗапасов.Ссылка КАК Ссылка,
СебестоимостьТоваров.АналитикаУчетаНоменклатуры КАК АналитикаУчетаНоменклатуры,
СУММА(СебестоимостьТоваров.СтоимостьРегл) КАК Стоимость
ПОМЕСТИТЬ ЦеныФактические
ИЗ
РегистрНакопления.СебестоимостьТоваров КАК СебестоимостьТоваров
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВтВидыЗапасов КАК ВидыЗапасов
ПО СебестоимостьТоваров.Регистратор = ВидыЗапасов.Ссылка
И СебестоимостьТоваров.АналитикаУчетаНоменклатуры = ВидыЗапасов.АналитикаУчетаНоменклатуры
И (ВидыЗапасов.ПредварительныйCalcul = ЛОЖЬ)
СГРУППИРОВАТЬ ПО
ВидыЗапасов.Ссылка,
СебестоимостьТоваров.АналитикаУчетаНоменклатуры;
////////////////////////////////////////////////////////////////////////////////
// Объединение результатов для вывода в макет
ВЫБРАТЬ
ВидыЗапасов.АналитикаУчетаНоменклатуры.Номенклатура КАК Номенклатура,
ВидыЗапасов.Количество КАК Количество,
ЕСТЬNULL(ЦеныПредв.Стоимость, ЕСТЬNULL(ЦеныФакт.Стоимость, 0)) КАК ИтоговаяСтоимость
ИЗ
ВтВидыЗапасов КАК ВидыЗапасов
ЛЕВОЕ СОЕДИНЕНИЕ ЦеныПредварительные КАК ЦеныПредв
ПО ВидыЗапасов.Ссылка = ЦеныПредв.Ссылка
И ВидыЗапасов.АналитикаУчетаНоменклатуры = ЦеныПредв.АналитикаУчетаНоменклатуры
ЛЕВОЕ СОЕДИНЕНИЕ ЦеныФактические КАК ЦеныФакт
ПО ВидыЗапасов.Ссылка = ЦеныФакт.Ссылка
И ВидыЗапасов.АналитикаУчетаНоменклатуры = ЦеныФакт.АналитикаУчетаНоменклатуры
Этот сложный, но эффективный запрос позволяет динамически переключаться между источниками себестоимости. Если месяц уже закрыт, мы получаем копейка в копейку точную регламентированную стоимость списания из проводок движения. Если месяц открыт — берется наиболее свежая аппроксимация из предварительного расчета, что исключает появление пустых колонок в макете.
Если ваша цель — предоставить пользователям стоимостную оценку списываемого имущества, но вы не хотите перегружать базу тяжелыми запросами расчета себестоимости, можно использовать встроенный функционал печати цен по типу цен.
Выясним, как это настроить в пользовательском режиме:
В этом случае при формировании печатной формы «Акт списания» программа сама подставит в макет актуальные планово-учетные цены, зарегистрированные документом «Установка цен номенклатуры». Это полностью решает проблему «пустых цен» до закрытия месяца и не требует внесения изменений в программный код конфигурации.
Мы подробно проанализировали специфику работы с себестоимостью в 1С:УТ 11. Подведем краткие итоги нашей совместной работы:
СебестоимостьТоваров всегда будут заполненные стоимостные данные «на лету» — они появляются там только после процедуры закрытия месяца.СтоимостьТоваров (предварительный расчет).Организация, Характеристика и АналитикаУчетаНоменклатуры, чтобы избежать некорректного завышения или занижения сумм.