Как правильно вывести себестоимость в список документов «Перемещение товаров» в 1С:Бухгалтерия 3.0

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

При работе с конфигурацией 1С:Бухгалтерия предприятия 3.0 (БП 3.0) разработчики часто сталкиваются с необходимостью отображения себестоимости списания товаров непосредственно в форме списка документов, например, в Перемещении товаров. Казалось бы, в документе уже существует реквизит СебестоимостьДокумента или аналогичные поля в табличной части, которые так и просятся для заполнения. Однако попытка записать туда данные программно в момент проведения документа может привести к фатальным ошибкам в учете.

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

Разбираем назначение стандартного реквизита «Себестоимость»

Для начала проанализируем ситуацию: зачем в типовой конфигурации БП 3.0 вообще существуют поля для ввода себестоимости, если программа должна рассчитывать их автоматически? Ответ кроется в архитектуре взаимодействия систем 1С:Управление торговлей (УТ) и 1С:Бухгалтерия предприятия (БП).

Рассмотрим логику, заложенную методологами 1С: в системе УТ ведется оперативный учет, и именно там формируется «истинная» себестоимость. При синхронизации данных документ переносится в БП уже с готовыми суммами. Чтобы бухгалтерия не пересчитывала эти суммы по своим правилам (которые могут отличаться из-за партионного учета или ФИФО), используется реквизит Себестоимость.

Важный вывод: этот реквизит служит «выключателем» стандартного механизма расчета. Если он заполнен, программный модуль УчетНоменклатуры видит готовую сумму и подставляет ее в проводки по счетам 10, 41 или 43 «как есть», игнорируя реальные остатки и стоимость партий на регистрах бухгалтерии.

Почему нельзя записывать себестоимость в стандартный реквизит при проведении?

Если мы попытаемся заполнить этот реквизит программно в процедуре ОбработкаПроведения, мы столкнемся с тремя критическими проблемами:

  1. Рекурсия записи: Для того чтобы значение сохранилось в реквизите объекта, нам нужно выполнить метод ЭтотОбъект.Записать(). Но вызов записи внутри транзакции проведения инициирует повторное проведение, что ведет либо к бесконечной петле, либо к ошибке блокировки таблиц базы данных.
  2. Потеря актуальности ФИФО: Как только мы записали число в это поле, документ становится «зацементированным». Если бухгалтер изменит приходную накладную задним числом, себестоимость в перемещении должна бы пересчитаться, но наш записанный «костыль» заставит систему всегда брать старую сумму.
  3. Логика перепроведения: Чтобы корректно обновить такие документы, нам пришлось бы проводить базу трижды: сначала очищать суммы, затем проводить для расчета, а затем записывать результат. Это увеличивает время регламентных операций в несколько раз.

Проанализируем альтернативные и безопасные пути реализации этой задачи.

Решение №1: Динамический список (самый правильный метод)

Если наша основная цель — видеть себестоимость в списке документов для визуального контроля, нам вообще не нужно менять структуру документа или записывать что-то в объект. Мы можем воспользоваться мощностью Динамического списка в форме списка документов.

Разберем по шагам, как это реализовать:

  1. Откроем форму списка документа ПеремещениеТоваров.
  2. Перейдем к свойствам основной таблицы (Динамический список) и откроем настройку запроса.
  3. В тексте запроса выполним левое соединение таблицы документов с виртуальной таблицей РегистрБухгалтерии.Хозрасчетный.Обороты.

Рассмотрим пример запроса для динамического списка:


ВЫБРАТЬ
    ДокументПеремещение.Ссылка КАК Ссылка,
    ДокументПеремещение.Дата КАК Дата,
    ДокументПеремещение.Номер КАК Номер,
    ЕСТЬNULL(ХозрасчетныйОбороты.СуммаОборот, 0) КАК СебестоимостьДляСписка
ИЗ
    Документ.ПеремещениеТоваров КАК ДокументПеремещение
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Хозрасчетный.Обороты(,, Авто, , , , , ) КАК ХозрасчетныйОбороты
        ПО ХозрасчетныйОбороты.Регистратор = ДокументПеремещение.Ссылка
            И (ХозрасчетныйОбороты.Счет В ИЕРАРХИИ (ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.Товары)))

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

Решение №2: Создание собственного реквизита через расширение

Если себестоимость необходима не только в списке, но и в сложных отчетах, где соединение с регистром бухгалтерии будет работать слишком медленно, мы можем создать собственный реквизит, например, упр_СебестоимостьДляОтчетов.

Выясним, как правильно организовать его заполнение:

  1. Создаем расширение конфигурации.
  2. Добавляем в документ ПеремещениеТоваров новый реквизит с типом Число(15, 2).
  3. Используем Подписку на событие ОбработкаПроведения (или ПриЗаписи).
  4. В обработчике получаем обороты по регистру Хозрасчетный, которые только что сформировал документ, и записываем их в наш новый реквизит.

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

Решение №3: Механизм дополнительных сведений

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

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

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

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

Важные нюансы учета в БП 3.0

Проанализируем ситуацию, упомянутую в обсуждении: «упрощенный учет и отсутствие закрытия месяца». В БП 3.0, если включена настройка Разрешить списание запасов при отсутствии остатков, себестоимость при проведении может быть нулевой, если товара нет на складе в момент нажатия кнопки «Провести».

В этом случае любая попытка записать «текущую» себестоимость в реквизит объекта зафиксирует 0. Когда позже придет документ поступления, себестоимость перемещения не появится автоматически — потребуется либо перепроведение всех документов, либо выполнение регламентной операции Корректировка стоимости номенклатуры в конце месяца.

Резюмируем: Использование стандартного реквизита СебестоимостьДокумента для хранения расчетных данных — это «путь к катастрофе» в учете 1С:Бухгалтерии. Самым элегантным и производительным решением является настройка динамического списка с запросом к регистру бухгалтерии. Если же физическое хранение суммы необходимо, используйте дополнительные сведения или собственный реквизит в расширении, никогда не трогая типовые поля, предназначенные для обмена данными.

← На главную