При разработке или модификации отчетов в 1С часто возникает задача заменить стандартные показатели (например, себестоимость или учетную сумму) на специфические значения, такие как сумма с учетом торговой наценки. В данной статье мы разберем ситуацию на примере отчета по остаткам номенклатуры в конфигурации для общепита, где необходимо вывести данные из документа Перемещение номенклатуры вместо стандартных остатков из регистра накопления.
Прежде чем приступать к правке отчета, нам необходимо проанализировать, где именно хранятся нужные данные. В системе 1С информация редко берется напрямую из экранных форм. Как правило, она распределена по таблицам — регистрам и документам. Проанализируем типичную ситуацию:
ОстаткиНоменклатуры: Это стандартный источник для большинства отчетов по складу. Он содержит ресурсы КоличествоОстаток и СуммаОстаток. Однако СуммаОстаток здесь обычно отражает себестоимость, а не розничную цену с наценкой.ПеремещениеНоменклатурыИзОбщепитаВРозницу: В его табличной части может содержаться реквизит СуммаСНаценкой. Но напрямую тянуть данные из документа в отчет по остаткам — это архитектурная ошибка, так как отчет показывает состояние на текущий момент, а документ — разовое событие.ЦеныНоменклатуры: Если в компании используется документ Установка отпускных цен, то актуальная розничная цена хранится именно здесь. Это наиболее правильный источник данных для расчета наценки в отчете.Рассмотрим самый надежный способ. Мы будем использовать Систему компоновки данных (СКД), чтобы соединить остатки товаров с актуальными ценами на дату отчета. Проанализируем последовательность действий в конструкторе схемы компоновки данных:
В наборе данных (запросе) мы должны выполнить ЛЕВОЕ СОЕДИНЕНИЕ таблицы остатков с виртуальной таблицей СрезПоследних регистра сведений. Рассмотрим пример кода запроса:
ВЫБРАТЬ
Остатки.Номенклатура КАК Номенклатура,
Остатки.КоличествоОстаток КАК Количество,
ЕСТЬNULL(Цены.Цена, 0) КАК ЦенаПродажная,
Остатки.КоличествоОстаток * ЕСТЬNULL(Цены.Цена, 0) КАК СуммаСНаценкой
ИЗ
РегистрНакопления.ОстаткиНоменклатуры.Остатки(&Период, ) КАК Остатки
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Период, ) КАК Цены
ПО Остатки.Номенклатура = Цены.Номенклатура
Этот метод позволяет динамически вычислять сумму с наценкой, умножая текущий остаток на актуальную цену. Выясним причину, почему это лучше: цена в документе перемещения могла быть актуальна вчера, но сегодня она может измениться, и отчет по остаткам должен отражать текущую реальность.
Если специфика учета такова, что наценка индивидуальна для каждой партии и фиксируется только в документе перемещения, нам придется обратиться к полю Регистратор. Разберем, как это реализовать:
В регистре накопления ОстаткиНоменклатуры должно быть включено измерение Партия или разрешен вывод по регистратору. В СКД мы добавим связь с табличной частью документа ПеремещениеНоменклатурыИзОбщепитаВРозницу.
Проанализируем пример запроса для такой связи:
ВЫБРАТЬ
Остатки.Номенклатура,
Остатки.КоличествоОстаток,
ТЧ_Документа.СуммаСНаценкой / ТЧ_Документа.Количество КАК ЦенаИзДокумента,
Остатки.КоличествоОстаток * (ТЧ_Документа.СуммаСНаценкой / ТЧ_Документа.Количество) КАК ИтоговаяСумма
ИЗ
РегистрНакопления.ОстаткиНоменклатуры.Остатки(&Период, ) КАК Остатки
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ПеремещениеНоменклатурыИзОбщепитаВРозницу.Товары КАК ТЧ_Документа
ПО Остатки.Регистратор = ТЧ_Документа.Ссылка
И Остатки.Номенклатура = ТЧ_Документа.Номенклатура
Важно: Этот способ сработает только в том случае, если в регистре накопления хранятся данные в разрезе документов (регистраторов). Если регистр "схлопывает" остатки, вы не сможете определить, из какого именно перемещения пришел товар.
В конфигурациях, основанных на бухгалтерском учете (например, 1С:Бухгалтерия или 1С:Общепит на ее базе), торговая наценка учитывается на счете 42. Посмотрим, как это упрощает задачу:
Сумма в продажных ценах складывается из дебетового остатка по счету 41 (товары) и кредитового остатка по счету 42 (наценка). В СКД мы можем создать вычисляемое поле.
Рассмотрим формулу для вычисляемого поля в СКД:
СуммаПродажная = СуммаОстатокДт41 + СуммаОстатокКт42
Для реализации этого метода выберем виртуальную таблицу Хозрасчетный.Остатки и настроим отбор по счету 41.11 (товары в рознице) и связанному с ним счету наценки.
Если вы чувствуете себя неуверенно в написании кода, пройдем по шагам в конструкторе схемы компоновки данных:
СуммаОстаток. Если ваша цель — полная замена, удалите его из выбранных полей, но оставьте в запросе для расчетов.СуммаСНаценкой.КоличествоОстаток * ПолучитьЦену(Номенклатура, &Период). Функция ПолучитьЦену может быть вашей собственной экспортной функцией в общем модуле, либо вы можете использовать соединение с регистром цен в самом запросе, как было показано в Методе 1.Сумма(...).Как справедливо заметили коллеги в обсуждении, основная трудность заключается в том, что для одной и той же номенклатуры в разных документах План-меню или Установка цен могут быть указаны разные наценки. Выясним, как программа должна понимать, какую цену брать:
Для решения этой проблемы в 1С используется понятие Тип цены. Проанализируем ситуацию: если для розничного склада определен конкретный тип цен (например, "Розничная общепит"), то в запросе к регистру ЦеныНоменклатуры.СрезПоследних обязательно нужно добавить условие по этому типу цен.
// Фрагмент условия в запросе СКД
ГДЕ
Цены.ТипЦен = &НужныйТипЦен
Таким образом, мы исключим дублирование строк в отчете и получим корректную сумму с наценкой, актуальную именно для выбранного подразделения или склада.
Подведем итог: замена данных в отчете — это не просто переименование колонки, а поиск правильной логической связи между остатком товара на складе и стоимостью этого товара в актуальных прайс-листах или документах поступления. Используя механизмы СКД и соединения таблиц, мы можем вывести любой расчетный показатель, необходимый пользователю.