Как программно изменить счет учета (МЦ.04 на МЦ.05) при проведении документа в 1С:Бухгалтерия 3.0?

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

Переход с редакции 2.0 на 3.0 в «1С:Бухгалтерия предприятия» часто сопровождается трудностями, связанными с изменением архитектуры проведения документов. Если раньше алгоритмы формирования проводок находились непосредственно в модуле объекта документа, то в современной версии 3.0 логика вынесена в общие модули, такие как УчетТоваров и УчетМатериаловВЭксплуатации. В этой статье мы подробно разберем, как корректно реализовать подмену счета учета в проводках (например, замену МЦ.04 на МЦ.05), основываясь на дополнительных свойствах номенклатуры, не снимая конфигурацию с поддержки.

Анализ проблемы: почему старые методы не работают

В БП 2.0 доработки часто вносились прямо в процедуру ОбработкаПроведения. В БП 3.0 при попытке изменить код в общем модуле УчетМатериаловВЭксплуатации вы столкнетесь с тем, что обновление программы станет крайне трудоемким процессом. Кроме того, в 3.0 движения формируются на основе таблиц значений, которые передаются в специализированные процедуры. Чтобы реализовать замену счета по условию (наличие дополнительного реквизита «СчетМЦ05»), наиболее правильным и современным подходом будет использование Подписки на событие.

Шаг 1: Подготовка дополнительных сведений

Прежде чем приступать к кодингу, проанализируем, как хранятся данные. В 1С дополнительные реквизиты и сведения хранятся в разных местах:

  1. Дополнительные реквизиты — находятся в табличной части ДополнительныеРеквизиты справочника Номенклатура.
  2. Дополнительные сведения — хранятся в независимом регистре сведений ДополнительныеСведения.

В нашем примере мы будем исходить из того, что у номенклатуры создан дополнительный реквизит, указывающий на необходимость использования счета МЦ.05. Выясним его точное имя через «Администрирование — Общие настройки — Дополнительные реквизиты и сведения».

Шаг 2: Создание общего модуля и подписки на событие

Для реализации логики нам потребуется создать новый объект в конфигураторе:

  1. Создадим новый Общий модуль (например, _РаботаСПроводкамиКастом). Установим свойства: Сервер, Внешнее соединение.
  2. Создадим объект Подписка на событие.
    • Источник: ДокументОбъект.ПередачаМатериаловВЭксплуатацию.
    • Событие: ОбработкаПроведения.
    • Обработчик: Выбираем наш созданный общий модуль и процедуру.

Шаг 3: Написание программного кода

Разберем алгоритм работы обработчика. Нам нужно получить список номенклатуры из документа, у которой установлен признак «СчетМЦ05», а затем пройтись по сформированным движениям и заменить счет МЦ.04 на МЦ.05. Рассмотрим пример кода:


