Как сделать, чтобы поле в 1С 8.3 предлагало только подходящие значения

· 9 мин

Содержание

Зависимость выбора в 1С 8.3 настраивается двумя свойствами реквизита или поля формы: «Параметры выбора» задают постоянный отбор (Отбор.ЭтоГруппа = Ложь), а «Связи параметров выбора» берут значение отбора из другого реквизита (Отбор.Владелец ← Объект.Контрагент). Платформа передаёт их в форму выбора и при вводе по строке, а динамический список сам накладывает отбор.

Типичная боль: пользователь выбирает договор чужого контрагента или склад другой организации, документ проводится, а ошибка всплывает в отчётах. Закрыть эту дыру можно в конфигураторе, кодом формы или в модуле менеджера — и каждый способ действует в своих границах.

Как платформа связывает поля и форму выбора

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

Что попадает в эту структуру:

  • 📌 Параметры выбора — фиксированные пары «имя = значение». Значение задаётся при разработке и не меняется.
  • 🔗 Связи параметров выбора — пары «имя = путь к данным». Значение берётся в момент выбора из реквизита формы.
  • 🧩 Связь по типу — для полей составного типа: тип значения определяется другим полем (классика — субконто, тип которого задаёт вид субконто).

Имя параметра бывает двух видов:

Имя параметраЧто делает платформа
Отбор.<Реквизит>Кладёт значение в Параметры.Отбор формы выбора; динамический список накладывает отбор автоматически
Любое другое имя, например ВидДоговораПередаёт как обычный параметр формы; форма выбора должна иметь параметр с таким именем и обработать его сама

Если в Отбор.<Реквизит> передать фиксированный массив, отбор работает как «В списке». Так ограничивают выбор несколькими допустимыми значениями.

Отбор, пришедший через параметры выбора, пользователь не может снять в настройках списка. Отбор, установленный пользователем вручную, наоборот, ничего не гарантирует: его легко убрать.

Главное ограничение механизма: параметры и связи выбора действуют только при интерактивном выборе. Значение, записанное в реквизит кодом, обработкой загрузки или обменом, платформа на соответствие не проверяет. Для жёсткого контроля нужна проверка в ОбработкаПроверкиЗаполнения или ПередЗаписью объекта.

Зависимости параметров выбора в конфигураторе и в форме

Настройку можно сделать в двух местах. От выбора зависит, где она будет действовать.

На уровне реквизита объекта

Откройте реквизит в дереве метаданных, вызовите палитру свойств и найдите свойства Параметры выбора и Связи параметров выбора.

  1. Для постоянного ограничения нажмите кнопку выбора в свойстве Параметры выбора, добавьте строку, в колонке «Имя» укажите Отбор.ЭтоГруппа, в колонке «Значение» — Ложь.
  2. Для зависимости откройте Связи параметров выбора. В левой части выберите реквизит-источник (например, Контрагент), в колонке «Параметр» укажите Отбор.Владелец.
  3. В колонке режима изменения выберите поведение зависимого поля при смене источника: Очищать или Не изменять.
  4. Сохраните конфигурацию и обновите конфигурацию базы данных.

Настройка на уровне реквизита действует во всех формах объекта, включая формы, сгенерированные автоматически. Это предпочтительный вариант для правил предметной области: «договор принадлежит контрагенту» верно везде.

На уровне поля формы

У поля формы есть свойства с теми же именами. Здесь путь к данным пишется с префиксом основного реквизита формы: Объект.Контрагент, а не просто Контрагент.

Используйте этот уровень, когда ограничение нужно только в одной форме. Например, в форме быстрого ввода разрешены только активные договоры, а в основной форме — любые.

Если зависимость задана и в реквизите, и в поле формы, при отладке проверяйте оба места. Разработчик часто правит одно и не видит, что поведение определяет другое.

Отбор в динамическом списке на клиенте

В самой форме выбора или в форме списка отбор можно добавить кодом через Список.Отбор или компоновщик настроек. В типовых конфигурациях на БСП для этого есть ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбораДинамическогоСписка. Такой отбор действует только в этой форме и не передаётся при вводе по строке, поэтому для ограничения выбора в документах он не заменяет параметры выбора.

Программное управление параметрами выбора

