При разработке сложных обработок или универсальных инструментов часто возникает задача предоставить пользователю возможность выбрать конкретный объект (например, документ или элемент справочника). Однако, если мы заранее не знаем, какой именно это будет объект, нам необходимо сначала предложить пользователю выбрать тип данных, а уже затем — конкретную ссылку. В этой статье мы подробно разберем, как реализовать этот двухэтапный процесс программно, не перегружая интерфейс лишними элементами управления.
Проанализируем самый простой и эффективный способ, заложенный в саму платформу 1С:Предприятие 8. Если на форме размещен реквизит, имеющий составной тип данных, платформа автоматически берет на себя управление процессом выбора. Рассмотрим ситуацию: у вас есть реквизит формы с именем ВыбранныйОбъект, тип которого включает в себя несколько справочников и документов.
Когда пользователь нажимает кнопку выбора (три точки) у такого поля, система сначала открывает стандартное окно «Выбор типа», где перечислены все доступные типы. После выбора типа (например, «Справочник ссылка: Номенклатура») платформа автоматически открывает форму выбора именно этого справочника. Таким образом, нам не нужно писать сложный код для вызова диалогов — достаточно правильно настроить типы реквизита.
Если же вы хотите реализовать это по кнопке, не привязываясь к конкретному полю ввода, мы можем воспользоваться программными методами вызова диалогов.
Выясним, как вызвать окно выбора типа программно. Для этого в современных управляемых формах используется метод ПоказатьВводЗначения. Этот метод позволяет запросить у пользователя значение определенного типа. Если мы передадим в качестве типа ОписаниеТипов, содержащее несколько вариантов, платформа сначала предложит выбрать тип.
Разберем по шагам, как это реализовать в коде:
// 1. Формируем массив типов, которые мы хотим предложить пользователю
МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("СправочникСсылка.Контрагенты"));
МассивТипов.Добавить(Тип("ДокументСсылка.РеализацияТоваровУслуг"));
// 2. Создаем объект ОписаниеТипов на основании этого массива
НужныеТипы = Новый ОписаниеТипов(МассивТипов);
// 3. Вызываем диалог ввода значения
ОписаниеОповещения = Новый ОписаниеОповещения("ПослеВыбораОбъекта", ЭтотОбъект);
ПоказатьВводЗначения(ОписаниеОповещения, Неопределено, "Выберите объект", НужныеТипы);
В данном примере, при выполнении кода, пользователь увидит окно выбора типа, в котором будут только «Контрагенты» и «Реализация товаров и услуг». После выбора типа сразу откроется форма выбора соответствующего объекта. Результат выбора попадет в процедуру ПослеВыбораОбъекта.
Рассмотрим ситуацию, когда нам нужно предоставить пользователю выбор среди всех справочников или документов системы, но при этом мы не хотим вручную перечислять их в массиве. Мы можем динамически сформировать ОписаниеТипов, обратившись к метаданным конфигурации.
Проанализируем следующий алгоритм:
МассивВсехСсылок = Новый Массив;
// Обходим все справочники в метаданных
Для Каждого МетаДанныеСправочника Из Метаданные.Справочники Цикл
ИмяТипа = "СправочникСсылка." + МетаДанныеСправочника.Имя;
МассивВсехСсылок.Добавить(Тип(ИмяТипа));
КонецЦикла;
// Обходим все документы
Для Каждого МетаДанныеДокумента Из Метаданные.Документы Цикл
ИмяТипа = "ДокументСсылка." + МетаДанныеДокумента.Имя;
МассивВсехСсылок.Добавить(Тип(ИмяТипа));
КонецЦикла;
ОписаниеВсехТипов = Новый ОписаниеТипов(МассивВсехСсылок);
Используя такое ОписаниеТипов в методе ПоказатьВводЗначения, мы получим универсальное окно выбора, где будут сгруппированы все справочники и документы базы. Важно отметить, что стандартный диалог платформы автоматически группирует типы по категориям (Справочники, Документы, Перечисления), что облегчает навигацию пользователю.
Иногда стандартное окно выбора типа не устраивает разработчика, например, если нужно, чтобы ветки «Справочники» и «Документы» были свернуты по умолчанию. К сожалению, стандартное окно 1С не позволяет программно управлять состоянием развернутости веток. В этом случае мы рекомендуем создать собственную форму выбора.
Посмотрим, как это сделать:
ДеревоЗначений.Элементы.ДеревоТипов.Развернуть(ИдентификаторУзла, Ложь), чтобы оставить только нужные группы открытыми.Такой подход требует больше времени на реализацию, но дает полный контроль над визуальным представлением списка типов.
Разберем еще один альтернативный вариант, который часто оказывается более удобным в интерфейсе «Такси». Если список типов ограничен (например, 5–10 вариантов), вместо тяжелого модального окна выбора типа лучше использовать выбор из списка.
Алгоритм действий следующий:
// Создаем список доступных типов для пользователя
СписокВыбора = Новый СписокЗначений;
СписокВыбора.Добавить("Справочник.Номенклатура", "Товары");
СписокВыбора.Добавить("Справочник.Контрагенты", "Клиенты");
// Показываем список выбора
ОписаниеОповещения = Новый ОписаниеОповещения("ОбработатьВыборТипа", ЭтотОбъект);
ПоказатьВыборИзСписка(ОписаниеОповещения, СписокВыбора);
В процедуре ОбработатьВыборТипа, получив выбранную строку (например, "Справочник.Номенклатура"), мы можем программно вызвать форму выбора конкретного справочника, используя метод ОткрытьФорму:
// Внутри процедуры обработки оповещения
ОткрытьФорму(ВыбранноеИмяМетаданных + ".ФормаВыбора", , ЭтаФорма);
Проанализируем ситуацию, когда вам нужно получить только Уникальный Идентификатор (GUID) объекта, находящегося в другой базе. В этом случае не обязательно загружать весь объект целиком. После того как пользователь выбрал ссылку через любой из вышеперечисленных методов, вы можете получить GUID следующим образом, а для сопоставления объектов с несовпадающими идентификаторами использовать перенос данных между похожими конфигурациями 1С по произвольным полям поиска:
Идентификатор = ВыбраннаяСсылка.УникальныйИдентификатор();
Это значение типа УникальныйИдентификатор легко преобразуется в строку и может быть передано в другую информационную базу для поиска соответствующего объекта без необходимости синхронизации самих ссылочных данных. Для быстрого получения и визуализации таких идентификаторов непосредственно в интерфейсе программы можно применить команду отображения GUID для элементов и списков объектов.
Подводя итог, можно сказать, что для большинства задач достаточно штатного метода ПоказатьВводЗначения с правильно сформированным объектом ОписаниеТипов. Это сохраняет единообразие интерфейса системы и требует минимум усилий от разработчика. В качестве готовой альтернативы самостоятельному программированию диалогов можно использовать универсальную форму для ввода значений различных типов.