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