При реализации механизмов прикрепления файлов к документам или справочникам в среде 1С:Предприятие 8 разработчики часто сталкиваются с ситуацией, когда вместо корректного имени файла в реквизит записывается строка «Массив» или непонятный набор символов. Разберем по шагам, почему возникает эта ошибка, как правильно извлечь имя и расширение файла при выборе через диалог, а также рассмотрим современные и надежные способы загрузки и выгрузки файлов в управляемых формах.
Рассмотрим фрагмент кода, в котором возникает проблема:
&НаКлиенте
Процедура ОбработатьВыборФайла(Результат, ДополнительныеПараметры) Экспорт
Если Результат <> Неопределено Тогда
ИмяФайла = Результат; // Ошибка: Результат является массивом
КонецЕсли;
КонецПроцедуры
Выясним причину такого поведения. Метод Показать объекта ДиалогВыбораФайла при успешном выборе пользователя передает в процедуру оповещения параметр Результат, тип которого — Массив строк. Даже если свойство МножественныйВыбор установлено в значение Ложь, платформа все равно возвращает массив, состоящий из одного элемента — полного пути к выбранному файлу на диске.
Если присвоить переменной или реквизиту сам объект Результат без индексации, платформа выполнит неявное приведение типа к строке, и значением станет системное представление типа — «Массив».
Кроме того, обратим внимание на режим работы диалога. Для выбора файла с диска для его последующей загрузки необходимо указывать режим РежимДиалогаВыбораФайла.Открытие, а не РежимДиалогаВыбораФайла.Сохранение.
Разберем классический вариант с исправлением работы ДиалогВыбораФайла. Чтобы не разбирать полный путь к файлу строковыми функциями, воспользуемся специализированным объектом платформы Файл.
Посмотрим на пример правильной обработки:
&НаКлиенте
Процедура ВыбратьФайл(Команда)
Оповещение = Новый ОписаниеОповещения("ОбработатьВыборФайла", ЭтотОбъект);
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
Диалог.МножественныйВыбор = Ложь;
Диалог.Заголовок = "Выберите файл для загрузки";
Диалог.Показать(Оповещение);
КонецПроцедуры
&НаКлиенте
Процедура ОбработатьВыборФайла(Результат, ДополнительныеПараметры) Экспорт
Если Результат <> Неопределено И Результат.Количество() > 0 Тогда
ПолныйПуть = Результат[0];
ВыбранныйФайл = Новый Файл(ПолныйПуть);
// Получаем метаданные файла
Объект.ИмяФайла = ВыбранныйФайл.Имя; // Имя с расширением
Объект.Расширение = ВыбранныйФайл.Расширение;
// Помещаем двоичные данные во временное хранилище
АдресВХ = "";
ПоместитьФайл(АдресВХ, ПолныйПуть, , Ложь, УникальныйИдентификатор);
Объект.АдресФайлаВХ = АдресВХ;
КонецЕсли;
КонецПроцедуры
Объект Файл предоставляет удобные свойства для получения любой информации о файле:
Имя — возвращает имя файла вместе с расширением (например, «ПлатежноеПоручение_123.pdf»);ИмяБезРасширения — только имя без точки и расширения;Расширение — расширение файла с точкой (например, «.pdf»);Размер() — размер файла в байтах.Проанализируем современный подход. При работе в веб-клиенте доступ к локальной файловой системе ограничен браузером. Использование прямого чтения локальных путей может приводить к ошибкам или требовать установки дополнительных расширений работы с файлами. Для обеспечения кроссплатформенности и работы в тонком, мобильном и веб-клиенте рекомендуется использовать асинхронные методы помещения файлов на сервер.
Рассмотрим реализацию через ПоместитьФайлНаСерверАсинх:
&НаКлиенте
Асинх Процедура ЗагрузитьФайлАсинх(Команда)
ПараметрыДиалога = Новый ПараметрыДиалогаПомещенияФайлов;
ПараметрыДиалога.Заголовок = "Выберите платежное поручение";
ПараметрыДиалога.МножественныйВыбор = Ложь;
Результат = Ждать ПоместитьФайлНаСерверАсинх(,,, ПараметрыДиалога, УникальныйИдентификатор);
Если Результат <> Неопределено Тогда
// Получаем имя выбранного файла напрямую из результата
Объект.ИмяФайла = Результат.Файл.Имя;
// Сохраняем адрес во временном хранилище для дальнейшей записи
СохранитьФайлВБазеНаСервере(Результат.Адрес);
КонецЕсли;
КонецПроцедуры
При таком подходе платформа сама открывает системный диалог выбора, передает файл во временное хранилище и возвращает структуру, в свойстве Файл.Имя которой уже содержится исходное имя файла без обращения к файловой системе клиента.
Разберем, как правильно сохранить полученные двоичные данные на сервере и как настроить их обратное сохранение на диск пользователя.
1. Запись двоичных данных в реквизит объекта на сервере:
При записи двоичных данных в реквизит с типом ХранилищеЗначения рекомендуется использовать сжатие данных для экономии места в базе.
&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
Если ЭтоАдресВременногоХранилища(АдресФайлаВХ) Тогда
ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресФайлаВХ);
ТекущийОбъект.ХранилищеФайла = Новый ХранилищеЗначения(ДвоичныеДанные, Новый СжатиеДанных(9));
УдалитьИзВременногоХранилища(АдресФайлаВХ);
КонецЕсли;
КонецПроцедуры
2. Выгрузка и открытие файла пользователю:
Для обратной выгрузки файла на компьютер пользователя воспользуемся асинхронным методом ПолучитьФайлССервераАсинх, передав навигационную ссылку на реквизит и сохраненное ранее имя файла.
&НаКлиенте
Асинх Процедура СохранитьФайлНаДиск(Команда)
Если Не ЗначениеЗаполнено(Объект.Ссылка) Тогда
Предупреждение("Сначала необходимо записать документ.");
Возврат;
КонецЕсли;
НавигационнаяСсылка = ПолучитьНавигационнуюСсылку(Объект.Ссылка, "ХранилищеФайла");
ПараметрыСохранения = Новый ПараметрыДиалогаПолученияФайлов;
Ждать ПолучитьФайлССервераАсинх(НавигационнаяСсылка, Объект.ИмяФайла, ПараметрыСохранения);
КонецПроцедуры
Такой подход гарантирует корректное сохранение файла с его исходным именем и расширением, обеспечивает максимальную производительность базы данных и стабильную работу конфигурации во всех режимах клиентских приложений.