Почему после выбора каталога путь не проставляется в поле на управляемой форме 1С?

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

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

Анализ проблемы: контекст формы и реквизиты объекта

Посмотрим на исходный фрагмент кода, с которым возникла трудность у разработчика:


Процедура КаталогЗагрузкиНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    
    ДиалогВыбораФайла           = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.ВыборКаталога);
    ДиалогВыбораФайла.Заголовок = "Выбор каталога";
    
    Если ДиалогВыбораФайла.Выбрать() Тогда
        КаталогЗагрузки = ДиалогВыбораФайла.Каталог;
    КонецЕсли;
    
КонецПроцедуры

Разберем, почему данный код не обновляет значение на форме. Здесь допущены сразу две принципиальные ошибки:

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

Исправление ошибки: прямое обращение через «Объект»

Рассмотрим рабочее решение, в котором устранены обе неточности. Мы явно устанавливаем флаг отключения платформенного выбора и обращаемся к реквизиту через основной реквизит формы:


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

Обратите внимание: если ваш реквизит действительно был добавлен напрямую в список реквизитов формы (а не в метаданные объекта), то обращение без префикса Объект было бы верным. Но когда поле ввода привязано к свойству Объект.КаталогЗагрузки, присвоение локальной переменной КаталогЗагрузки никак не повлияет на отображение в интерфейсе.

Отказ от модальности: современный асинхронный вызов

Проанализируем еще одну важную деталь. Метод ДиалогВыбораФайла.Выбрать() является синхронным (модальным). В большинстве современных конфигураций 1С включен режим запрета модальных окон (свойство «Режим использования модальности» установлено в значение «Не использовать»). При запуске такого кода в рабочей базе платформа вызовет критическое исключение: «Использование модальных окон в данном режиме запрещено».

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


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

Если требуется поддержка более ранних версий платформы без ключевого слова Асинх, то используется метод Показать() с объектом ОписаниеОповещения:


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

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

Чек-лист для проверки при проблемах с выбором каталога

  1. Проверьте свойство «ПутьКДанным» у элемента формы. Убедитесь, что поле ввода действительно связано с путем Объект.КаталогЗагрузки, а не с пустым или временным значением.
  2. Убедитесь в наличии директивы &НаКлиенте. Работа с файловой системой пользователя и диалоговыми окнами возможна только на стороне клиента.
  3. Не забывайте про завершающий слэш. Свойство диалога Каталог возвращает путь к папке без завершающего разделителя (\ в Windows или / в Linux). Если дальше в алгоритме выполняется склейка пути с именами файлов, обязательно проверяйте наличие разделителя в конце строки.
  4. Вызов события «ПриИзменении». Программная запись значения в Объект.КаталогЗагрузки не вызывает интерфейсное событие элемента КаталогЗагрузкиПриИзменении. Если у вас на это событие завязана валидация данных или доступность других кнопок, вызовите обработчик вручную.
← На главную