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