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