Как программно изменить данные документа и движения регистра в закрытом периоде ERP без перепроведения

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

В процессе эксплуатации 1С:ERP Управление предприятием часто возникают ситуации, когда необходимо внести исправления в документы прошлых периодов. Стандартный путь через открытие периода и перепроведение документов влечет за собой необходимость перезакрытия месяца, что в крупных распределенных базах может занять значительное время и привести к изменению финансовых результатов. Разберем, как корректно внести изменения в реквизиты табличных частей и движения по регистрам накопления, минуя механизмы проверки даты запрета изменения.

Проблема изменения данных в закрытых периодах

Основная сложность заключается в том, что типовые механизмы БСП (Библиотеки стандартных подсистем), на которых базируется ERP, блокируют любую запись объекта, если его дата попадает в закрытый период. Даже если мы устанавливаем флаг ОбменДанными.Загрузка = Истина, этого часто бывает недостаточно, так как многочисленные подписки на события в ERP могут содержать дополнительные проверки или пытаться обновить связанные регистры, что вызовет ошибку доступа.

Рассмотрим ситуацию на примере документов Реализация товаров и услуг, Корректировка реализации и Возврат товаров от клиента. Нам требуется дозаполнить реквизиты в табличных частях и одновременно обновить данные в собственном (кастомном) регистре накопления, не затрагивая основные финансовые движения.

Шаг 1. Модификация объекта документа без перепроведения

Для того чтобы изменить данные в документе и при этом не инициировать процедуру его проведения (которая неизбежно потребует открытия периода), мы должны использовать режим записи Запись. Однако, чтобы система позволила сохранить объект в закрытом периоде, необходимо передать специальные инструкции в коллекцию ДополнительныеСвойства.

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


// Получаем объект документа по ссылке
ОбъектДокумента = СсылкаНаДокумент.ПолучитьОбъект();

// Устанавливаем режим загрузки, чтобы отключить большинство стандартных проверок
ОбъектДокумента.ОбменДанными.Загрузка = Истина;

// Добавляем специальный ключ для обхода даты запрета изменения (стандарт БСП)
ОбъектДокумента.ДополнительныеСвойства.Вставить("ПропуститьПроверкуЗапретаИзменения", Истина);

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

// Выполняем модификацию табличной части
Для Каждого СтрокаТЧ Из ОбъектДокумента.Товары Цикл
    // Например, заполняем наш служебный реквизит
    СтрокаТЧ.НашСлужебныйРеквизит = "НовоеЗначение";
КонецЦикла;

// Записываем объект СТРОГО в режиме записи, чтобы не вызвать движения
ОбъектДокумента.Записать(РежимЗаписиДокумента.Запись);

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

Шаг 2. Исправление движений в регистрах накопления

После того как данные в самом документе исправлены, нам необходимо актуализировать движения в регистрах. Если регистр является "своим" (добавленным при кастомизации), мы можем напрямую работать с его набором записей. Основная магия здесь также заключается в использовании ДополнительныеСвойства для набора записей.

Разберем алгоритм корректировки движений:


// Создаем набор записей по нашему регистру
НЗ = РегистрыНакопления.НашСобственныйРегистр.СоздатьНаборЗаписей();
НЗ.Отбор.Регистратор.Установить(СсылкаНаДокумент);

// Читаем существующие движения, чтобы не затереть их, а дополнить
НЗ.Прочитать();

// Вставляем ключ обхода даты запрета для набора записей
НЗ.ДополнительныеСвойства.Вставить("ПропуститьПроверкуЗапретаИзменения", Истина);

Для Каждого Запись Из НЗ Цикл
    // Выполняем корректировку ресурсов или реквизитов записи
    Запись.СлужебныйПараметр = "Обновлено";
КонецЦикла;

// Записываем набор. Флаг ПропуститьПроверкуЗапретаИзменения позволит 
// сделать это даже если период закрыт.
НЗ.Записать();

Выясним причину, по которой необходимо использовать именно ДополнительныеСвойства. В ERP подписки на события, проверяющие дату запрета изменения, подписаны на объект РегистрНакопленияНаборЗаписей. Внутри этих подписок происходит анализ коллекции ДополнительныеСвойства. Если они находят там флаг ПропуститьПроверкуЗапретаИзменения, то проверка игнорируется.

Особенности документов продажи в ERP

При работе с РеализацияТоваровУслуг или КорректировкаРеализации в ERP 2.5 и выше, система очень строго следит за целостностью данных. Если вы меняете данные в ТЧ, которые влияют на управленческий баланс или взаиморасчеты, простая запись объекта может быть недостаточной для того, чтобы система "забыла" о необходимости перепроведения.

Посмотрим на специфические ключи, которые могут быть полезны:

  1. ПерезаписыватьДвиженияПриЗаписи — если установить этот ключ в Ложь в дополнительных свойствах документа, система при записи не будет пытаться актуализировать стандартные движения, что критично для закрытого периода.
  2. ОтключитьОтражениеВОперативномУчете — помогает избежать фиксации изменений в регистрах оперативного учета, которые могут потребовать последующего перезакрытия.

Меры предосторожности и рекомендации

Проанализируем ситуацию с точки зрения рисков. Прямая правка данных в закрытом периоде — это "хирургическое" вмешательство. Чтобы не нарушить логику системы, придерживайтесь следующих правил:

Рассмотрим пример правильной структуры обработки:


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

Используя данный подход, вы сможете эффективно управлять данными в 1С:ERP, сохраняя стабильность системы и избегая избыточных регламентных операций по перезакрытию прошлых периодов.

← На главную