При переходе с обычных форм на управляемые формы платформы 1С:Предприятие 8.3 разработчики часто сталкиваются с ошибками при попытке выбрать и прочитать файл Excel. Привычные методы работы с элементами формы и локальной файловой системой в управляемом приложении меняются из-за четкого разделения выполнения кода между клиентом и сервером.
В этой статье мы подробно разберем, почему возникают ошибки вида «Поле объекта не обнаружено», как правильно настроить реквизиты формы для хранения пути к файлу и как корректно организовать работу с файлом в клиенто-серверном режиме.
Проанализируем типичные промахи, с которыми сталкиваются программисты при попытке вызвать диалог выбора файла:
Значение элемента формы: В обычных формах элементы управления напрямую содержали значение (`Элемент.Значение`). В управляемых формах элементы (ПолеФормы) служат лишь для визуального отображения, а сами данные хранятся в реквизитах формы или объекта. Изменение значения должно выполняться через имя реквизита напрямую.Строка (неограниченной длины). Если реквизит имеет составной тип или тип ссылки (например, ЛюбаяСсылка), вызов диалога или присвоение пути завершится ошибкой.C:\Users\File.xlsx) указывает на локальный диск клиентского компьютера. Сервер 1С физически находится на другом компьютере и не имеет доступа к локальному диску пользователя. Попытка открыть этот путь в серверном контексте через COMОбъект или GetCOMObject вызовет ошибку открытия файла.Разберем по шагам, как правильно подготовить реквизиты формы:
ПутьКФайлу.Строка. Если длина ограничена, снимем ограничение длины (неограниченная строка).ПутьКФайлу в панель элементов формы. Будет создан элемент типа ПолеВвода.КнопкаВыбора (а также при необходимости отключим РедактированиеТекста).НачалоВыбора создадим обработчик на клиенте.Рассмотрим рабочий код обработчика события НачалоВыбора. В клиентском контексте мы перехватываем стандартную обработку выбора и вызываем объект ДиалогВыбораФайла:
&НаКлиенте
Процедура ПутьКФайлуНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ДиалогОткрытияФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
ДиалогОткрытияФайла.Заголовок = "Выберите файл Excel";
ДиалогОткрытияФайла.Фильтр = "Файлы Excel (*.xls;*.xlsx)|*.xls;*.xlsx";
ДиалогОткрытияФайла.ИндексФильтра = 0;
ДиалогОткрытияФайла.ПредварительныйПросмотр = Ложь;
ДиалогОткрытияФайла.ПроверятьСуществованиеФайла = Истина;
ДиалогОткрытияФайла.МножественныйВыбор = Ложь;
// Позиционируем диалог на ранее выбранном файле, если путь уже заполнен
ДиалогОткрытияФайла.ПолноеИмяФайла = ПутьКФайлу;
Если ДиалогОткрытияФайла.Выбрать() Тогда
// Записываем полученный путь напрямую в реквизит формы
ПутьКФайлу = ДиалогОткрытияФайла.ПолноеИмяФайла;
КонецЕсли;
КонецПроцедуры
Обратите внимание: мы присваиваем результат выбора напрямую реквизиту ПутьКФайлу, а не обращаемся к Элемент.Значение.
Выясним, как правильно передать выбранный файл на сервер для обработки. Если мы хотим прочитать Excel-файл на сервере, локальный путь клиента использовать нельзя. Нам необходимо поместить файл во временное хранилище на клиенте и передать полученный адрес на сервер.
Посмотрим на пример безопасной передачи файла во временное хранилище и чтения его на сервере через объект ТабличныйДокумент (кроссплатформенный вариант, который не требует установленного Microsoft Excel):
&НаКлиенте
Процедура ЗагрузитьФайлНаКлиенте()
Если НЕ ЗначениеЗаполнено(ПутьКФайлу) Тогда
ВызватьИсключение "Не выбран файл для загрузки!";
КонецЕсли;
// Помещаем файл с диска клиента во временное хранилище
АдресХранилища = "";
Если ПоместитьВоВременноеХранилище(Новый ДвоичныеДанные(ПутьКФайлу), ЭтаФорма.УникальныйИдентификатор, АдресХранилища) Тогда
// Вызываем серверную процедуру для обработки
ОбработатьФайлНаСервере(АдресХранилища);
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ОбработатьФайлНаСервере(АдресХранилища)
// Получаем двоичные данные из хранилища и сохраняем во временный файл на сервере
ДвоичныеДанныеФайла = ПолучитьИзВременногоХранилища(АдресХранилища);
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xlsx");
ДвоичныеДанныеФайла.Записать(ИмяВременногоФайла);
// Читаем Excel-файл с помощью встроенного ТабличногоДокумента
ТабДок = Новый ТабличныйДокумент;
Попытка
ТабДок.Прочитать(ИмяВременногоФайла, СпособЧтенияЗначенийТабличногоДокумента.Значение);
// Здесь выполняется обход ячеек ТабДок или выгрузка в ТаблицуЗначений
Важно
УдалитьФайлы(ИмяВременногоФайла); // Обязательно удаляем временный файл на сервере
КонецПопытки;
КонецПроцедуры
Таким образом, соблюдение трех правил — использование реквизита формы со типом Строка, прямой записью в реквизит без Элемент.Значение и правильной передачей файла во временное хранилище — позволяет легко и без ошибок реализовывать загрузку Excel-файлов в любых управляемых формах 1С.