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