В процессе эксплуатации 1С:ERP Управление предприятием часто возникают ситуации, когда необходимо внести исправления в документы прошлых периодов. Стандартный путь через открытие периода и перепроведение документов влечет за собой необходимость перезакрытия месяца, что в крупных распределенных базах может занять значительное время и привести к изменению финансовых результатов. Разберем, как корректно внести изменения в реквизиты табличных частей и движения по регистрам накопления, минуя механизмы проверки даты запрета изменения.
Основная сложность заключается в том, что типовые механизмы БСП (Библиотеки стандартных подсистем), на которых базируется ERP, блокируют любую запись объекта, если его дата попадает в закрытый период. Даже если мы устанавливаем флаг ОбменДанными.Загрузка = Истина, этого часто бывает недостаточно, так как многочисленные подписки на события в ERP могут содержать дополнительные проверки или пытаться обновить связанные регистры, что вызовет ошибку доступа.
Рассмотрим ситуацию на примере документов Реализация товаров и услуг, Корректировка реализации и Возврат товаров от клиента. Нам требуется дозаполнить реквизиты в табличных частях и одновременно обновить данные в собственном (кастомном) регистре накопления, не затрагивая основные финансовые движения.
Для того чтобы изменить данные в документе и при этом не инициировать процедуру его проведения (которая неизбежно потребует открытия периода), мы должны использовать режим записи Запись. Однако, чтобы система позволила сохранить объект в закрытом периоде, необходимо передать специальные инструкции в коллекцию ДополнительныеСвойства.
Проанализируем программный код, который позволяет это сделать:
// Получаем объект документа по ссылке
ОбъектДокумента = СсылкаНаДокумент.ПолучитьОбъект();
// Устанавливаем режим загрузки, чтобы отключить большинство стандартных проверок
ОбъектДокумента.ОбменДанными.Загрузка = Истина;
// Добавляем специальный ключ для обхода даты запрета изменения (стандарт БСП)
ОбъектДокумента.ДополнительныеСвойства.Вставить("ПропуститьПроверкуЗапретаИзменения", Истина);
// Для некоторых документов ERP (например, Реализация) может потребоваться
// имитация изменения технического состояния
ОбъектДокумента.ДополнительныеСвойства.Вставить("ИзменилосьТолькоСостояниеПереходаПраваСобственности", Истина);
// Выполняем модификацию табличной части
Для Каждого СтрокаТЧ Из ОбъектДокумента.Товары Цикл
// Например, заполняем наш служебный реквизит
СтрокаТЧ.НашСлужебныйРеквизит = "НовоеЗначение";
КонецЦикла;
// Записываем объект СТРОГО в режиме записи, чтобы не вызвать движения
ОбъектДокумента.Записать(РежимЗаписиДокумента.Запись);
Важно помнить: использование ОбменДанными.Загрузка = Истина отключает проверку заполнения обязательных реквизитов и выполнение кода в процедурах ПередЗаписью и ПриЗаписи, если там прописано условие отсечки по этому флагу. Это позволяет избежать инициации фоновых заданий по расчету себестоимости и других механизмов ERP.
После того как данные в самом документе исправлены, нам необходимо актуализировать движения в регистрах. Если регистр является "своим" (добавленным при кастомизации), мы можем напрямую работать с его набором записей. Основная магия здесь также заключается в использовании ДополнительныеСвойства для набора записей.
Разберем алгоритм корректировки движений:
// Создаем набор записей по нашему регистру
НЗ = РегистрыНакопления.НашСобственныйРегистр.СоздатьНаборЗаписей();
НЗ.Отбор.Регистратор.Установить(СсылкаНаДокумент);
// Читаем существующие движения, чтобы не затереть их, а дополнить
НЗ.Прочитать();
// Вставляем ключ обхода даты запрета для набора записей
НЗ.ДополнительныеСвойства.Вставить("ПропуститьПроверкуЗапретаИзменения", Истина);
Для Каждого Запись Из НЗ Цикл
// Выполняем корректировку ресурсов или реквизитов записи
Запись.СлужебныйПараметр = "Обновлено";
КонецЦикла;
// Записываем набор. Флаг ПропуститьПроверкуЗапретаИзменения позволит
// сделать это даже если период закрыт.
НЗ.Записать();
Выясним причину, по которой необходимо использовать именно ДополнительныеСвойства. В ERP подписки на события, проверяющие дату запрета изменения, подписаны на объект РегистрНакопленияНаборЗаписей. Внутри этих подписок происходит анализ коллекции ДополнительныеСвойства. Если они находят там флаг ПропуститьПроверкуЗапретаИзменения, то проверка игнорируется.
При работе с РеализацияТоваровУслуг или КорректировкаРеализации в ERP 2.5 и выше, система очень строго следит за целостностью данных. Если вы меняете данные в ТЧ, которые влияют на управленческий баланс или взаиморасчеты, простая запись объекта может быть недостаточной для того, чтобы система "забыла" о необходимости перепроведения.
Посмотрим на специфические ключи, которые могут быть полезны:
Ложь в дополнительных свойствах документа, система при записи не будет пытаться актуализировать стандартные движения, что критично для закрытого периода.Проанализируем ситуацию с точки зрения рисков. Прямая правка данных в закрытом периоде — это "хирургическое" вмешательство. Чтобы не нарушить логику системы, придерживайтесь следующих правил:
ВыручкаИПродажи или СебестоимостьТоваров. Если движения не будут соответствовать документу, отчеты покажут неверные данные.Рассмотрим пример правильной структуры обработки:
НачатьТранзакцию();
Попытка
// 1. Изменяем документ
Объект = Ссылка.ПолучитьОбъект();
Объект.ОбменДанными.Загрузка = Истина;
Объект.ДополнительныеСвойства.Вставить("ПропуститьПроверкуЗапретаИзменения", Истина);
// ... логика изменения ...
Объект.Записать(РежимЗаписиДокумента.Запись);
// 2. Изменяем движения
НЗ = РегистрыНакопления.ВашРегистр.СоздатьНаборЗаписей();
НЗ.Отбор.Регистратор.Установить(Ссылка);
НЗ.ДополнительныеСвойства.Вставить("ПропуститьПроверкуЗапретаИзменения", Истина);
НЗ.Прочитать();
// ... логика изменения ...
НЗ.Записать();
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ЗаписатьЛогОшибки(ОписаниеОшибки());
КонецПопытки;
Используя данный подход, вы сможете эффективно управлять данными в 1С:ERP, сохраняя стабильность системы и избегая избыточных регламентных операций по перезакрытию прошлых периодов.