Когда условие зависит от данных, а не от одного реквизита, связи задают кодом. Свойства ПараметрыВыбора и СвязиПараметровВыбора у поля формы принимают фиксированный массив. Обычный массив платформа не примет, а изменить элемент существующего фиксированного массива нельзя — массив собирают заново целиком.

&НаСервере
Процедура НастроитьВыборДоговора()

    МассивСвязей = Новый Массив;
    МассивСвязей.Добавить(Новый СвязьПараметраВыбора("Отбор.Владелец",
        "Объект.Контрагент", РежимИзмененияСвязанногоЗначения.Очищать));
    МассивСвязей.Добавить(Новый СвязьПараметраВыбора("Отбор.Организация",
        "Объект.Организация", РежимИзмененияСвязанногоЗначения.Очищать));
    Элементы.Договор.СвязиПараметровВыбора = Новый ФиксированныйМассив(МассивСвязей);

    МассивПараметров = Новый Массив;
    МассивПараметров.Добавить(Новый ПараметрВыбора("Отбор.ПометкаУдаления", Ложь));
    Элементы.Договор.ПараметрыВыбора = Новый ФиксированныйМассив(МассивПараметров);

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

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    НастроитьВыборДоговора();
КонецПроцедуры

Переменную не называйте Параметры: это имя занято параметрами самой формы, и код начнёт портить их.

Добавить к существующим параметрам, а не затереть

Если у поля уже есть параметры из конфигуратора, присвоение нового массива их уберёт. Скопируйте старые элементы и добавьте свой:

МассивПараметров = Новый Массив;
Для Каждого ПараметрВыбораПоля Из Элементы.Склад.ПараметрыВыбора Цикл
    МассивПараметров.Добавить(ПараметрВыбораПоля);
КонецЦикла;
МассивПараметров.Добавить(Новый ПараметрВыбора("Отбор.ТипСклада", ТипСкладаДляФормы));
Элементы.Склад.ПараметрыВыбора = Новый ФиксированныйМассив(МассивПараметров);

Здесь ТипСкладаДляФормы — значение, которое вы вычислили заранее. Если оно меняется в процессе работы, вызывайте такую процедуру из обработчика ПриИзменении реквизита-источника.

Ограничение в модуле менеджера

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

Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка)

    Если Не Параметры.Отбор.Свойство("ПометкаУдаления") Тогда
        Параметры.Отбор.Вставить("ПометкаУдаления", Ложь);
    КонецЕсли;

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

СтандартнаяОбработка остаётся Истина: платформа сама подберёт данные, но уже с дополненным отбором. Если поставить Ложь, придётся самому заполнить ДанныеВыбора списком значений и обработать введённую строку.

Связи параметров выбора в табличных частях

В табличной части зависимость обычно строится внутри одной строки: характеристика зависит от номенклатуры, серия — от номенклатуры и склада.

В конфигураторе

Для реквизита табличной части в окне связей доступны и реквизиты шапки, и реквизиты той же табличной части. Выберите реквизит строки — платформа сама подставит значение из текущей строки.

В поле формы

В свойствах колонки-поля путь к соседней колонке указывают через текущие данные таблицы формы:

Что нужноПуть к данным в связи
Значение из шапки документаОбъект.Склад
Значение из той же строкиЭлементы.Товары.ТекущиеДанные.Номенклатура

Программно это та же конструкция СвязьПараметраВыбора, только путь ведёт в ТекущиеДанные.

Режим Очищать в табличной части очищает значение в той строке, где сменили источник. Другие строки не трогаются, даже если в них то же значение.

Подводные камни строк

  • ⚙️ Групповое заполнение. Подбор, заполнение по основанию, загрузка из файла заносят значения кодом — связи их не проверяют. Если сменили номенклатуру обработкой, характеристика не очистится.
  • 📋 Копирование строк. Скопированная строка сохраняет значения, даже если они уже не проходят отбор.
  • 🔀 Разные условия в строках. Если отбор зависит не от колонки, а от вычисляемого признака, проще задать фиксированные параметры в ПриАктивизацииСтроки таблицы: перед выбором поле получит актуальные параметры для текущей строки.

Диагностика: почему отбор не работает

Чаще всего проблема в имени параметра, пути к данным или в нестандартной форме выбора.

