Как включить перетаскивание ячеек в табличном документе на управляемых формах без разрешения редактирования

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

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

Анализируем причину блокировки перетаскивания

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

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

Шаг 1. Программная настройка свойств элемента формы

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


&НаКлиенте
Процедура НастроитьДоступностьПеретаскивания()
    // Устанавливаем свойства именно ЭЛЕМЕНТА формы
    Элементы.ТабличныйДокумент.Редактирование = Истина;
    Элементы.ТабличныйДокумент.ТолькоПросмотр = Ложь;
    
    // Снимаем общую защиту документа, чтобы разрешить операции Drag-and-Drop
    Элементы.ТабличныйДокумент.Защита = Ложь;
КонецПроцедуры

Важно понимать, что установка Редактирование = Истина — это ключевой момент, который «оживляет» механизм перетаскивания. Без этого никакие дальнейшие действия не принесут результата.

Шаг 2. Блокировка интерактивного изменения ячеек

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


&НаКлиенте
Процедура ТабличныйДокументВыбор(Элемент, Область, СтандартнаяОбработка)
    // Отключаем стандартный вход в режим редактирования ячейки
    СтандартнаяОбработка = Ложь;
    
    // Здесь можно реализовать логику расшифровки, если она требуется
    ПосмотретьРасшифровку(Область.Расшифровка);
КонецПроцедуры

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


&НаКлиенте
Процедура ТабличныйДокументПриНачалеРедактирования(Элемент, СтандартнаяОбработка)
    // Запрещаем ввод текста в любую ячейку
    СтандартнаяОбработка = Ложь;
КонецПроцедуры

Шаг 3. Тонкая настройка параметров перетаскивания

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

  1. РазрешитьНачалоПеретаскивания — позволяет пользователю «захватить» ячейку.
  2. РазрешитьПеретаскивание — позволяет «сбросить» данные в область таблицы.

Рассмотрим пример программной установки этих признаков:


Элементы.ТабличныйДокумент.РазрешитьНачалоПеретаскивания = Истина;
Элементы.ТабличныйДокумент.РазрешитьПеретаскивание = Истина;

Шаг 4. Управление защитой на уровне областей

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

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


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

Особенности платформы 8.3.15 и выше

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

ЭтаФорма.ТекущийЭлемент = Элементы.ТабличныйДокумент;

Подведем итог: для реализации перетаскивания в защищенном табличном документе на управляемых формах мы используем «открытые» свойства элемента формы (Редактирование = Истина), но жестко пресекаем любые попытки изменения данных через обработчики событий Выбор и ПриНачалеРедактирования, устанавливая СтандартнаяОбработка = Ложь. Такой подход обеспечивает отличный пользовательский опыт, сохраняя целостность отображаемой информации.

← На главную