Как массово снять право 'Интерактивное удаление' для документов в ролях 1С, избегая нежелательных изменений?

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

При работе с конфигурациями 1С, особенно версий 8.2 и ранних 8.3, нередко возникает задача по корректировке прав доступа пользователей. Одна из таких задач – массовое снятие права "Интерактивное удаление" для всех документов в определенной роли. Казалось бы, простая операция, но на практике она может столкнуться с неожиданными препятствиями в стандартном конфигураторе. Мы рассмотрим, почему возникает эта проблема и как ее эффективно решить.

Суть проблемы: Пользователи сталкиваются с ситуацией, когда при попытке снять флажок "Интерактивное удаление" на верхнем уровне ("Документы") в редакторе прав роли, флажок оказывается серым. Это означает, что для некоторых документов в этой роли право есть, а для некоторых нет. При попытке кликнуть на серый флажок, вместо его снятия, он сначала становится активным (устанавливается для всех документов), и что критично – одновременно устанавливаются права на "Чтение", "Изменение" и "Удаление" для ВСЕХ ДОКУМЕНТОВ в этой роли. Естественно, такой побочный эффект крайне нежелателен, так как нарушает существующие тонкие настройки прав доступа.

Такое поведение наблюдается в конфигураторе 1С:Предприятия 8.2 (например, на платформе 8.2.16.368) и может проявляться в аналогичных условиях на более новых платформах, запущенных в режиме совместимости. Стандартные инструменты, такие как редактор "Все роли" или различные внешние обработки для назначения ролей, часто не могут решить эту проблему без нежелательных побочных эффектов, поскольку они используют тот же механизм работы с правами, что и основной редактор роли.

Решение 1: Попытка использования стандартных средств конфигуратора (и почему они не подходят)

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

  1. Редактор роли (узел "Документы"):

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

    Если для части документов право "Интерактивное удаление" установлено, а для другой части нет, этот флажок на верхнем уровне отображается серым. Это индикатор смешанного состояния. При попытке снять серый флажок, конфигуратор интерпретирует это действие как команду "установить право для всех" (чтобы привести их к одному состоянию), а затем уже при повторном клике позволит снять его. Хуже того, в определенных версиях платформы или конфигураций, такое действие автоматически устанавливает также права "Чтение", "Изменение" и "Удаление" для всех документов, что является серьезным нарушением логики существующих прав.

    Изменение права для каждого документа по отдельности, конечно, возможно. Мы можем заходить в каждый документ, снимать галку "Интерактивное удаление", сохранять роль. Однако, при наличии десятков или сотен документов, такой подход становится непрактичным и крайне трудоемким. Этот метод не подходит для массовых операций.

  2. Редактор "Все роли" (Конфигурация -> Все роли):

    Этот инструмент позволяет нам просматривать и редактировать права для всех ролей на все объекты метаданных в одном окне, что значительно удобнее для обзорного анализа. Мы выбираем нужную роль, переходим на вкладку "Документы" и пытаемся найти там флажок "Интерактивное удаление" для всего раздела "Документы".

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

  3. Внешние обработки для управления правами:

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

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

Решение 2: Программное изменение прав через выгрузку конфигурации в XML-файлы

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

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

Шаг 1: Подготовка и выгрузка конфигурации в файлы

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

  1. Откройте конфигурацию в режиме Конфигуратора.
  2. Перейдите в меню Конфигурация -> Сохранить конфигурацию в файлы....
  3. В открывшемся диалоговом окне укажите пустую папку на вашем диске, куда будет выгружена конфигурация. Мы рекомендуем создать новую папку, например, "Config_XML_Dump".
  4. Нажмите кнопку "Сохранить". Дождитесь завершения процесса выгрузки. Это может занять некоторое время в зависимости от размера вашей конфигурации.

После успешной выгрузки в указанной папке вы увидите множество подпапок и файлов. Нас интересует папка с именем Roles.

Шаг 2: Программная модификация XML-файлов ролей

Теперь, когда у нас есть доступ к файлам, мы можем написать скрипт, который пройдет по всем XML-файлам ролей и изменит значение права "Delete" (удаление) на false.

