Как получить значение из формы выбора справочника в 1С и почему переменная оказывается пустой

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

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

Причина 1. Затенение локальной переменной реквизитом объекта

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

Если мы пишем строку вида:

Подразделение = ФормаВыбора.ОткрытьМодально();

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

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

Решить эту проблему можно двумя путями:

  1. Явно объявить локальную переменную: указать директиву Перем в начале процедуры, чтобы изолировать контекст выполнения.
  2. Использовать уникальное имя переменной: назвать переменную так, чтобы она не пересекалась с именами реквизитов документа или формы (например, ВыбранноеПодразделениеОрганизации).

Причина 2. Ошибки в параметрах метода ПолучитьФормуВыбора

Посмотрим на параметры стандартного метода получения формы выбора у менеджера справочника:

ПолучитьФормуВыбора(Форма, Владелец, КлючУникальности)

Рассмотрим распространенную ошибку передачи параметров: когда третьим параметром передается ссылка на текущий объект:


ФормаВыбора = Справочники.ПодразделенияОрганизаций.ПолучитьФормуВыбора(,, ЭтотОбъект);

В данном случае аргумент ЭтотОбъект ошибочно передается в КлючУникальности, а параметр Владелец остается пустым. Если вам требуется привязать форму выбора к конкретному элементу управления, его следует указывать вторым параметром (например, элемент табличного поля). Если же форма открывается модально для ручной обработки результата в коде, параметры владельца и ключа уникальности чаще всего можно опустить вовсе.

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

Причина 3. Особенности работы метода ОткрытьМодально

Выясним, почему метод ОткрытьМодально() может возвращать значение Неопределено даже при видимом выборе строки пользователем:

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

Способ 1. Использование функции ВвестиЗначение

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


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

Обратите внимание на объявление Перем ВыбранноеПодразделение;. Это гарантирует, что платформа не запишет результат в реквизит шапки с похожим именем и не исказит тип данных.

Способ 2. Корректное открытие формы выбора модально

Если вам требуется открыть конкретную форму выбора (например, для наложения специализированных отборов перед открытием), используем модальное открытие с явной настройкой свойств:


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

Способ 3. Немодальный выбор через владельца формы (рекомендуемый механизм)

Рассмотрим наиболее правильный с точки зрения архитектуры платформы 1С механизм — немодальное открытие формы выбора с назначением владельца. Этот способ не блокирует работу интерфейса и соответствует современным стандартам разработки.

Разберем по шагам, как это реализовать:

  1. Открываем форму выбора, передавая в качестве владельца элемент управления табличной части:
    
    Процедура ДействияФормыОткрытьВыбор(Кнопка)
        ФормаВыбора = Справочники.ПодразделенияОрганизаций.ПолучитьФормуВыбора(, ЭлементыФормы.Товары);
        ФормаВыбора.Открыть();
    КонецПроцедуры
    
  2. В свойствах табличного поля Товары назначаем обработчик события ОбработкаВыбора. В этот обработчик платформа автоматически передаст результат, выбранный пользователем:
    
    Процедура ТоварыОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
        
        Если ЗначениеЗаполнено(ВыбранноеЗначение) Тогда
            СкопироватьПодразделение(Товары, ВыбранноеЗначение);
        КонецЕсли;
        
    КонецПроцедуры
    

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

← На главную