К статье
Практический материал

Разработка и Конфигурация · 11 мин

1С: как сделать перетаскивание элементов в форме

Как настроить перетаскивание в 1С: разрешитьПеретаскивание, обработчики Перетаскивание и ПроверкаПеретаскивания, примеры кода для табличного поля и дерева.

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

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

Где в 1С работает перетаскивание и как оно устроено

Платформа 1С:Предприятие поддерживает перетаскивание в табличных полях, динамических списках, деревьях значений и между элементами управляемой формы. Механизм построен на объекте ПараметрыПеретаскивания, который передаётся в обработчики и содержит перетаскиваемое значение, тип действия и допустимые действия.

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

Как включить перетаскивание через свойства формы

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

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

&НаСервере

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

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

Элементы.Корзина.РазрешитьПеретаскивание = Истина;

КонецПроцедуры

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

Обработчики событий ПроверкаПеретаскивания и Перетаскивание

Когда стандартного поведения недостаточно, подключаются два события табличного поля. Событие ПроверкаПеретаскивания вызывается, когда курсор с захваченными данными находится над приёмником: здесь вы решаете, допустимо ли перетаскивание, и задаёте действие. Событие Перетаскивание срабатывает в момент «отпускания» кнопки мыши — здесь выполняется фактическая обработка данных.

Типовой шаблон обработчиков выглядит так:

&НаКлиенте

Процедура КорзинаПроверкаПеретаскивания(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Поле)

СтандартнаяОбработка = Ложь;

Если ТипЗнч(ПараметрыПеретаскивания.Значение) = Тип("Массив") Тогда

ПараметрыПеретаскивания.Действие = ДействиеПеретаскивания.Копирование;

Иначе

ПараметрыПеретаскивания.Действие = ДействиеПеретаскивания.Отмена;

КонецЕсли;

КонецПроцедуры

&НаКлиенте

Процедура КорзинаПеретаскивание(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Поле)

СтандартнаяОбработка = Ложь;

Для Каждого СтрокаИсточника Из ПараметрыПеретаскивания.Значение Цикл

НоваяСтрока = Объект.Корзина.Добавить();

ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаИсточника);

КонецЦикла;

КонецПроцедуры

Установка СтандартнаяОбработка = Ложь обязательна: иначе платформа попытается выполнить действие по умолчанию, что часто приводит к ошибкам несовпадения типов. В обработчике проверки всегда явно задавайте ДействиеПеретаскивания.Отмена для неподдерживаемых данных — тогда курсор покажет пользователю, что перетаскивание сюда запрещено.

Порядок настройки перетаскивания вручную
  1. 1
    Включите РазрешитьНачалоПеретаскивания у таблицы-источника
  2. 2
    Включите РазрешитьПеретаскивание у таблицы-приёмника
  3. 3
    Создайте обработчик ПроверкаПеретаскивания у приёмника и задайте допустимое действие
  4. 4
    Создайте обработчик Перетаскивание и реализуйте перенос данных
  5. 5
    Установите СтандартнаяОбработка = Ложь в обоих обработчиках
  6. 6
    Проверьте перетаскивание одной строки и нескольких строк в режиме предприятия

Перетаскивание для изменения порядка строк табличной части

Частая задача — дать пользователю возможность менять порядок строк мышью вместо кнопок «Вверх» и «Вниз». Для этого у табличного поля, связанного с табличной частью, включите и начало перетаскивания, и приём, а в обработчике используйте метод Сдвинуть коллекции строк.

&НаКлиенте

Процедура ТоварыПеретаскивание(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Поле)

СтандартнаяОбработка = Ложь;

Если Строка = Неопределено Тогда

Возврат;

КонецЕсли;

ИндексНазначения = Объект.Товары.Индекс(Объект.Товары.НайтиПоИдентификатору(Строка));

Для Каждого Перетаскиваемая Из ПараметрыПеретаскивания.Значение Цикл

ИндексИсточника = Объект.Товары.Индекс(Перетаскиваемая);

Объект.Товары.Сдвинуть(ИндексИсточника, ИндексНазначения - ИндексИсточника);

