Механизм Drag`n`drop значительно повышает удобство работы пользователей, позволяя прикреплять документы, изображения или отчеты простым перетаскиванием мыши из папки Windows прямо в окно программы 1С. Однако при реализации этой функции программисты часто сталкиваются с тем, что система либо игнорирует действие, либо открывает файл как обычный текстовый документ. В данной статье мы подробно разберем, как правильно настроить этот механизм, какие события формы использовать и как избежать типичных ошибок, связанных с правами доступа.
Первое, с чего мы должны начать — это настройка самого элемента формы, в который пользователь будет «бросать» файлы. Это может быть ТабличноеПоле, ПолеСписка или Декорация. Рассмотрим ситуацию на примере управляемых форм. Для того чтобы элемент начал реагировать на перетаскивание, необходимо в палитре свойств найти раздел «Использование» и установить два критически важных флага:
Проанализируем важный нюанс: если вы работаете в обычном приложении (толстый клиент), эти свойства также обязательны для заполнения, иначе события перетаскивания просто не будут генерироваться платформой.
Если мы просто включим флаги и попробуем перетащить файл, 1С по умолчанию попытается открыть его. Чтобы этого не произошло, нам нужно программно вмешаться в процесс. Для этого используется событие ПроверкаПеретаскивания. Рассмотрим, как это выглядит в коде:
&НаКлиенте
Процедура ФайлыПроверкаПеретаскивания(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Поле)
// Отключаем стандартное поведение 1С (открытие файла)
СтандартнаяОбработка = Ложь;
// Указываем, что мы готовы принять объект (копирование)
ПараметрыПеретаскивания.ДопустимыеДействия = ДействиеПеретаскивания.Копирование;
КонецПроцедуры
Разберем, что здесь происходит. Установка СтандартнаяОбработка = Ложь говорит системе: «Я сам решу, что делать с этим объектом». Параметр Строка в обработчике позволяет нам определить, на какую именно строку таблицы наведен курсор. Это очень полезно, если мы хотим привязать файл к конкретному объекту в списке (например, к конкретной строке договора).
Теперь перейдем к основному действию. Когда пользователь отпускает кнопку мыши над элементом, срабатывает событие Перетаскивание. Здесь нам нужно извлечь информацию о файле и поместить его в хранилище или передать на сервер.
Важно помнить, что пользователь может перетаскивать как один файл, так и целую группу. Поэтому нам следует проверить тип данных в параметре Значение. Посмотрим на универсальный пример кода:
&НаКлиенте
Процедура ФайлыПеретаскивание(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Поле)
СтандартнаяОбработка = Ложь;
// Проверяем, массив это или одиночный файл
Если ТипЗнч(ПараметрыПеретаскивания.Значение) = Тип("Массив") Тогда
Для Каждого ТекущийФайл Из ПараметрыПеретаскивания.Значение Цикл
ОбработатьОдиночныйФайл(ТекущийФайл);
КонецЦикла;
ИначеЕсли ТипЗнч(ПараметрыПеретаскивания.Значение) = Тип("Файл") Тогда
ОбработатьОдиночныйФайл(ПараметрыПеретаскивания.Значение);
КонецЕсли;
КонецПроцедуры
Внутри процедуры ОбработатьОдиночныйФайл мы можем использовать стандартные методы работы с файловой системой. Обратите внимание, что объект Файл в данном контексте уже содержит все необходимые свойства, такие как ПолноеИмя и Имя.
В современных версиях платформы (8.3.15 и выше) рекомендуется избегать синхронных методов вроде ПоместитьФайл на клиенте. Выясним причину: синхронные вызовы блокируют интерфейс и могут приводить к ошибкам в веб-клиенте. Вместо этого используем асинхронный подход с методом НачатьПомещениеФайлаНаСервер.
Проанализируем логику: 1. Создаем описание оповещения. 2. Вызываем асинхронный метод помещения файла. 3. В процедуре завершения передаем адрес временного хранилища на сервер для окончательной записи.
&НаКлиенте
Процедура ОбработатьОдиночныйФайл(ОбъектФайл)
ОписаниеОповещения = Новый ОписаниеОповещения("ЗавершитьЗагрузкуФайла", ЭтотОбъект);
НачатьПомещениеФайлаНаСервер(ОписаниеОповещения, , , , ОбъектФайл.ПолноеИмя, УникальныйИдентификатор);
КонецПроцедуры
&НаКлиенте
Процедура ЗавершитьЗагрузкуФайла(Результат, Адрес, ВыбранноеИмяФайла, ДополнительныеПараметры) Экспорт
Если Результат Тогда
// Здесь вызываем серверную процедуру для сохранения файла из Адреса
СохранитьФайлНаСервере(Адрес, ВыбранноеИмяФайла);
КонецЕсли;
КонецПроцедуры
Рассмотрим ситуацию, когда все настроено верно, но при перетаскивании пользователь видит перечеркнутый круг (запрещающий знак). Выясним причину этой проблемы:
Конфликт прав доступа (UAC). Если ваша 1С запущена «От имени администратора», а проводник Windows запущен от имени обычного пользователя, механизм Drag`n`drop работать не будет. Это стандартная защита Windows (UIPI). Для исправления ситуации необходимо запускать оба приложения с одинаковыми правами — либо оба от администратора (не рекомендуется), либо оба в обычном режиме.
Перетаскивание из Outlook. Если вы попытаетесь перетащить вложение напрямую из письма Microsoft Outlook, 1С может не распознать тип данных Файл. В этом случае данные передаются через интерфейсы COM, которые платформа не всегда обрабатывает автоматически. Рекомендуется сначала сохранить вложение на рабочий стол, а затем перетаскивать его в 1С, либо использовать специализированные внешние компоненты.
Визуальная индикация. В событии ПроверкаПеретаскивания мы можем динамически менять значок курсора. Например, если файл имеет недопустимое расширение (скажем, мы ждем только .pdf), мы можем установить ПараметрыПеретаскивания.ДопустимыеДействия = ДействиеПеретаскивания.Недоступно. В этом случае пользователь сразу поймет, что данный файл загрузить нельзя.
Подводя итог, можно сказать, что реализация Drag`n`drop в 1С требует комплексного подхода: правильной настройки свойств элементов формы, грамотной обработки событий и учета особенностей безопасности операционной системы. Использование асинхронных методов сделает ваше решение надежным и современным.