Диагностика: выберите симптом

Как посмотреть, что реально передаётся

  1. Поставьте точку останова в ПриСозданииНаСервере формы выбора.
  2. Откройте выбор в отладке и посмотрите Параметры.Отбор в табло: видны все ключи и значения.
  3. Если ключей нет — проблема на стороне вызывающей формы: смотрите свойства поля и реквизита.
  4. Для ввода по строке ставьте точку в ОбработкаПолученияДанныхВыбора модуля менеджера и смотрите тот же Параметры.Отбор.

Ещё один источник путаницы — значение-источник пустое. Связь передаёт пустую ссылку, и отбор Владелец = пустая ссылка возвращает пустой список. Пользователь видит пустую форму выбора и думает, что справочник не заполнен. Решение — проверка заполненности источника в НачалоВыбора с сообщением «Сначала выберите контрагента».

Скорость выбора: как не тормозить на больших справочниках

На справочнике в сотни тысяч элементов неудачный отбор превращает каждое нажатие кнопки выбора в паузу на несколько секунд.

Что помогает:

  • 🗂️ Индекс по полю отбора. Для реквизита, по которому идёт отбор, включите свойство Индексировать (вариант с доп. упорядочиванием — если список ещё и сортируется по нему). Владелец у подчинённого справочника индексируется платформой и так.
  • ⚡ Ввод по строке. Чем меньше полей в свойстве Ввод по строке, тем быстрее поиск. Наименование плюс код — обычно достаточно.
  • 🔍 Полнотекстовый поиск при вводе по строке. Свойство справочника можно отключить, если индекс полнотекстового поиска не обновляется регулярно — иначе результаты будут неполными.
  • 📄 Динамическое считывание данных. У динамического списка в форме выбора оставьте его включённым: список читает только видимую порцию строк.
  • 🚫 Без произвольного запроса без нужды. Если список построен на произвольном запросе с соединениями, отбор накладывается на результат и может работать медленнее, чем на основной таблице.
  • 🧮 Тяжёлая логика вне клиента. Сложные вычисления условия делайте один раз на сервере и кладите результат в фиксированный параметр, а не считайте при каждом открытии.

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

Включение индекса меняет структуру таблиц базы. Обновление конфигурации базы данных с реструктуризацией требует монопольного доступа: пользователей придётся выгнать из базы. Делайте это в нерабочее время и после резервной копии.

Когда параметров выбора недостаточно

Связи выбора — это удобство интерфейса, а не правило целостности. В трёх случаях нужен дополнительный механизм:

ЗадачаЧем решать
Запретить записать неверное значение любым способомПроверка в ОбработкаПроверкиЗаполнения или ПередЗаписью объекта
Скрыть элементы от определённых пользователейОграничение доступа на уровне записей (RLS), а не отбор
Условие с несколькими таблицамиОбработкаПолученияДанныхВыбора или своя форма выбора с запросом

Отбор через параметры выбора не защищает данные: пользователь с правами может открыть справочник из меню и увидеть всё. Если элементы должны быть невидимы, это задача прав доступа.

Частые вопросы

Чем «Связи параметров выбора» отличаются от «Связи по владельцу» из старых версий?
Связь по владельцу была частным случаем. В 8.2 и 8.3 она выражается связью параметра Отбор.Владелец и позволяет связывать поля по любому реквизиту, а не только по владельцу.
Можно ли отфильтровать по реквизиту табличной части справочника?
Через Отбор. — нет, отбор работает по реквизитам шапки. Для такой задачи нужна обработка в ОбработкаПолученияДанныхВыбора с запросом или своя форма выбора.
Работают ли параметры выбора в отчётах на СКД?
У параметров и полей схемы компоновки есть свои свойства параметров выбора и связей. Механизм тот же, но настраивается в схеме, а не в реквизите.
Почему у пользователя пропала зависимость после обновления типовой?
Если вы правили реквизит типовой конфигурации напрямую, обновление могло перезаписать свойство. Такие доработки надёжнее делать в расширении, задавая связи кодом в форме.
Можно ли передать в отбор значение «не равно»?
Нет, параметр выбора задаёт равенство или «в списке» для массива. Для исключения передайте массив допустимых значений или используйте обработчик модуля менеджера.