Как вывести себестоимость в документ Реализация товаров и услуг

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

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

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

Метод 1. Программное формирование отчета через СКД

Самый надежный способ получить цифры, идентичные тем, что видит пользователь в стандартных отчетах (например, «Стоимостная оценка склада»), — это программное выполнение схемы компоновки данных (СКД) этого самого отчета. Разберем по шагам, как это реализовать.

Суть метода заключается в том, чтобы не переписывать сложный запрос расчета себестоимости (который в типовых конфигурациях может занимать сотни строк), а использовать уже готовую логику отчета. Мы программно инициализируем отчет, передаем в него нужные параметры (дата, склад, номенклатура) и выгружаем результат в ТаблицаЗначений.

Рассмотрим пример кода, который позволяет программно получить данные из схемы компоновки:


Функция ПолучитьСебестоимостьИзОтчета(СсылкаНаОбъект) Экспорт
    // Находим нужный отчет в системе
    ОтчетОбъект = Отчеты.СтоимостнаяОценкаСкладаВЦенахНоменклатуры.Создать();
    СхемаСКД = ОтчетОбъект.СхемаКомпоновкиДанных;
    
    // Получаем настройки по умолчанию
    Настройки = ОтчетОбъект.КомпоновщикНастроек.ПолучитьНастройки();
    
    // Устанавливаем параметры отчета
    ПараметрДата = Настройки.ПараметрыДанных.Элементы.Найти("Период");
    ПараметрДата.Значение = СсылкаНаОбъект.Дата;
    ПараметрДата.Использование = Истина;

    // Выполняем компоновку макета
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаСКД, Настройки, , , Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
    
    // Процессор компоновки
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
    
    // Выводим результат в таблицу значений
    ТаблицаРезультат = Новый ТаблицаЗначений;
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
    ПроцессорВывода.УстановитьОбъект(ТаблицаРезультат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки);
    
    Возврат ТаблицаРезультат;
КонецФункции

Проанализируем ситуацию: этот метод гарантирует точность данных, но он очень ресурсоемкий. Если в документе сотни строк, формирование полного отчета при каждом изменении количества будет приводить к значительным задержкам (фризам) интерфейса.

Метод 2. Прямой запрос к регистрам накопления

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

Выясним причину, почему нельзя просто взять данные из регистра ВыручкаИСебестоимостьПродаж. Этот регистр заполняется только после проведения документа. Если менеджер только создает документ, данных в этом регистре еще нет. Поэтому нам нужно обращаться к остаткам по регистру СебестоимостьТоваров.

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

  1. Создаем запрос к виртуальной таблице Остатки регистра СебестоимостьТоваров.
  2. Устанавливаем фильтр по номенклатуре и складу из документа.
  3. Рассчитываем цену единицы как Стоимость / Количество.

Важный нюанс: В 1С существует понятие «Предварительная себестоимость» и «Фактическая себестоимость». Фактическая рассчитывается только регламентной операцией «Закрытие месяца». До этого момента данные в регистрах могут быть неточными или отсутствовать (если используется партионный учет 2.2 и расчет не выполнялся).

Метод 3. Использование типов цен (упрощенный подход)

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

В этом случае задача программиста упрощается до получения цен из регистра сведений ЦеныНоменклатуры:


ПараметрыЗапроса = Новый Структура;
ПараметрыЗапроса.Вставить("ВидЦены", Справочники.ВидыЦен.НайтиПоНаименованию("Себестоимость"));
ПараметрыЗапроса.Вставить("Дата", Объект.Дата);
ПараметрыЗапроса.Вставить("Номенклатура", ТекущаяСтрока.Номенклатура);

ЦенаСебестоимости = ЦенообразованиеВызовСервера.ПолучитьЦеныНоменклатуры(ПараметрыЗапроса);

Плюсы: высокая скорость работы, не нагружает систему сложными расчетами.

Минусы: это справочное значение, которое не учитывает остатки конкретных партий на складе.

Проблема себестоимости услуг

Рассмотрим ситуацию с услугами, упомянутую в обсуждении. В классическом понимании 1С Услуга не имеет складской себестоимости, так как она не хранится на складе и не имеет материального воплощения. Для услуг в 1С:УТ себестоимость чаще всего равна нулю.

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

Оптимизация: как избежать тормозов

Как справедливо замечено в обсуждении, расчет себестоимости «на лету» при каждом добавлении строки может превратить работу пользователя в мучение. Проанализируем способы оптимизации:

  1. Кнопка в командной панели: Вместо автоматического расчета добавьте кнопку «Рассчитать себестоимость». Менеджер нажмет ее один раз, когда документ будет готов, и система за один запрос соберет данные по всем строкам.
  2. Фоновое выполнение: При открытии формы или изменении состава ТЧ запускайте фоновое задание, которое рассчитает данные и вернет их в форму без блокировки интерфейса.
  3. Кэширование: Если номенклатура в документе повторяется, не делайте запрос дважды для одного и того же товара.

Итоги реализации

Для реализации задачи мы рекомендуем комбинированный подход. Если требуется максимальная точность — используйте программный вызов СКД отчета Стоимостная оценка склада, но делайте это по кнопке или при записи документа. Если нужна скорость и ориентировочные данные — используйте получение данных из регистра ЦеныНоменклатуры по специально выделенному типу цен.

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

← На главную