Для выполнения этого шага мы будем использовать внутренний язык 1С (либо любой другой язык программирования, который умеет работать с файлами и XML, но для удобства и интеграции с платформой, 1С-скрипт предпочтителен). Мы можем создать временную внешнюю обработку в 1С для выполнения этого скрипта.

Рассмотрим пример кода на встроенном языке 1С, который выполнит эту задачу:

  1. Создайте новую внешнюю обработку в конфигураторе 1С.
  2. Откройте модуль объекта или модуль формы этой обработки.
  3. Вставьте следующий код:
  4. 
    // Определите путь к папке, куда была выгружена конфигурация.
    // Замените "C:\Config_XML_Dump" на ваш актуальный путь.
    ПутьКВыгрузкеКонфигурации = "C:\Config_XML_Dump"; 
    ПапкаРолей = ПутьКВыгрузкеКонфигурации + "\Roles";
    
    // Проверяем, существует ли папка с ролями
    Если НЕ ФайлСуществует(ПапкаРолей) Тогда
        Сообщить("Ошибка: Папка с ролями не найдена по пути: " + ПапкаРолей);
        Возврат;
    КонецЕсли;
    
    // Ищем все XML-файлы внутри папки Roles и всех ее подпапок
    // (роли могут быть разложены по подпапкам в зависимости от их структуры)
    НайденныеФайлы = НайтиФайлы(ПапкаРолей, "*.xml", ИСТИНА);
    
    Если НайденныеФайлы.Количество() = 0 Тогда
        Сообщить("В папке " + ПапкаРолей + " не найдено XML-файлов ролей.");
        Возврат;
    КонецЕсли;
    
    Сообщить("Найдено файлов ролей для обработки: " + НайденныеФайлы.Количество());
    Сообщить("Начинаем обработку...");
    
    Для Каждого Файл Из НайденныеФайлы Цикл
        Текст = Новый ТекстовыйДокумент;
        Попытка
            // Читаем файл в кодировке UTF-8. Это стандартная кодировка для XML 1С.
            Текст.Прочитать(Файл.ПолноеИмя, "utf-8");
            СтрокаXML = Текст.ПолучитьТекст();
            НоваяСтрокаXML = СтрокаXML;
            
            // Переменная для подсчета изменений в текущем файле
            КоличествоИзмененийВФайле = 0;
    
            // Ищем все вхождения тега Delete и меняем соответствующее значение
            // Право "Интерактивное удаление" в файле XML представлено тегом Delete
            // и следующим за ним тегом true или false
            ПозицияПоиска = 1;
            Пока ИСТИНА Цикл
                // Ищем тег Delete
                ИтераторНачалаТега = СтрНайти(НоваяСтрокаXML, "Delete", , ПозицияПоиска);
                Если ИтераторНачалаТега = 0 Тогда
                    Прервать; // Больше не найдено вхождений
                КонецЕсли;
                
                // Находим позицию после тега Delete
                ПозицияПослеТегаDelete = ИтераторНачалаТега + СтрДлина("Delete");
                
                // Ищем тег  за найденным Delete
                ИтераторНачалоЗначения = СтрНайти(НоваяСтрокаXML, "", , ПозицияПослеТегаDelete);
                Если ИтераторНачалоЗначения = 0 Тогда
                    // Не найдено соответствующее значение, переходим к следующему поиску "Delete"
                    ПозицияПоиска = ПозицияПослеТегаDelete + 1;
                    Продолжить;
                КонецЕсли;
                
                // Ищем закрывающий тег 
                ИтераторКонецЗначения = СтрНайти(НоваяСтрокаXML, "", , ИтераторНачалоЗначения);
                Если ИтераторКонецЗначения = 0 Тогда
                    // Не найдено закрывающего тега, переходим к следующему поиску "Delete"
                    ПозицияПоиска = ИтераторНачалоЗначения + 1;
                    Продолжить;
                КонецЕсли;
                
                // Извлекаем текущее значение (true/false)
                ТекущееЗначение = Сред(НоваяСтрокаXML, ИтераторНачалоЗначения + СтрДлина(""), ИтераторКонецЗначения - (ИтераторНачалоЗначения + СтрДлина("")));
    
                // Если текущее значение "true", меняем его на "false"
                Если СтрСравнить(ТекущееЗначение, "true", Ложь) = 0 Тогда // Ложь для регистронезависимого сравнения
                    НоваяСтрокаXML = Лев(НоваяСтрокаXML, ИтераторНачалоЗначения + СтрДлина("") - 1) 
                                    + "false" 
                                    + Сред(НоваяСтрокаXML, ИтераторКонецЗначения);
                    КоличествоИзмененийВФайле = КоличествоИзмененийВФайле + 1;
                    // Так как строка изменилась, нам нужно скорректировать позицию для следующего поиска
                    ПозицияПоиска = ИтераторКонецЗначения + СтрДлина("false") - СтрДлина(ТекущееЗначение);
                Иначе
                    // Значение уже "false" или другое, просто двигаемся дальше
                    ПозицияПоиска = ИтераторКонецЗначения + СтрДлина("");
                КонецЕсли;
            КонецЦикла;
            
            // Если были изменения, записываем измененный текст обратно в файл
            Если КоличествоИзмененийВФайле > 0 Тогда
                Текст.УстановитьТекст(НоваяСтрокаXML);
                Текст.Записать(Файл.ПолноеИмя, "utf-8");
                Сообщить("Файл " + Файл.Имя + " успешно обновлен. Изменений: " + КоличествоИзмененийВФайле);
            Иначе
                Сообщить("В файле " + Файл.Имя + " изменения не потребовались.");
            КонецЕсли;
    
        Исключение
            Сообщить("Ошибка при обработке файла " + Файл.ПолноеИмя + ": " + ОписаниеОшибки());
        КонецПопытки;
    КонецЦикла;
    
    Сообщить("Обработка файлов завершена.");
    
       // Внимание: Роль "Полные права" может быть специфичной и не всегда корректно выгружаться/загружаться
       // стандартными средствами из файлов из-за внутренних механизмов платформы.
       // После общей загрузки конфигурации из файлов, если вы изменяли эту роль,
       // возможно, потребуется вручную проверить и скорректировать ее права в конфигураторе.
       // В данном случае, мы меняем права для "Delete", которое относится к интерактивному удалению
       // и редко ставится для "Полных прав", но стоит об этом помнить.
    
  5. Запустите обработку в режиме 1С:Предприятие (если это внешняя обработка) или выполните ее в конфигураторе (если это, например, временный скрипт в Общем модуле).

