Как изменить статус проведенного документа в 1С, если права на запись ограничены?

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

Рассмотрим частую задачу: менеджеры формируют документы реализации на основании заказов. Чтобы исключить изменение данных задним числом, права менеджеров настроены так, что после проведения документа любые изменения блокируются. Однако возникает необходимость отслеживать статус распечатки документа (например, флаг Распечатан). При попытке изменить этот статус система выдает ошибку, так как сохранение документа заблокировано правами доступа.

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

Решение 1: Использование привилегированного общего модуля

Это решение позволяет обойти проверку прав, выполнив сохранение реквизита на сервере с полными правами. Выясним, как это правильно реализовать:

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

Для файловых баз или старых конфигураций, где не используется клиент-серверный режим, можно применить программное включение привилегированного режима прямо в коде вызовом функции УстановитьПривилегированныйРежим(Истина) перед записью.

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

Посмотрим на пример реализации процедуры:


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

Решение 2: Хранение статуса в регистре сведений (без перезаписи документа)

Запись самого документа ради одного флага накладывает на него исключительную блокировку базы данных. Если с базой активно работают другие пользователи, могут возникать конфликты блокировок. Более безопасный и методологически правильный вариант — хранить статус распечатки в отдельном регистре сведений.

В конфигурации "Управление торговлей 10.3" можно использовать встроенный штатный механизм — Свойства и категории. Этот механизм позволяет привязывать к документам произвольные значения, которые физически сохраняются в специальном регистре сведений ЗначенияСвойствОбъектов. Достаточно дать менеджерам права на запись в этот регистр. Сам документ при этом не модифицируется, остается защищенным от изменений, а проблема прав решается полностью штатными средствами без изменения структуры метаданных.

Как реализовать раскраску и сортировку журнала при хранении статуса в регистре?

Поскольку УТ 10.3 работает на обычных формах, динамический вывод данных из регистра и раскраска строк реализуется через обработчик события табличного поля списка ПриПолученииДанных. Разберем алгоритм действий:

  1. В событии ПриПолученииДанных мы получаем коллекцию ОформленияСтрок.
  2. Собираем из нее массив ссылок видимых на экране документов.
  3. Выполняем один пакетный запрос к нашему регистру сведений (или регистру свойств) с отбором по этому массиву ссылок.
  4. Обходим результат запроса и, в зависимости от полученного статуса, применяем свойство ОформлениеСтроки.ЦветФона к нужной строке, а текстовое значение выводим в добавленную колонку табличного поля.

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

← На главную