Процедура ПриПроведенииПередачиВЭксплуатацию(Источник, Отказ, РежимПроведения) Экспорт

    // 1. Проверяем, не происходит ли загрузка данных (обмен)
    Если Источник.ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;

    // 2. Формируем запрос для получения номенклатуры с особым свойством
    Запрос = Новый Запрос;
    Запрос.Текст = 
    "ВЫБРАТЬ
    |	ТЧ.Номенклатура КАК Номенклатура
    |ИЗ
    |	Документ.ПередачаМатериаловВЭксплуатацию.ИнвентарьИХозяйственныеПринадлежности КАК ТЧ
    |		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Номенклатура.ДополнительныеРеквизиты КАК НомДоп
    |		ПО ТЧ.Номенклатура = НомДоп.Ссылка
    |ГДЕ
    |	ТЧ.Ссылка = &Ссылка
    |	И НомДоп.Свойство.Наименование ПОДОБНО ""%СчетМЦ05%""
    |	И НомДоп.Значение = ИСТИНА
    |СГРУППИРОВАТЬ ПО
    |	ТЧ.Номенклатура";

    Запрос.УстановитьПараметр("Ссылка", Источник.Ссылка);
    
    РезультатЗапроса = Запрос.Выполнить();
    Если РезультатЗапроса.Пустой() Тогда
        Возврат; // Особой номенклатуры нет, ничего менять не нужно
    КонецЕсли;

    ТаблицаОсобойНоменклатуры = РезультатЗапроса.Выгрузить();
    ТаблицаОсобойНоменклатуры.Индексы.Добавить("Номенклатура");

    // 3. Анализируем движения по регистру Хозрасчетный
    Для Каждого Проводка Из Источник.Движения.Хозрасчетный Цикл
        
        // Нас интересует забалансовый счет МЦ.04 по дебету
        Если Проводка.СчетДт = ПланыСчетов.Хозрасчетный.ИнвентарьИХозяйственныеПринадлежностиВЭксплуатации Тогда
            
            // Проверяем, есть ли номенклатура из проводки в нашем списке
            НоменклатураВПроводке = Проводка.СубконтоДт.Номенклатура;
            Если ТаблицаОсобойНоменклатуры.Найти(НоменклатураВПроводке, "Номенклатура") <> Неопределено Тогда
                
                // Выполняем замену счета
                Проводка.СчетДт = ПланыСчетов.Хозрасчетный.НайтиПоКоду("МЦ.05");
                
                // Важно: при смене счета могут измениться субконто!
                // На МЦ.05 обычно нет субконто "Работники организаций", которое есть на МЦ.04.
                // Рекомендуется перезаполнить субконто через типовой механизм:
                БухгалтерскийУчет.УстановитьСубконто(Проводка.СчетДт, Проводка.СубконтоДт, "Номенклатура", НоменклатураВПроводке);
                
                // Устанавливаем флаг записи движений
                Источник.Движения.Хозрасчетный.Записывать = Истина;
                
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;

КонецПроцедуры

Разбор нюансов реализации

Рассмотрим подробнее критически важные моменты, которые часто упускают начинающие разработчики:

1. Соответствие субконто. Счет МЦ.04 (Инвентарь в эксплуатации) в типовой БП 3.0 имеет три субконто: Номенклатура, Партии материалов в эксплуатации и Работники организаций. Счет МЦ.05 (Спецоснастка) может иметь другой набор. Проанализируем план счетов: если на новом счете нет какого-то измерения, 1С может выдать ошибку при записи или оставить некорректные ссылки в базе. Использование метода БухгалтерскийУчет.УстановитьСубконто позволяет избежать этих проблем, так как он проверяет наличие вида субконто на счете перед установкой значения.

2. Флаг записи движений. В подписке на событие ОбработкаПроведения движения документа уже сформированы в памяти, но еще не записаны в базу данных. Если вы изменили коллекцию Источник.Движения.Хозрасчетный, обязательно установите свойство Записывать = Истина. В противном случае ваши изменения будут проигнорированы, и документ запишет те проводки, которые сформировал основной алгоритм.

3. Поиск счета. Использование ПланыСчетов.Хозрасчетный.НайтиПоНаименованию — не самый надежный способ, так как пользователь может переименовать счет в режиме «Предприятие». Проанализируем альтернативы: лучше использовать ПланыСчетов.Хозрасчетный.НайтиПоКоду("МЦ.05") или обращаться к предопределенным счетам, если они есть в конфигурации (например, ПланыСчетов.Хозрасчетный.СпецоснасткаВЭксплуатации).

Альтернативное решение через расширение конфигурации

Если ваша версия платформы позволяет использовать расширения, выясним, как сделать это еще элегантнее. Вместо подписки можно перехватить процедуру в общем модуле УчетМатериаловВЭксплуатации с помощью аннотации &После.


&После("СформироватьДвиженияПередачаИнвентаряВЭксплуатацию")
Процедура Расш_СформироватьДвиженияПередачаИнвентаряВЭксплуатацию(ТаблицаМатериалы, ТаблицаСписанныеМатериалы, ТаблицаРеквизиты, Движения, Отказ)
    // Здесь мы можем напрямую работать с коллекцией Движения.Хозрасчетный,
    // имея на руках уже готовую ТаблицаМатериалы, что избавляет от лишних запросов к БД.
КонецПроцедуры

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

Типичные ошибки при программном изменении проводок

Подведем итог: для изменения счета в БП 3.0 мы используем подписку на событие, проверяем дополнительные реквизиты номенклатуры запросом и аккуратно корректируем коллекцию движений Хозрасчетный, не забывая про корректную установку субконто.

← На главную