Как программно изменить проводки в документе «Поступление товаров и услуг» и почему не сохраняются изменения?

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

В практике разработки на платформе «1С:Предприятие 8.3» часто возникает задача модификации движений документа «на лету». Типичная ситуация: бухгалтерии требуется специфический расчет валютной суммы по внутреннему курсу, который отличается от курса ЦБ. Программист создает расширение, подключается к процедуре ОбработкаПроведения, пишет код изменения коллекции Движения, но после завершения транзакции проводки остаются прежними. Рассмотрим подробно, почему это происходит и как правильно реализовать задачу.

Анализируем причину: почему изменения в «Движениях» не сохраняются?

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

  1. Флаг записи набора записей: Для каждого регистра в коллекции Движения (например, Движения.Хозрасчетный) существует свойство Записывать. Если в основной конфигурации этот флаг был сброшен или не установлен в Истина после ваших манипуляций, платформа просто не инициирует запись набора в базу данных.
  2. Повторная перезапись типовыми механизмами: В современных конфигурациях (БП 3.0, ERP, КА) процедура ОбработкаПроведения часто является лишь «верхушкой айсберга». Основная работа по формированию таблиц движений происходит в общих модулях, которые могут вызываться после выполнения кода в расширении или использовать механизмы отложенного проведения.
  3. Использование «Дополнительных свойств»: Типовые механизмы часто формируют данные не напрямую в регистр, а в специальную структуру ДополнительныеСвойства внутри объекта документа. После выхода из процедуры проведения система берет данные из этой структуры и записывает их в регистры, затирая любые ручные правки коллекции Движения.

Решение №1: Принудительная установка флага записи

Проанализируем самый простой способ исправления ситуации в расширении. Чтобы изменения зафиксировались, необходимо явно указать системе, что набор записей модифицирован и требует сохранения. Вызов метода Записать() внутри процедуры проведения обычно не рекомендуется (так как это происходит внутри транзакции автоматически), но установка свойства Записывать обязательна.

Рассмотрим пример правильного кода в расширении:


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

    // Предположим, у нас есть реквизит КурсВзаиморасчетовДляОтчетовКомитенту
    Если ЗначениеЗаполнено(ЭтотОбъект.КурсВзаиморасчетовДляОтчетовКомитенту) Тогда
        
        Для Каждого Проводка Из Движения.Хозрасчетный Цикл
            // Выполняем ваш расчет суммы по нужному курсу
            // Пример: Проводка.ВалютнаяСуммаКт = Проводка.Сумма / ЭтотОбъект.КурсВзаиморасчетовДляОтчетовКомитенту;
            
            // Тестовая установка значения
            Проводка.ВалютнаяСуммаКт = 100; 
        КонецЦикла;
        
        // КРИТИЧЕСКИ ВАЖНЫЙ МОМЕНТ:
        Движения.Хозрасчетный.Записывать = Истина;
        
    КонецЕсли;

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

Решение №2: Использование флага «РучнаяКорректировка»

Выясним, почему система иногда «откатывает» суммы к стандартным при перепроведении или выполнении регламентных операций. В типовой конфигурации Бухгалтерия предприятия заложена логика: если движения не соответствуют стандартным алгоритмам, они могут быть пересчитаны. Чтобы «узаконить» свои правки, можно программно установить флаг ручной корректировки.

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


// В коде изменения проводок добавляем установку флага
ЭтотОбъект.РучнаяКорректировка = Истина;
// Это заблокирует автоматический пересчет движений типовыми механизмами в будущем

Важно: У этого способа есть побочный эффект — пользователь увидит включенную кнопку «Ручная корректировка» в документе, и автоматические механизмы обновления проводок (например, при изменении количества в табличной части) перестанут работать до тех пор, пока флаг не будет снят.

Решение №3: Изменение структуры данных до записи (Метод «Вместо»)

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

Рассмотрим порядок действий:

  1. Найдем в модуле документа или общем модуле процедуру, отвечающую за заполнение набора записей (например, ИнициализироватьДанныеДокумента или СформироватьТаблицуХозрасчетный).
  2. Используем аннотацию &Вместо или &После для этой процедуры в расширении.
  3. Внесем изменения в структуру ДополнительныеСвойства.ТаблицыДляДвижений.

Посмотрим на пример логики перехвата данных в таблице:


// Пример модификации таблицы значений в ДополнительныхСвойствах
ТаблицаПроводок = ДополнительныеСвойства.ТаблицыДляДвижений.ТаблицаХозрасчетный;
Для Каждого СтрокаТаблицы Из ТаблицаПроводок Цикл
    // Здесь мы меняем данные еще до того, как они стали проводками в регистре
    СтрокаТаблицы.ВалютнаяСуммаКт = СтрокаТаблицы.Сумма / НужныйКурс;
КонецЦикла;

Соблюдение баланса и валютный учет

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

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

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

← На главную