Как программно рассчитать себестоимость по документу реализации в 1С:УТ 11?

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

В процессе разработки часто возникает задача получить себестоимость проданных товаров по конкретному документу, например, по «Реализации товаров и услуг». Стандартные отчеты показывают итоговые цифры, но как извлечь эти данные программно для дальнейшей обработки? Разберем несколько подходов, которые помогут решить эту задачу в конфигурации 1С:Управление торговлей 11.

Проанализируем ситуацию: у нас есть проведенный документ реализации, и нам нужно для каждой строки его табличной части "Товары" получить рассчитанную себестоимость. Эта информация может быть нужна для анализа позиций товаров в документе реализации, кастомных отчетов, выгрузок или других специфических механизмов.

Подход 1: Использование общих модулей расчета себестоимости

Самый "правильный" и надежный способ — обратиться к тем же механизмам, которые использует сама конфигурация. В УТ 11 за расчет себестоимости отвечает сложная система, но для наших целей можно воспользоваться экспортными процедурами из общих модулей.

Основной модуль, который нас интересует, — это УчетСебестоимости. Он содержит процедуры для подготовки и расчета данных. Рассмотрим по шагам, как его использовать.

  1. Подготовка данных для расчета.

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

  2. Вызов процедуры расчета.

    Воспользуемся процедурой РассчитатьСебестоимость из общего модуля УчетСебестоимости. Эта процедура принимает на вход параметры расчета и возвращает таблицу с результатами.

Посмотрим на практический пример кода, который решает нашу задачу:


// Предполагается, что СсылкаНаДокумент - это переменная,
// содержащая ссылку на нужный документ "РеализацияТоваровУслуг".

// 1. Создаем структуру параметров для расчета
ПараметрыРасчета = Новый Структура;
ПараметрыРасчета.Вставить("РассчитатьПартии", Истина);
ПараметрыРасчета.Вставить("Источник", СсылкаНаДокумент);

// 2. Вызываем основную процедуру расчета из общего модуля
ТаблицаСебестоимости = УчетСебестоимости.РассчитатьСебестоимость(ПараметрыРасчета);

// 3. Обрабатываем результат
Для Каждого Строка Из ТаблицаСебестоимости Цикл
    Сообщить(
        Строка("Номенклатура: %1, Себестоимость: %2",
        Строка.Номенклатура,
        Строка.Сумма)
    );
КонецЦикла;

Разберем код подробнее:

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

Подход 2: Формирование отчета "Валовая прибыль предприятия" с отбором

Иногда требуется более простое решение, которое не требует глубокого погружения в общие модули. В таком случае можно программно сформировать стандартный отчет, установив в нем нужные отборы. Отчет "Валовая прибыль предприятия" идеально подходит для этой цели, так как он оперирует данными о продажах и себестоимости.

Основная идея: мы создаем экземпляр отчета, устанавливаем отбор по документу-регистратору и выводим результат в таблицу значений, которую затем можем обработать, например, выполнив ABC/XYZ Анализ номенклатуры.

Рассмотрим пример реализации этого подхода:


// Предполагается, что ДокументСсылка - это переменная,
// содержащая ссылку на нужный документ "РеализацияТоваровУслуг".

// 1. Получаем объект отчета
Отчет = Отчеты.ВаловаяПрибыльПредприятия.Создать();

// 2. Устанавливаем настройки компоновки данных
СхемаКомпоновкиДанных = Отчет.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
Настройки = СхемаКомпоновкиДанных.НастройкиПоУмолчанию;

// 3. Устанавливаем отбор по регистратору (нашему документу)
ЭлементОтбора = Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Регистратор");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = ДокументСсылка;
ЭлементОтбора.Использование = Истина;

// 4. Устанавливаем период (можно взять из документа)
Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("НачалоПериода", НачалоМесяца(ДокументСсылка.Дата));
Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("КонецПериода", КонецМесяца(ДокументСсылка.Дата));

// 5. Формируем отчет
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки);

ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);

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

// 7. Результат находится в таблице "Результат"
// Теперь можно перебрать строки и получить нужные данные
Для Каждого Строка Из Результат Цикл
    Сообщить(
        Строка("Номенклатура: %1, Себестоимость: %2",
        Строка.Номенклатура,
        Строка.Себестоимость)
    );
КонецЦикла;

Преимущества этого метода:

Недостатки:

Итоговые рекомендации

Выбор метода зависит от конкретной задачи:

В любом случае, оба способа позволяют надежно получить данные о себестоимости в разрезе конкретного документа, решая поставленную задачу.

← На главную