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