Как правильно реализовать выбор файла в управляемых формах 1С 8.3 и избежать ошибок?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Переход с обычных форм на управляемые часто вызывает трудности у разработчиков, привыкших к линейному выполнению кода. Одной из самых распространенных проблем является работа с файловой системой, а именно — использование объекта ДиалогВыбораФайла. В этой статье мы подробно разберем, почему старый код выдает ошибку "Тип не определен", как влияет режим модальности на работу программы и как правильно написать современный асинхронный код для выбора файлов. Для этой задачи есть инструмент для отладки кода 1С в режиме «Предприятие».

Разбор причины ошибки «Тип не определен (ДиалогВыбораФайла)»

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

Объект ДиалогВыбораФайла предназначен для взаимодействия с интерфейсом операционной системы пользователя. Следовательно, он существует и доступен только на клиенте. Если вы вызываете этот код в процедуре без директивы компиляции или в процедуре с директивой &НаСервере, платформа закономерно сообщит, что такой тип ей неизвестен, так как на стороне сервера нет графического интерфейса и доступа к локальным файлам пользователя напрямую.

Важное правило: всегда проверяйте, что процедура, работающая с диалогами, помечена директивой &НаКлиенте.

Проблема модальности в современных конфигурациях

Рассмотрим вторую важную преграду — режим использования модальности. В старых версиях платформы и обычных формах мы использовали метод Выбрать(), который останавливал выполнение кода до тех пор, пока пользователь не закроет окно выбора файла. В современных управляемых приложениях (особенно в типовых решениях вроде БП 3.0, ERP или УТ 11) свойство конфигурации «Режим использования модальности» обычно установлено в значение «Не использовать».

Это сделано для обеспечения работы в веб-клиенте (браузерах), которые блокируют модальные окна. При попытке вызвать метод Выбрать() в таком режиме система выдаст программную ошибку. Рассмотрим, как решить эту задачу правильно.

Решение №1: Использование метода Показать() и ОписанияОповещения

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

Во-первых, нам необходимо создать процедуру, которая инициирует диалог. Во-вторых, создать экспортную процедуру, которая обработает результат выбора. Посмотрим на пример кода:


&НаКлиенте
Процедура КомандаВыбратьФайл(Команда)
    
    // Указываем режим работы диалога: открытие файла
    ПараметрыДиалога = РежимДиалогаВыбораФайла.Открытие;
    Диалог = Новый ДиалогВыбораФайла(ПараметрыДиалога);
    
    Диалог.Заголовок = "Выберите файл для загрузки";
    Диалог.Фильтр = "Документы PDF (*.pdf)|*.pdf|Все файлы (*.*)|*.*";
    Диалог.ПолноеИмяФайла = "";
    
    // Создаем описание оповещения, указывая имя процедуры-обработчика
    Оповещение = Новый ОписаниеОповещения("ПослеВыбораФайла", ЭтотОбъект);
    
    // Вызываем асинхронный метод Показать
    Диалог.Показать(Оповещение);
    
    // Важно: код, написанный здесь, выполнится СРАЗУ, не дожидаясь выбора пользователя!
    
КонецПроцедуры

&НаКлиенте
Процедура ПослеВыбораФайла(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт
    
    Если ВыбранныеФайлы <> Неопределено Тогда
        // Пользователь выбрал один или несколько файлов (например, для импорта данных из Excel, txt или csv)
        ПутьКФайлу = ВыбранныеФайлы[0];
        Сообщить("Выбран файл: " + ПутьКФайлу);
        
        // Здесь можно вызвать серверную процедуру для обработки файла
        ОбработатьФайлНаСервере(ПутьКФайлу);
    Иначе
        // Пользователь нажал "Отмена"
        Сообщить("Выбор файла отменен.");
    КонецЕсли;
    
КонецПроцедуры

Решение №2: Современный подход через ВыбратьАсинхронно() (Платформа 8.3.18+)

Если ваша конфигурация работает на современной платформе (версии 8.3.18 и выше), мы можем использовать более элегантный синтаксис с использованием ключевого слова Ждать. Это позволяет писать асинхронный код так же просто, как и старый синхронный, сохраняя линейную структуру. Проанализируем, как это выглядит:


&НаКлиенте
Асинхронная Процедура ВыбратьФайлСовременно(Команда)
    
    Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
    Диалог.Заголовок = "Выберите файл";
    
    // Используем Ждать для получения результата без блокировки интерфейса
    РезультатВыбора = Ждать Диалог.ВыбратьАсинхронно();
    
    Если РезультатВыбора <> Неопределено Тогда
        // РезультатВыбора — это массив строк с путями к файлам
        Для Каждого Путь Из РезультатВыбора Цикл
            Сообщить("Выбран путь: " + Путь); 
        КонецЦикла;
    КонецЕсли;
    
КонецПроцедуры

Обратите внимание на ключевое слово Асинхронная перед объявлением процедуры. Это обязательное требование платформы для использования оператора Ждать.

Особенности работы в веб-клиенте

Если вы разрабатываете решение, которое будет запускаться через браузер, следует помнить о нескольких нюансах. Рассмотрим их подробнее:

  1. Расширение работы с файлами: В старых версиях платформы для вызова диалогов требовалось устанавливать расширение для браузера. В новых версиях 1С старается обходить это ограничение, но асинхронность (использование Показать или ВыбратьАсинхронно) является критически важной.
  2. Интерактивное действие: Браузеры блокируют программное открытие окон выбора файлов, если оно не было инициировано непосредственным нажатием кнопки пользователем. То есть вы не сможете вызвать диалог выбора файла, например, в обработчике события ПриОткрытии формы без участия пользователя.
  3. Передача на сервер: Сам по себе ДиалогВыбораФайла только возвращает строковый путь к файлу на диске клиента — для этого подойдёт универсальная загрузка данных из Excel и CSV. Чтобы прочитать содержимое файла на сервере, файл нужно передать во временное хранилище с помощью метода ПоместитьФайлНаСерверАсинхронно().

Рекомендация по использованию глобальных методов

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

Резюмируем: для успешного решения задачи выбора файла в 1С 8.3 необходимо убедиться, что код исполняется в контексте &НаКлиенте, и заменить устаревший метод Выбрать() на асинхронные аналоги (Показать() с оповещением или ВыбратьАсинхронно() с оператором Ждать). Это гарантирует стабильную работу программы во всех режимах — от тонкого клиента до веб-браузера.

← На главную