Как решить проблему с отображением пути к файлу в 1С: разница между Полем ввода и Полем выбора

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

При разработке различных обработок по загрузке или выгрузке данных в 1С программисты часто сталкиваются с необходимостью предоставить пользователю возможность интерактивного выбора файла на диске. Казалось бы, задача тривиальная: создаем элемент на форме, вешаем на него событие начала выбора, пишем стандартный код вызова диалога — и готово. Однако на практике разработчики (особенно начинающие или те, кто возвращается к поддержке старых конфигураций на обычных формах) натыкаются на неприятный визуальный баг: файл успешно выбирается диалоговым окном, код отрабатывает без ошибок, но само поле на форме остается абсолютно пустым.

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

Анализ исходной проблемы: почему «Поле выбора» остается пустым?

Давайте подробно разберем ситуацию, описанную автором темы на форуме. Разработчик создал на обычной форме элемент управления и привязал его к реквизиту с именем ВыбратьФайл (тип реквизита — произвольный). На событие начала выбора был назначен программный обработчик. При запуске код отрабатывал, открывалось стандартное окно операционной системы для выбора файла Microsoft Excel, пользователь выбирал файл, нажимал «Открыть», но путь к файлу в поле на форме не отображался.

Причина такого поведения кроется в фундаментальном различии между элементами управления «Поле ввода» и «Поле выбора» (в терминологии других языков программирования — ComboBox).

Элемент формы ПолеВыбора жестко ориентирован на работу со списком значений (свойство СписокВыбора). Когда мы программно присваиваем связанному реквизиту текстовую строку с путем к файлу (например, "C:\Users\User\Documents\Report.xlsx"), платформа пытается найти эту строку среди элементов своего предопределенного списка выбора. Поскольку этого файла в списке нет, элемент управления не может сопоставить значение и отображает пустое поле. Физически в самом реквизите путь к файлу сохраняется и с ним можно работать в коде, но пользователь видит лишь пустую строку, что вводит его в заблуждение.

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

Решение проблемы на обычных формах: пошаговое руководство

Выяснив причину проблемы, разберем по шагам, как правильно настроить форму и написать работоспособный код для обычных форм 1С.

Шаг 1. Настройка элемента управления в конфигураторе.

Прежде всего, откроем форму нашей обработки или документа в конфигураторе и настроим свойства элемента:

  1. Убедимся, что тип элемента управления установлен как Поле ввода (а не Поле выбора). При необходимости удалим старый элемент и добавим новый с типом Поле ввода.
  2. В панели свойств элемента найдем строку Данные и свяжем его с реквизитом обработки (например, реквизит ПутьКФайлу с типом Строка произвольной длины).
  3. Установим свойство КнопкаВыбора в значение Истина (Да). Это действие выведет в правой части поля привычную кнопку с троеточием «...».
  4. Убедимся, что свойство РежимВыбораИзСписка установлено в значение Ложь (Нет).

Шаг 2. Написание программного кода.

В исходном коде автора темы на форуме была допущена еще одна критическая ошибка: отсутствовало управление параметром СтандартнаяОбработка. Рассмотрим правильный шаблон кода для обычной формы:


Процедура ПутьКФайлуНачалоВыбора(Элемент, СтандартнаяОбработка) Экспорт
    
    // Блокируем стандартное поведение платформы
    СтандартнаяОбработка = Ложь;
    
    // Инициализируем диалог выбора файла
    ДиалогВыбора = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
    ДиалогВыбора.Заголовок = "Выберите файл Excel";
    ДиалогВыбора.ПолноеИмяФайла = "";
    ДиалогВыбора.Фильтр = "Таблицы (*.xls,*.xlsx)|*.xls;*.xlsx|Microsoft Excel 97/2000/XP/2003 (*.xls)|*.xls|Microsoft Excel 2007/2010 (*.xlsx)|*.xlsx";
    
    // Открываем диалог в модальном режиме
    Если ДиалогВыбора.Выбрать() Тогда 
        // Присваиваем реквизиту формы выбранный путь
        ПутьКФайлу = ДиалогВыбора.ПолноеИмяФайла;
    КонецЕсли;
    
КонецПроцедуры

Разберем подробнее строчку СтандартнаяОбработка = Ложь;. По умолчанию, когда пользователь нажимает кнопку выбора «...», платформа 1С пытается выполнить заложенное в конфигурации стандартное действие (например, открыть справочник или окно выбора типа данных, если реквизит не типизирован). Если не установить этот флаг в значение Ложь, то поверх нашего диалога выбора файла может открыться стандартное окно выбора типа данных, либо значение, выбранное нами, будет сразу стерто последующей стандартной очисткой платформы.

Современные стандарты: перенос решения на управляемые формы

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

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

Вариант А. Устаревший асинхронный метод (через ОписаниеОповещения)

Этот подход применялся в версиях платформы 1С:Предприятие от 8.3.3 до 8.3.17. Для его реализации нам потребуется создать две процедуры: одну для инициализации диалога, вторую — для обработки результата выбора.


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

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

Этот метод полностью рабочий, однако он имеет существенный недостаток: код размывается по модулю формы, становится сложным для чтения и поддержки из-за обилия процедур-колбэков.

Вариант Б. Современный асинхронный метод (Платформа 8.3.18 и выше)

В современных релизах платформы разработчикам доступен лаконичный и красивый механизм асинхронного программирования на основе обещаний (Promise). Мы используем модификатор процедуры Асинх и оператор ожидания Ждать.


&НаКлиенте
Асинх Процедура ПутьКФайлуНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
    Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
    Диалог.Заголовок = "Выберите файл для обработки";
    Диалог.Фильтр = "Таблицы Excel (*.xlsx)|*.xlsx";
    
    // Платформа приостановит выполнение процедуры до закрытия диалога пользователем
    РезультатВыбора = Ждать Диалог.ВыбратьАсинх();
    
    Если РезультатВыбора <> Неопределено Тогда
        // Метод ВыбратьАсинх() возвращает массив путей выбранных файлов
        Объект.ПутьКФайлу = РезультатВыбора[0];
    КонецЕсли;
    
КонецПроцедуры

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

Ограничения безопасности веб-клиента

Работая в управляемом интерфейсе, особенно через веб-браузер, важно понимать: простое получение пути к локальному файлу (например, "C:\MyFolder\file.xlsx") не дает серверу 1С возможности прочитать этот файл напрямую. Сервер физически не имеет доступа к жесткому диску клиентского компьютера.

Если ваша обработка должна выполняться на сервере (например, чтение данных из файла Excel и запись их в информационную базу), то вместо простого сохранения пути необходимо использовать механизм временного хранилища. Для этого применяется асинхронная функция ПоместитьФайлНаСерверАсинх, которая не просто возвращает путь, а загружает сам файл в память сервера 1С, возвращая уникальный адрес во временном хранилище.

Резюме и правила хорошего тона при работе с файлами в 1С

Давайте подытожим основные правила, которые мы выработали в процессе совместного решения этой технической задачи:

← На главную