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