Как запретить перенос групп (папок) внутри справочника в 1С?

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

Разберем распространенную ситуацию, с которой сталкиваются разработчики и администраторы баз данных 1С: пользователи случайно, сами того не замечая, переносят группы (папки) внутри иерархического справочника с помощью мыши (механизм drag-and-drop). Это приводит к нарушению структуры данных и путанице. Рассмотрим подробнее, какими способами мы можем запретить перенос папок, сохранив при этом удобство работы с системой.

Глобальное отключение перетаскивания для всего списка

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

  1. РазрешитьНачалоПеретаскивания (в английском синтаксисе EnableStartDrag) — разрешает или запрещает захватывать данные из этого списка для переноса.
  2. РазрешитьПеретаскивание (в английском синтаксисе EnableDrag) — разрешает или запрещает сбрасывать перетаскиваемые данные в этот список.

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

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

Если нам необходимо запретить перенос исключительно групп, оставив возможность drag-and-drop для элементов, мы используем обработчики событий самой формы списка или дерева. Разберем по шагам, как это реализовать.

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

Мы можем программно обойти этот массив, проверить, является ли хотя бы одна из ссылок группой (используя стандартное свойство ЭтоГруппа), и если да — отменить действие. При этом курсор мыши изменится на запрещающий знак, визуально показывая пользователю, что операция недоступна.

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


&НаКлиенте
Процедура СписокПроверкаПеретаскивания(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Поле)
    
    // Проверяем, что именно перетаскивается
    Если ТипЗнч(ПараметрыПеретаскивания.Значение) = Тип("Массив") Тогда
        Для Каждого ПеретаскиваемаяСсылка Из ПараметрыПеретаскивания.Значение Цикл
            // Если перетаскивается группа, отменяем действие
            Если ОбщегоНазначенияСервер.ЭтоГруппа(ПеретаскиваемаяСсылка) Тогда
                ПараметрыПеретаскивания.Действие = ДействиеПеретаскивания.Отмена;
                Прервать;
            КонецЕсли;
        КонецЦикла;
    КонецЕсли;
    
КонецПроцедуры

Важное замечание: вызов свойства ЭтоГруппа напрямую на клиенте для ссылки невозможен, поэтому в примере выше используется серверный вызов (например, через общий модуль) или предварительное получение данных о строке. Если вы работаете с управляемой формой, оптимальнее получать данные текущей строки из данных самой формы, чтобы избежать лишних серверных вызовов в динамическом событии.

Запрет на уровне базы данных (модуль объекта)

Выясним причину, по которой описанных выше клиентских запретов может быть недостаточно. Перенос методом Drag-and-Drop — это лишь визуальный способ изменения реквизита Родитель. Опытный пользователь может просто открыть карточку группы и изменить поле "Родитель" вручную. Кроме того, родитель может быть изменен программно при различных загрузках данных из Excel или других баз.

Для создания надежной и железобетонной защиты необходимо добавить проверку непосредственно в модуль самого справочника. Рассмотрим подробнее использование события ПередЗаписью.

В этом обработчике мы проверяем следующее условие: если текущий записываемый объект является группой, и это не создание новой папки (то есть объект уже существует в базе), мы сравниваем новое значение реквизита Родитель с тем значением, которое сейчас сохранено в базе данных. Если они отличаются, значит, происходит попытка перемещения. В этом случае мы устанавливаем параметр Отказ в значение Истина.

Посмотрим на пример серверного кода в модуле объекта справочника:


Процедура ПередЗаписью(Отказ)
    
    // Проверяем, что объект является группой и он уже записан в базу
    Если ЭтоГруппа И Не ЭтоНовый() Тогда
        
        // Получаем старое значение родителя из базы данных
        СтарыйРодитель = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Ссылка, "Родитель");
        
        // Сравниваем новое значение с тем, что в базе
        Если Родитель <> СтарыйРодитель Тогда
            Отказ = Истина;
            Сообщение = Новый СообщениеПользователю;
            Сообщение.Текст = "Перемещение групп (папок) в данном справочнике строго запрещено!";
            Сообщение.Поле = "Родитель";
            Сообщение.Сообщить();
        КонецЕсли;
        
    КонецЕсли;
    
КонецПроцедуры

Дополнительные ограничения в интерфейсе и правах доступа

Чтобы избежать путаницы и не заставлять пользователей получать ошибку при попытке записи, рекомендуется сделать реквизит Родитель в самой форме группы недоступным для редактирования. Установите для этого элемента управления на форме свойство ТолькоПросмотр или Доступность в значение Ложь. Таким образом, пользователи даже не смогут попытаться выбрать другую папку внутри карточки группы.

Если вы работаете в сложных корпоративных системах (например, ERP или Комплексная автоматизация), запрет на перемещение групп часто настраивается вообще без программирования — на уровне прав доступа. Через профили групп доступа или механизм RLS (Record Level Security) пользователям просто снимают права на изменение поля Родитель для записей, у которых установлен признак группы. Это автоматически делает невозможным как перетаскивание, так и ручное изменение, и система сама сформирует корректный интерфейс, заблокировав нужные поля.

Используя комплексный подход (ограничение Drag-and-Drop на форме + строгая проверка ПередЗаписью в модуле объекта), мы гарантируем, что иерархия наших групп останется в полной безопасности и не будет нарушена случайными действиями пользователей.

← На главную