КонецЦикла;

КонецПроцедуры

Учтите, что порядок строк в табличной части сохраняется при записи документа, поэтому дополнительных полей «Порядок» вводить не нужно. Если же данные хранятся в регистре или динамическом списке, простого сдвига недостаточно — понадобится отдельный реквизит сортировки и его пересчёт на сервере.

Перетаскивание в дереве значений и между группами справочника

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

При перетаскивании в иерархическом списке справочника платформа меняет родителя автоматически, но только если включён режим отображения «Иерархический список» или «Дерево». В режиме плоского списка перетаскивание групп недоступно. Также проверьте, что у справочника не запрещено изменение родителя в подписках на события или бизнес-логике — иначе запись завершится ошибкой уже после визуально успешного перетаскивания.

Перетаскивание файлов и данных извне

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

Учтите ограничение тонкого и веб-клиента: работа с файловой системой требует расширения работы с файлами, а в веб-клиенте часть сценариев доступна только после явного разрешения пользователя. Если перетаскивание файлов не срабатывает, первым делом проверяйте тип клиента и подключение расширения.

Типичные ошибки
01
Забыли СтандартнаяОбработка = Ложь — платформа выполняет своё действие и возникает ошибка несовпадения типов
02
В обработчике ожидают одно значение, хотя при множественном выборе приходит массив — проверяйте тип Значение
03
Перетаскивание не работает из-за отключённого свойства ИзменятьСоставСтрок у таблицы-приёмника
04
Сравнивают строки таблицы по ссылке вместо поиска через НайтиПоИдентификатору — строка не находится
05
Пытаются сдвигать строки динамического списка — он доступен только для чтения, нужен реквизит сортировки

Проверка результата и отладка

После настройки проверьте все варианты взаимодействия: перетаскивание одной строки, нескольких строк, перетаскивание в пустую таблицу, попытку перетащить недопустимый тип данных (курсор должен показывать запрет). Для отладки удобно временно выводить в обработчике проверки тип и содержимое ПараметрыПеретаскивания.Значение через Сообщить() или точку останова.

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

Контрольные точки

Как проверить результат

Перетаскивание одной строки
Норма

Строка перемещается или копируется в нужное место, форма обновляется

Тревожный признак

Строка исчезает, дублируется или появляется ошибка типов

Курсор над запрещённой областью
Норма

Отображается значок запрета, действие отменяется

Тревожный признак

Перетаскивание «проходит» и вызывает исключение

Запись после переноса
Норма

Объект записывается, порядок или родитель сохраняются после переоткрытия

Тревожный признак

После переоткрытия формы изменения теряются

Итог

Что важно запомнить

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

Частые вопросы о перетаскивании в 1С

Почему перетаскивание не работает, хотя свойства включены?

Чаще всего причина в отключённом свойстве «ИзменятьСоставСтрок» у таблицы, режиме «только просмотр» формы или отсутствии обработчиков событий. Также проверьте, что перетаскивание тестируется в режиме предприятия, а не ожидается эффект от одних флажков в конфигураторе для нестандартного сценария.

Можно ли перетаскивать строки между формами разных объектов?

Да, если обе формы открыты в одном клиентском приложении и у них настроены свойства и обработчики. Значение передаётся через ПараметрыПеретаскивания, поэтому в приёмнике нужно корректно интерпретировать тип перетаскиваемых данных — например, массив строк табличной части другого документа.

Как запретить перетаскивание отдельных строк?

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

Работает ли перетаскивание в веб-клиенте?

Базовые сценарии (между таблицами формы, изменение порядка строк, иерархия списков) в веб-клиенте работают. Ограничения касаются перетаскивания файлов из операционной системы и сценариев, требующих расширения работы с файлами, — их нужно проверять отдельно для каждого браузера.

Как сохранить порядок строк, заданный перетаскиванием, в динамическом списке?

Динамический список — это запрос к данным, он не хранит порядок строк. Добавьте в объект реквизит для сортировки (например, «ПорядокСортировки»), в обработчике перетаскивания пересчитывайте его значения на сервере и настройте сортировку списка по этому реквизиту.