Переход с обычных форм на управляемые часто вызывает трудности у разработчиков, привыкших к линейному выполнению кода. Одной из самых распространенных проблем является работа с файловой системой, а именно — использование объекта ДиалогВыбораФайла. В этой статье мы подробно разберем, почему старый код выдает ошибку "Тип не определен", как влияет режим модальности на работу программы и как правильно написать современный асинхронный код для выбора файлов. Для этой задачи есть инструмент для отладки кода 1С в режиме «Предприятие».
Проанализируем ситуацию, с которой сталкивается автор темы. При попытке инициализировать объект Новый ДиалогВыбораФайла система выдает ошибку неопределенного типа. Выясним причину этого поведения. В 1С:Предприятие 8.3 управляемое приложение жестко разделяет контексты выполнения кода на клиентский и серверный.
Объект ДиалогВыбораФайла предназначен для взаимодействия с интерфейсом операционной системы пользователя. Следовательно, он существует и доступен только на клиенте. Если вы вызываете этот код в процедуре без директивы компиляции или в процедуре с директивой &НаСервере, платформа закономерно сообщит, что такой тип ей неизвестен, так как на стороне сервера нет графического интерфейса и доступа к локальным файлам пользователя напрямую.
Важное правило: всегда проверяйте, что процедура, работающая с диалогами, помечена директивой &НаКлиенте.
Рассмотрим вторую важную преграду — режим использования модальности. В старых версиях платформы и обычных формах мы использовали метод Выбрать(), который останавливал выполнение кода до тех пор, пока пользователь не закроет окно выбора файла. В современных управляемых приложениях (особенно в типовых решениях вроде БП 3.0, ERP или УТ 11) свойство конфигурации «Режим использования модальности» обычно установлено в значение «Не использовать».
Это сделано для обеспечения работы в веб-клиенте (браузерах), которые блокируют модальные окна. При попытке вызвать метод Выбрать() в таком режиме система выдаст программную ошибку. Рассмотрим, как решить эту задачу правильно.
Это классический способ работы в управляемых формах для версий платформы ниже 8.3.18 — поможет инструменты разработчика для работы с управляемыми формами. Вместо того чтобы ждать ответа от метода, мы передаем системе процедуру, которую нужно вызвать сразу после того, как пользователь выберет файл. Разберем этот механизм по шагам.
Во-первых, нам необходимо создать процедуру, которая инициирует диалог. Во-вторых, создать экспортную процедуру, которая обработает результат выбора. Посмотрим на пример кода:
&НаКлиенте
Процедура КомандаВыбратьФайл(Команда)
// Указываем режим работы диалога: открытие файла
ПараметрыДиалога = РежимДиалогаВыбораФайла.Открытие;
Диалог = Новый ДиалогВыбораФайла(ПараметрыДиалога);
Диалог.Заголовок = "Выберите файл для загрузки";
Диалог.Фильтр = "Документы PDF (*.pdf)|*.pdf|Все файлы (*.*)|*.*";
Диалог.ПолноеИмяФайла = "";
// Создаем описание оповещения, указывая имя процедуры-обработчика
Оповещение = Новый ОписаниеОповещения("ПослеВыбораФайла", ЭтотОбъект);
// Вызываем асинхронный метод Показать
Диалог.Показать(Оповещение);
// Важно: код, написанный здесь, выполнится СРАЗУ, не дожидаясь выбора пользователя!
КонецПроцедуры
&НаКлиенте
Процедура ПослеВыбораФайла(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт
Если ВыбранныеФайлы <> Неопределено Тогда
// Пользователь выбрал один или несколько файлов (например, для импорта данных из Excel, txt или csv)
ПутьКФайлу = ВыбранныеФайлы[0];
Сообщить("Выбран файл: " + ПутьКФайлу);
// Здесь можно вызвать серверную процедуру для обработки файла
ОбработатьФайлНаСервере(ПутьКФайлу);
Иначе
// Пользователь нажал "Отмена"
Сообщить("Выбор файла отменен.");
КонецЕсли;
КонецПроцедуры
Если ваша конфигурация работает на современной платформе (версии 8.3.18 и выше), мы можем использовать более элегантный синтаксис с использованием ключевого слова Ждать. Это позволяет писать асинхронный код так же просто, как и старый синхронный, сохраняя линейную структуру. Проанализируем, как это выглядит:
&НаКлиенте
Асинхронная Процедура ВыбратьФайлСовременно(Команда)
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
Диалог.Заголовок = "Выберите файл";
// Используем Ждать для получения результата без блокировки интерфейса
РезультатВыбора = Ждать Диалог.ВыбратьАсинхронно();
Если РезультатВыбора <> Неопределено Тогда
// РезультатВыбора — это массив строк с путями к файлам
Для Каждого Путь Из РезультатВыбора Цикл
Сообщить("Выбран путь: " + Путь);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Обратите внимание на ключевое слово Асинхронная перед объявлением процедуры. Это обязательное требование платформы для использования оператора Ждать.
Если вы разрабатываете решение, которое будет запускаться через браузер, следует помнить о нескольких нюансах. Рассмотрим их подробнее:
Показать или ВыбратьАсинхронно) является критически важной.ПриОткрытии формы без участия пользователя.ДиалогВыбораФайла только возвращает строковый путь к файлу на диске клиента — для этого подойдёт универсальная загрузка данных из Excel и CSV. Чтобы прочитать содержимое файла на сервере, файл нужно передать во временное хранилище с помощью метода ПоместитьФайлНаСерверАсинхронно().Вместо ручного создания объекта ДиалогВыбораФайла, часто бывает удобнее и правильнее использовать метод глобального контекста НачатьПомещениеФайлаНаСервер(). Этот метод объединяет в себе вызов диалога выбора и автоматическую загрузку файла в базу — есть готовая автоматизированная загрузка номенклатуры и изображений в 1С. Это избавляет разработчика от необходимости отдельно настраивать объект диалога и писать дополнительный код для передачи данных.
Резюмируем: для успешного решения задачи выбора файла в 1С 8.3 необходимо убедиться, что код исполняется в контексте &НаКлиенте, и заменить устаревший метод Выбрать() на асинхронные аналоги (Показать() с оповещением или ВыбратьАсинхронно() с оператором Ждать). Это гарантирует стабильную работу программы во всех режимах — от тонкого клиента до веб-браузера.