При разработке отчетов, обработок и прикладных решений на платформе 1С:Предприятие 8.3 часто возникает задача предоставить пользователю возможность выбирать список ссылочных элементов (например, конкретные позиции справочника СправочникСсылка.Должности или СправочникСсылка.Организации). Если добавить реквизит с типом СписокЗначений непосредственно в реквизиты объекта конфигурации (отчета или обработки), в палитре свойств метаданных отсутствует возможность ограничить состав типов хранимых значений. При этом для реквизита формы такой выбор доступен.
Разберем причины такого поведения платформы, проанализируем варианты решения задачи и посмотрим, как правильно настроить типизацию и удобный подбор элементов на управляемой форме.
Выясним причину архитектурных различий между реквизитами формы и реквизитами объекта:
СписокЗначений не поддерживается как реквизит постоянного хранения в базе данных, так как у него нет прямого отображения в структуры реляционных СУБД. Для хранения списков в базе данных используются табличные части или реквизит с типом ХранилищеЗначения.СписокЗначений можно добавить в отчет или обработку, платформа оставляет его коллекцией с произвольным (составным) типом значений. Задать строгое описание типов на уровне дерева метаданных нельзя.СписокЗначений в окне свойств доступно специальное поле Тип значения, где разработчик может жестко задать конкретную ссылку или состав типов.Если реквизит СписокЗначений уже создан в объекте (например, Объект.СписокДолжностей) и выведен на форму в виде таблицы, наиболее надежным и правильным способом является явная установка свойства ТипЗначения при инициализации формы. Назначим тип один раз при создании формы на сервере.
Рассмотрим пример кода в модуле управляемой формы:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Ограничиваем тип элементов списка нужным справочником
Объект.СписокДолжностей.ТипЗначения = Новый ОписаниеТипов("СправочникСсылка.Должности");
КонецПроцедуры
После выполнения этого кода колонка Значение в таблице формы автоматически примет требуемый тип. При нажатии кнопки добавления строки или при редактировании ячейки пользователю сразу будет открываться форма выбора соответствующего справочника.
При тестировании стандартного подбора можно столкнуться с ситуацией, когда по кнопке Добавить выбор работает корректно, а стандартная кнопка Подбор либо открывает выпадающий список, либо не срабатывает. Проанализируем, почему это происходит.
Поведение выбора зависит от свойства справочника Быстрый выбор в метаданных (например, для справочника «Организации» он часто включен по умолчанию, а для «Номенклатуры» — выключен). Если быстрый выбор активен, поле пытается предложить выпадающий список вместо полноценного окна выбора.
Чтобы обеспечить предсказуемое открытие формы выбора справочника при любых настройках метаданных, настроим свойства элемента управления (поля ввода колонки «Значение») в процедуре ПриСозданииНаСервере или интерактивно в свойствах элемента формы:
&НаСервере
Процедура НастроитьЭлементыФормы()
ЭлементКолонки = Элементы.СписокДолжностейЗначение;
ЭлементКолонки.КнопкаВыбора = Истина;
ЭлементКолонки.КнопкаВыпадающегоСписка = Ложь;
ЭлементКолонки.РежимВыбораИзСписка = Ложь;
КонецПроцедуры
Рассмотрим альтернативный подход, который часто применяется при сложной логике интерфейса. Вместо привязки таблицы формы напрямую к реквизиту объекта создается отдельный реквизит формы.
Разберем по шагам реализацию данного варианта:
СписокДолжностейФормы, с типом СписокЗначений.СправочникСсылка.Должности).Посмотрим на пример процедур чтения и сохранения данных:
&НаСервере
Процедура ЗагрузитьСписокИзОбъекта()
// Заполняем реквизит формы из данных объекта
СписокДолжностейФормы.ЗагрузитьЗначения(Объект.СписокДолжностей.ВыгрузитьЗначения());
КонецПроцедуры
&НаСервере
Процедура СохранитьСписокВОбъект()
// Переносим выбранные элементы обратно в реквизит объекта
Объект.СписокДолжностей.Очистить();
Для Каждого ЭлементСписка Из СписокДолжностейФормы Цикл
Объект.СписокДолжностей.Добавить(ЭлементСписка.Значение, ЭлементСписка.Представление, ЭлементСписка.Пометка);
КонецЦикла;
КонецПроцедуры
Когда требуется предоставить пользователю возможность выбирать сразу группу элементов из справочника (множественный выбор с зажатой клавишей Shift/Ctrl или флажками), создадим собственную команду подбора.
Рассмотрим программную реализацию множественного подбора:
&НаКлиенте
Процедура КомандаПодбор(Команда)
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("МножественныйВыбор", Истина);
ПараметрыФормы.Вставить("ЗакрыватьПриВыборе", Ложь);
// Открываем форму выбора справочника с передачей текущей формы как владельца
ОткрытьФорму("Справочник.Должности.ФормаВыбора", ПараметрыФормы, ЭтаФорма);
КонецПроцедуры
&НаКлиенте
Процедура ОбработкаВыбора(ЗначениеВыбора, ИсточникВыбора)
// Обрабатываем результат множественного выбора
Если ТипЗнч(ЗначениеВыбора) = Тип("Массив") Тогда
Для Каждого ВыбранныйЭлемент Из ЗначениеВыбора Цикл
Если Объект.СписокДолжностей.НайтиПоЗначению(ВыбранныйЭлемент) = Неопределено Тогда
Объект.СписокДолжностей.Добавить(ВыбранныйЭлемент);
КонецЕсли;
КонецЦикла;
ИначеЕсли ЗначениеЗаполнено(ЗначениеВыбора) Тогда
Если Объект.СписокДолжностей.НайтиПоЗначению(ЗначениеВыбора) = Неопределено Тогда
Объект.СписокДолжностей.Добавить(ЗначениеВыбора);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Для корректной работы со СпискомЗначений в управляемых формах 1С рекомендуются следующие подходы:
ТипЗначения программно через Новый ОписаниеТипов(...) в событии ПриСозданииНаСервере.МножественныйВыбор = Истина и обработкой результата в событии ОбработкаВыбора.