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

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

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

Проблема ручного изменения документов

Когда перед нами стоит задача ограничить проведение в 20 или более видах документов, классический подход «зайти в каждый модуль объекта» имеет ряд критических недостатков:

  1. Высокая трудоемкость: необходимо добавлять каждый документ в расширение, создавать программные прерывания (Hooks) и прописывать логику.
  2. Сложность обновления: чем больше объектов изменено в расширении, тем сложнее становится процесс обновления конфигурации.
  3. Риск ошибок: легко пропустить один из документов или допустить опечатку в коде при многократном копировании.

Проанализируем ситуацию: нам нужно решение, которое будет работать автоматически для любого документа, где присутствует реквизит НаправлениеДеятельности.

Универсальное решение: Подписка на событие

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

1. Создадим новую подписку на событие в конфигурации или расширении. Назовем ее, например, КонтрольСтатусаНаправленияДеятельностиПриПроведении.

2. В поле Источник выберем тип ДокументОбъект. Это позволит обработчику срабатывать при проведении любого документа системы.

3. В поле Событие выберем ОбработкаПроведения.

4. Создадим общий модуль (если его нет) с установленными свойствами Сервер и Вызов сервера, где будет располагаться процедура-обработчик.

Программная реализация проверки

Теперь разберем код обработчика. Основная сложность заключается в том, что не у всех документов есть реквизит НаправлениеДеятельности. Чтобы избежать ошибок исполнения (Runtime errors), мы должны использовать проверку метаданных.


Процедура КонтрольСтатусаНаправленияДеятельностиПриПроведении(Источник, Отказ, РежимПроведения) Экспорт
    
    // Проверяем наличие реквизита в шапке документа через метаданные
    МетаданныеДокумента = Источник.Метаданные();
    РеквизитНаправление = МетаданныеДокумента.Реквизиты.Найти("НаправлениеДеятельности");
    
    Если РеквизитНаправление <> Неопределено Тогда
        ПроверитьСтатусНаправления(Источник.НаправлениеДеятельности, Отказ);
    КонецЕсли;
    
    // Важно: направление деятельности часто встречается в табличных частях
    Если Не Отказ Тогда
        Для Каждого ТЧ Из МетаданныеДокумента.ТабличныеЧасти Цикл
            РеквизитТЧ = ТЧ.Реквизиты.Найти("НаправлениеДеятельности");
            Если РеквизитТЧ <> Неопределено Тогда
                ИмяТЧ = ТЧ.Имя;
                Для Каждого СтрокаТЧ Из Источник[ИмяТЧ] Цикл
                    ПроверитьСтатусНаправления(СтрокаТЧ.НаправлениеДеятельности, Отказ);
                    Если Отказ Тогда Прервать; КонецЕсли;
                КонецЦикла;
            КонецЕсли;
            Если Отказ Тогда Прервать; КонецЕсли;
        КонецЦикла;
    КонецЕсли;

КонецПроцедуры

Процедура ПроверитьСтатусНаправления(ЗначениеНаправления, Отказ)
    
    Если ЗначениеЗаполнено(ЗначениеНаправления) Тогда
        // Обращаемся к статусу направления. 
        // В типовых решениях (ERP, КА) статус может быть перечислением
        Если ЗначениеНаправления.Статус = ПредопределенноеЗначение("Перечисление.СтатусыНаправленийДеятельности.НеИспользуется") Тогда
            ТекстСообщения = СтрШаблон("Проведение запрещено! Направление деятельности '%1' имеет статус 'Не используется'.", ЗначениеНаправления);
            ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстСообщения);
            Отказ = Истина;
        КонецЕсли;
    КонецЕсли;
    
КонецПроцедуры

Оптимизация производительности (Кэширование)

Если документов в базе много, постоянное обращение к реквизиту Статус через точку (ЗначениеНаправления.Статус) может замедлить проведение из-за лишних запросов к базе данных. Проанализируем, как это оптимизировать.

Рекомендуется создать Модуль повторного использования, в котором будет функция, возвращающая соответствие ссылок и их статусов. Это позволит системе один раз прочитать данные о статусах и использовать их для всех строк документа мгновенно.

Альтернативный метод: Контроль на уровне регистра

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

Преимущества этого метода:

Недостатки: пользователь получит ошибку уже после того, как документ попытается сформировать движения, что иногда сложнее диагностировать.

Использование механизма RLS

Выясним, можно ли решить задачу без программирования. В современных конфигурациях (ERP 2.5, УТ 11.5) можно настроить RLS (Row Level Security) — ограничение доступа на уровне записей. Вы можете настроить профиль групп доступа таким образом, чтобы пользователям было запрещено изменение документов, где значение НаправлениеДеятельности.Статус равно Не используется. Однако этот метод требует тщательной настройки прав и может существенно снизить производительность системы при больших объемах данных.

Выводы и рекомендации

Для реализации качественного запрета проведения мы рекомендуем следовать следующим правилам:

  1. Используйте Подписку на событие для типа ДокументОбъект, чтобы не загромождать расширение лишними объектами.
  2. Обязательно проверяйте метаданные, так как состав реквизитов у разных документов отличается.
  3. Не забывайте проверять табличные части, так как аналитика часто разносится построчно.
  4. Для предотвращения выбора новых элементов используйте событие ОбработкаВыбора в формах или настройку связей параметров выбора в самих реквизитах справочника.

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

← На главную