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