Почему внезапно очищаются записи регистра сведений при перепроведении документов?

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

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

Анализ исходной ситуации

Представим типичный сценарий: в конфигурации (например, 1С:Комплексная автоматизация 2.4) создан непериодический регистр сведений, подчиненный регистратору (например, документу РеализацияТоваровУслуг). Разработчик реализовал запись в этот регистр через модуль формы документа, используя событие ПриЗаписи. На первый взгляд, все работает корректно: пользователь открывает документ, нажимает «Провести и закрыть», и данные в регистре обновляются.

Однако проблема обнаруживается утром, когда выясняется, что после ночного перепроведения документов или групповой обработки записей в регистре больше нет. Проанализируем, почему это происходит.

Главная архитектурная ошибка: Логика в модуле формы

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

Выясним причину исчезновения данных в рассматриваемом кейсе:

  1. Бухгалтер или оператор запустил массовую отмену проведения и повторное проведение документов.
  2. При отмене проведения платформа, следуя логике механизмов движений, очищает все наборы записей, где данный документ является регистратором.
  3. При последующем программном проведении код, размещенный в ПриЗаписи формы, просто не выполняется.
  4. В итоге: старые записи удалены платформой, а новые не созданы, так как объектная модель ничего не знает о логике, «спрятанной» в форме.

Механизм работы с набором записей

Посмотрим на пример кода, который часто становится причиной «тихого» удаления данных, если он вызывается некорректно:


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

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

Рассмотрим более правильный, но все еще опасный в контексте формы код обновления записей:


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

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

НаборЗаписей.Записать();

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

Как правильно организовать запись в подчиненный регистр

Чтобы данные не пропадали, необходимо перенести логику формирования записей из модуля формы в модуль объекта документа или использовать подписки на события. Рассмотрим основные способы решения задачи.

Способ 1: Использование процедуры ОбработкаПроведения

Это стандартный путь для формирования любых движений документа. Процедура ОбработкаПроведения находится в модуле объекта и вызывается всегда, независимо от того, как проводится документ — вручную или программно.


Процедура ОбработкаПроведения(Отказ, РежимПроведения)
    // Очистка старых записей происходит автоматически, если в метаданных 
    // настроено удаление движений.
    
    ЗаписьРегистра = Движения.ДокументыРеализации.Добавить();
    ЗаписьРегистра.Период = Дата;
    ЗаписьРегистра.СтатусАкта = Перечисления.СтатусыАкта.АктСформирован;
    // Регистратор подставляется платформой автоматически
КонецПроцедуры

Способ 2: Подписка на событие (Event Subscription)

Если вы работаете с типовой конфигурацией (например, ERP или КА) и не хотите менять модуль объекта, лучше всего использовать подписку на событие ОбработкаПроведения или ПриЗаписи. Это обеспечит выполнение вашего кода при любом способе изменения документа.

Посмотрим, как выглядит обработчик такой подписки:


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

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

Важные нюансы и настройки метаданных

Разберем настройки самого регистра и документа в дереве метаданных, которые влияют на поведение системы:

  1. Свойство «Удаление движений» в документе:
    • Удалять автоматически — перед проведением платформа сама очищает все движения по всем регистрам, указанным в списке «Движения» документа.
    • Не удалять автоматически — разработчик должен сам заботиться об очистке старых записей.
  2. Режим записи регистра: Убедитесь, что ваш регистр сведений имеет режим записи Подчинение регистратору. В этом случае поле Регистратор становится обязательным измерением, и платформа берет на себя часть контроля за целостностью данных.
  3. Тестирование и исправление (ТиИ): В случае работы с файловой базой (формат .1CD), если данные исчезли без явных причин в коде, рекомендуется выполнить «Тестирование и исправление» с флагом «Реиндексация таблиц». Иногда в 1С записи могут «пропадать» из-за разрушения индексов, хотя физически они остаются в таблице.

Итоги

Проанализировав проблему «внезапного» исчезновения данных, мы выяснили, что причина всегда кроется в несоблюдении принципов объектно-ориентированной архитектуры 1С. Никогда не размещайте бизнес-логику, влияющую на состояние данных в регистрах, в модулях форм. Используйте события модуля объекта и подписки на события — это гарантирует сохранность ваших данных при любых регламентных операциях, будь то перепроведение документов или обмен данными.

← На главную