Как ограничить выбор значений в колонке таблицы значений на обычных формах

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

При разработке интерфейсов на обычных формах (толстый клиент) часто возникает задача ограничить выбор пользователя в конкретной ячейке таблицы. Например, если в одной колонке выбран определенный вид товара, то в другой колонке (например, «Объем тары») пользователь должен иметь возможность выбрать только из строго заданного списка значений, а не из всего справочника. В этой статье мы подробно разберем, как реализовать механизм выбора из динамически формируемого списка для колонки ТаблицыЗначений.

Постановка задачи и анализ ситуации

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

Способ 1: Использование списка выбора элемента управления

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

Разберем по шагам алгоритм реализации:

  1. Настройте свойства колонки в конфигураторе или программно: установите флаг РежимВыбораИзСписка в значение Истина и включите отображение кнопки списка выбора.
  2. Используйте событие ПередНачаломВыбора или ПриНачалеРедактирования для заполнения списка.

Рассмотрим пример кода, который необходимо разместить в модуле формы:


Процедура МояТЗПередНачаломВыбора(Элемент, СтандартнаяОбработка)
    
    // Получаем текущую строку, чтобы понять контекст
    ТекущиеДанные = ЭлементыФормы.МояТЗ.ТекущиеДанные;
    
    // Если в соседней колонке "Товар" указан сок, формируем список объемов
    Если ТекущиеДанные.Товар.Наименование = "Сок" Тогда
        
        // Отменяем стандартное открытие формы справочника
        СтандартнаяОбработка = Ложь;
        
        // Обращаемся к колонке и ее элементу управления
        КолонкаОбъем = ЭлементыФормы.МояТЗ.Колонки.ОбъемТары;
        СписокВыбора = КолонкаОбъем.ЭлементУправления.СписокВыбора;
        
        // Обязательно очищаем старые значения, иначе они будут накапливаться
        СписокВыбора.Очистить();
        
        // Добавляем нужные ссылки из справочника
        СписокВыбора.Добавить(Справочники.ОбъемыНоменклатуры.НайтиПоНаименованию("0.48л"));
        СписокВыбора.Добавить(Справочники.ОбъемыНоменклатуры.НайтиПоНаименованию("0.98л"));
        СписокВыбора.Добавить(Справочники.ОбъемыНоменклатуры.НайтиПоНаименованию("1.98л"));
        
        // Включаем режим выбора из списка для этого элемента
        КолонкаОбъем.ЭлементУправления.РежимВыбораИзСписка = Истина;
        
    КонецЕсли;

КонецПроцедуры

Важные нюансы жизненного цикла элемента управления

Проанализируем ситуацию, когда список должен быть разным для каждой строки. Поскольку ЭлементУправления общий для всей колонки, если вы измените СписокВыбора в одной строке и не переопределите его в другой, пользователь увидит неактуальные данные.

Рекомендация: всегда вызывайте СписокВыбора.Очистить() в начале обработки события и устанавливайте РежимВыбораИзСписка = Ложь, если для данной строки ограничение не требуется. Это вернет колонке стандартное поведение (выбор из всего справочника).

Способ 2: Программный вызов метода ВыбратьИзСписка

Если вам требуется еще большая гибкость, можно использовать метод ВыбратьИзСписка. Этот метод позволяет показать список значений в любом месте, привязав его к конкретному элементу формы. Выясним, как это работает на практике.

Для этого в событии НачалоВыбора мы полностью берем управление на себя:


Процедура МояТЗОбъемНачалоВыбора(Элемент, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь; // Отключаем стандартный механизм 1С
    
    СЗ = Новый СписокЗначений;
    СЗ.Добавить(Справочники.Объемы.НайтиПоКоду("001"), "Малый объем (0.48л)");
    СЗ.Добавить(Справочники.Объемы.НайтиПоКоду("002"), "Средний объем (0.98л)");
    
    // Показываем список пользователю прямо у ячейки
    ВыбранныйЭлемент = ВыбратьИзСписка(СЗ, Элемент);
    
    Если ВыбранныйЭлемент <> Неопределено Тогда
        // Записываем результат в данные текущей строки
        ЭлементыФормы.МояТЗ.ТекущиеДанные.ОбъемТары = ВыбранныйЭлемент.Значение;
    КонецЕсли;

КонецПроцедуры

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

Связь по владельцу — альтернатива без кода

Если ваша логика «сок -> объем» заложена в структуре метаданных (например, справочник «Объемы» подчинен справочнику «Номенклатура»), мы можем использовать встроенный механизм платформы 1С — Связи параметров выбора.

Посмотрим на шаги настройки:

  1. В свойствах колонки табличного поля найдите параметр СвязиПараметровВыбора.
  2. Добавьте новую связь: укажите Отбор.Владелец и выберите поле ЭлементыФормы.МояТЗ.ТекущиеДанные.Товар.
  3. Теперь платформа сама будет фильтровать список объемов, показывая только те, которые принадлежат выбранному товару.

Важно: этот метод работает только для иерархических связей или связей по реквизитам. Если логика фильтрации сложная (например, зависит от нескольких условий или внешних файлов), придется использовать Способ 1.

Типичные ошибки при реализации

Проанализируем основные грабли, на которые наступают разработчики:

Используя приведенные выше инструкции, мы сможем создать удобный и контролируемый интерфейс ввода данных в обычных формах, минимизируя ошибки пользователей при выборе некорректных значений.

← На главную