Пояснения к коду:

Данный скрипт гарантирует, что право "Интерактивное удаление" будет изменено только там, где оно было установлено на true, и не затронет другие права, связанные с чтением, изменением или удалением объектов, поскольку он оперирует только конкретным тегом Delete.

Шаг 3: Загрузка измененных прав обратно в конфигурацию

После того как XML-файлы ролей были успешно модифицированы, нам необходимо загрузить их обратно в информационную базу.

  1. Вернитесь в Конфигуратор.
  2. Перейдите в меню Конфигурация -> Загрузить конфигурацию из файлов....
  3. Укажите ту же папку ("Config_XML_Dump"), из которой вы выгружали конфигурацию и в которой производили изменения.
  4. Нажмите кнопку "Загрузить". Конфигуратор прочитает измененные файлы и предложит обновить конфигурацию.
  5. После загрузки, когда конфигурация базы данных будет обновлена, обязательно сохраните конфигурацию базы данных (F7 или кнопка "Обновить конфигурацию базы данных").

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

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

  1. В конфигураторе тестовой базы сохраните конфигурацию в файл .cf (Конфигурация -> Сохранить конфигурацию в файл...).
  2. В конфигураторе рабочей базы откройте меню Конфигурация -> Сравнить, объединить с конфигурацией из файла....
  3. Выберите сохраненный .cf файл.
  4. В окне сравнения снимите все флажки, оставив отмеченными только изменения, касающиеся прав доступа в ролях (обычно они отображаются как изменения в объектах типа "Роль").
  5. Выполните объединение.
Это позволит перенести только измененные права, минимизируя риски. Однако, если конфигурации сильно отличаются, или вы не уверены в корректности выборочного объединения, полный перенос всей конфигурации после успешного тестирования на копии базы может быть более безопасным подходом.

Дополнительные рекомендации и важные моменты

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

← На главную