При переходе с обычных форм на управляемые многие разработчики сталкиваются с тем, что привычные механизмы работы с табличным документом ведут себя иначе. Одной из таких проблем является механизм Drag-and-Drop (перетаскивание). В толстом клиенте достаточно было манипулировать свойством ТолькоПросмотр, но в управляемом интерфейсе блокировка редактирования документа намертво отключает и возможность перетаскивания ячеек. Разберем, почему это происходит и как элегантно обойти это ограничение.
Выясним причину, по которой стандартные методы перестают работать. В управляемых формах 1С:Предприятие 8.3 существует строгое разделение между данными (объект ТабличныйДокумент) и их визуальным представлением (элемент формы типа ПолеТабличногоДокумента). Свойство Редактирование у элемента формы управляет состоянием интерфейса. Если оно установлено в значение Ложь, платформа считает, что пользователь не может интерактивно изменять структуру или содержимое, а значит, и механизм перетаскивания, который потенциально меняет данные, блокируется на уровне ядра платформы.
Проанализируем ситуацию: нам нужно, чтобы документ был интерактивным для перетаскивания, но защищенным от случайного ввода текста. Для этого мы применим комбинированный подход: разрешим редактирование на уровне элемента формы, но запретим его на уровне событий конкретных ячеек.
Рассмотрим основной программный код, который необходимо выполнить при создании формы или в специализированной процедуре подготовки отчета/обработки. Нам необходимо принудительно включить режим редактирования и отключить защиту, которая мешает работе курсора.
&НаКлиенте
Процедура НастроитьДоступностьПеретаскивания()
// Устанавливаем свойства именно ЭЛЕМЕНТА формы
Элементы.ТабличныйДокумент.Редактирование = Истина;
Элементы.ТабличныйДокумент.ТолькоПросмотр = Ложь;
// Снимаем общую защиту документа, чтобы разрешить операции Drag-and-Drop
Элементы.ТабличныйДокумент.Защита = Ложь;
КонецПроцедуры
Важно понимать, что установка Редактирование = Истина — это ключевой момент, который «оживляет» механизм перетаскивания. Без этого никакие дальнейшие действия не принесут результата.
Теперь, когда мы разрешили редактирование, пользователь может случайно изменить текст в ячейке, нажав Enter или дважды кликнув мышью. Чтобы имитировать режим «Только просмотр», мы перехватим стандартные события. Разберем по шагам создание обработчика события Выбор.
&НаКлиенте
Процедура ТабличныйДокументВыбор(Элемент, Область, СтандартнаяОбработка)
// Отключаем стандартный вход в режим редактирования ячейки
СтандартнаяОбработка = Ложь;
// Здесь можно реализовать логику расшифровки, если она требуется
ПосмотретьРасшифровку(Область.Расшифровка);
КонецПроцедуры
Дополнительно проанализируем событие ПриНачалеРедактирования. Оно срабатывает, если пользователь нажал F2 или начал вводить текст в активную ячейку. Для полной защиты данных добавим следующий код:
&НаКлиенте
Процедура ТабличныйДокументПриНачалеРедактирования(Элемент, СтандартнаяОбработка)
// Запрещаем ввод текста в любую ячейку
СтандартнаяОбработка = Ложь;
КонецПроцедуры
Посмотрим на настройки самого элемента формы. Чтобы перетаскивание заработало, недостаточно просто включить Редактирование. В палитре свойств элемента ТабличныйДокумент или программно должны быть установлены флаги:
РазрешитьНачалоПеретаскивания — позволяет пользователю «захватить» ячейку.РазрешитьПеретаскивание — позволяет «сбросить» данные в область таблицы.Рассмотрим пример программной установки этих признаков:
Элементы.ТабличныйДокумент.РазрешитьНачалоПеретаскивания = Истина;
Элементы.ТабличныйДокумент.РазрешитьПеретаскивание = Истина;
Проанализируем ситуацию, когда нам нужно разрешить перетаскивание только в определенные зоны. Свойство Защита у всего документа лучше оставить в значении Ложь, но для конкретных ячеек-приемников или ячеек-источников можно использовать точечную настройку. Если ячейка имеет установленное свойство Область.Защита = Истина, платформа может блокировать сброс данных именно в эту ячейку, даже если общее Редактирование включено.
Для более гибкого управления процессом рекомендуем использовать события ПроверкаПеретаскивания и Перетаскивание. Это позволит вам программно определять, можно ли бросать данные в конкретную область, анализируя тип данных или координаты.
&НаКлиенте
Процедура ТабличныйДокументПроверкаПеретаскивания(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Поле, Область)
// Проверяем, является ли область целевой для нашего перетаскивания
Если Область.Имя = "ЗонаПриемник" Тогда
ПараметрыПеретаскивания.ДопустимыеДействия = ДействияПеретаскивания.Копирование;
Иначе
ПараметрыПеретаскивания.ДопустимыеДействия = ДействияПеретаскивания.Отмена;
КонецЕсли;
СтандартнаяОбработка = Ложь;
КонецПроцедуры
Важно отметить, что в последних версиях платформы работа с фокусом стала более строгой. Выясним причину возможных сбоев: иногда перетаскивание не начинается, если табличный документ не получил фокус ввода. В таких случаях перед началом интерактивных действий полезно принудительно установить текущий элемент формы:
ЭтаФорма.ТекущийЭлемент = Элементы.ТабличныйДокумент;
Подведем итог: для реализации перетаскивания в защищенном табличном документе на управляемых формах мы используем «открытые» свойства элемента формы (Редактирование = Истина), но жестко пресекаем любые попытки изменения данных через обработчики событий Выбор и ПриНачалеРедактирования, устанавливая СтандартнаяОбработка = Ложь. Такой подход обеспечивает отличный пользовательский опыт, сохраняя целостность отображаемой информации.