Как сделать, чтобы поле в 1С 8.3 предлагало только подходящие значения
Содержание
Зависимость выбора в 1С 8.3 настраивается двумя свойствами реквизита или поля формы: «Параметры выбора» задают постоянный отбор (Отбор.ЭтоГруппа = Ложь), а «Связи параметров выбора» берут значение отбора из другого реквизита (Отбор.Владелец ← Объект.Контрагент). Платформа передаёт их в форму выбора и при вводе по строке, а динамический список сам накладывает отбор.
Типичная боль: пользователь выбирает договор чужого контрагента или склад другой организации, документ проводится, а ошибка всплывает в отчётах. Закрыть эту дыру можно в конфигураторе, кодом формы или в модуле менеджера — и каждый способ действует в своих границах.
Как платформа связывает поля и форму выбора
Механизм один и тот же для всех ссылочных полей. Когда пользователь нажимает кнопку выбора или начинает набирать текст, платформа собирает структуру параметров и передаёт её дальше.
Что попадает в эту структуру:
- 📌 Параметры выбора — фиксированные пары «имя = значение». Значение задаётся при разработке и не меняется.
- 🔗 Связи параметров выбора — пары «имя = путь к данным». Значение берётся в момент выбора из реквизита формы.
- 🧩 Связь по типу — для полей составного типа: тип значения определяется другим полем (классика — субконто, тип которого задаёт вид субконто).
Имя параметра бывает двух видов:
| Имя параметра | Что делает платформа |
|---|---|
Отбор.<Реквизит> | Кладёт значение в Параметры.Отбор формы выбора; динамический список накладывает отбор автоматически |
Любое другое имя, например ВидДоговора | Передаёт как обычный параметр формы; форма выбора должна иметь параметр с таким именем и обработать его сама |
Если в Отбор.<Реквизит> передать фиксированный массив, отбор работает как «В списке». Так ограничивают выбор несколькими допустимыми значениями.
Отбор, пришедший через параметры выбора, пользователь не может снять в настройках списка. Отбор, установленный пользователем вручную, наоборот, ничего не гарантирует: его легко убрать.
Главное ограничение механизма: параметры и связи выбора действуют только при интерактивном выборе. Значение, записанное в реквизит кодом, обработкой загрузки или обменом, платформа на соответствие не проверяет. Для жёсткого контроля нужна проверка в ОбработкаПроверкиЗаполнения или ПередЗаписью объекта.
Зависимости параметров выбора в конфигураторе и в форме
Настройку можно сделать в двух местах. От выбора зависит, где она будет действовать.
На уровне реквизита объекта
Откройте реквизит в дереве метаданных, вызовите палитру свойств и найдите свойства Параметры выбора и Связи параметров выбора.
- Для постоянного ограничения нажмите кнопку выбора в свойстве
Параметры выбора, добавьте строку, в колонке «Имя» укажитеОтбор.ЭтоГруппа, в колонке «Значение» —Ложь. - Для зависимости откройте
Связи параметров выбора. В левой части выберите реквизит-источник (например,Контрагент), в колонке «Параметр» укажитеОтбор.Владелец. - В колонке режима изменения выберите поведение зависимого поля при смене источника:
ОчищатьилиНе изменять. - Сохраните конфигурацию и обновите конфигурацию базы данных.
Настройка на уровне реквизита действует во всех формах объекта, включая формы, сгенерированные автоматически. Это предпочтительный вариант для правил предметной области: «договор принадлежит контрагенту» верно везде.
На уровне поля формы
У поля формы есть свойства с теми же именами. Здесь путь к данным пишется с префиксом основного реквизита формы: Объект.Контрагент, а не просто Контрагент.
Используйте этот уровень, когда ограничение нужно только в одной форме. Например, в форме быстрого ввода разрешены только активные договоры, а в основной форме — любые.
Если зависимость задана и в реквизите, и в поле формы, при отладке проверяйте оба места. Разработчик часто правит одно и не видит, что поведение определяет другое.
Отбор в динамическом списке на клиенте
В самой форме выбора или в форме списка отбор можно добавить кодом через Список.Отбор или компоновщик настроек. В типовых конфигурациях на БСП для этого есть ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбораДинамическогоСписка. Такой отбор действует только в этой форме и не передаётся при вводе по строке, поэтому для ограничения выбора в документах он не заменяет параметры выбора.
Программное управление параметрами выбора
Когда условие зависит от данных, а не от одного реквизита, связи задают кодом. Свойства ПараметрыВыбора и СвязиПараметровВыбора у поля формы принимают фиксированный массив. Обычный массив платформа не примет, а изменить элемент существующего фиксированного массива нельзя — массив собирают заново целиком.
&НаСервере
Процедура НастроитьВыборДоговора()
МассивСвязей = Новый Массив;
МассивСвязей.Добавить(Новый СвязьПараметраВыбора("Отбор.Владелец",
"Объект.Контрагент", РежимИзмененияСвязанногоЗначения.Очищать));
МассивСвязей.Добавить(Новый СвязьПараметраВыбора("Отбор.Организация",
"Объект.Организация", РежимИзмененияСвязанногоЗначения.Очищать));
Элементы.Договор.СвязиПараметровВыбора = Новый ФиксированныйМассив(МассивСвязей);
МассивПараметров = Новый Массив;
МассивПараметров.Добавить(Новый ПараметрВыбора("Отбор.ПометкаУдаления", Ложь));
Элементы.Договор.ПараметрыВыбора = Новый ФиксированныйМассив(МассивПараметров);
КонецПроцедуры
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
НастроитьВыборДоговора();
КонецПроцедуры
Переменную не называйте Параметры: это имя занято параметрами самой формы, и код начнёт портить их.
Добавить к существующим параметрам, а не затереть
Если у поля уже есть параметры из конфигуратора, присвоение нового массива их уберёт. Скопируйте старые элементы и добавьте свой:
МассивПараметров = Новый Массив;
Для Каждого ПараметрВыбораПоля Из Элементы.Склад.ПараметрыВыбора Цикл
МассивПараметров.Добавить(ПараметрВыбораПоля);
КонецЦикла;
МассивПараметров.Добавить(Новый ПараметрВыбора("Отбор.ТипСклада", ТипСкладаДляФормы));
Элементы.Склад.ПараметрыВыбора = Новый ФиксированныйМассив(МассивПараметров);
Здесь ТипСкладаДляФормы — значение, которое вы вычислили заранее. Если оно меняется в процессе работы, вызывайте такую процедуру из обработчика ПриИзменении реквизита-источника.
Ограничение в модуле менеджера
Чтобы правило действовало во всех формах и при вводе по строке, используйте обработчик модуля менеджера справочника:
Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка)
Если Не Параметры.Отбор.Свойство("ПометкаУдаления") Тогда
Параметры.Отбор.Вставить("ПометкаУдаления", Ложь);
КонецЕсли;
КонецПроцедуры
СтандартнаяОбработка остаётся Истина: платформа сама подберёт данные, но уже с дополненным отбором. Если поставить Ложь, придётся самому заполнить ДанныеВыбора списком значений и обработать введённую строку.
Связи параметров выбора в табличных частях
В табличной части зависимость обычно строится внутри одной строки: характеристика зависит от номенклатуры, серия — от номенклатуры и склада.
В конфигураторе
Для реквизита табличной части в окне связей доступны и реквизиты шапки, и реквизиты той же табличной части. Выберите реквизит строки — платформа сама подставит значение из текущей строки.
В поле формы
В свойствах колонки-поля путь к соседней колонке указывают через текущие данные таблицы формы:
| Что нужно | Путь к данным в связи |
|---|---|
| Значение из шапки документа | Объект.Склад |
| Значение из той же строки | Элементы.Товары.ТекущиеДанные.Номенклатура |
Программно это та же конструкция СвязьПараметраВыбора, только путь ведёт в ТекущиеДанные.
Режим Очищать в табличной части очищает значение в той строке, где сменили источник. Другие строки не трогаются, даже если в них то же значение.
Подводные камни строк
- ⚙️ Групповое заполнение. Подбор, заполнение по основанию, загрузка из файла заносят значения кодом — связи их не проверяют. Если сменили номенклатуру обработкой, характеристика не очистится.
- 📋 Копирование строк. Скопированная строка сохраняет значения, даже если они уже не проходят отбор.
- 🔀 Разные условия в строках. Если отбор зависит не от колонки, а от вычисляемого признака, проще задать фиксированные параметры в
ПриАктивизацииСтрокитаблицы: перед выбором поле получит актуальные параметры для текущей строки.
Диагностика: почему отбор не работает
Чаще всего проблема в имени параметра, пути к данным или в нестандартной форме выбора.
Как посмотреть, что реально передаётся
- Поставьте точку останова в
ПриСозданииНаСервереформы выбора. - Откройте выбор в отладке и посмотрите
Параметры.Отборв табло: видны все ключи и значения. - Если ключей нет — проблема на стороне вызывающей формы: смотрите свойства поля и реквизита.
- Для ввода по строке ставьте точку в
ОбработкаПолученияДанныхВыборамодуля менеджера и смотрите тот жеПараметры.Отбор.
Ещё один источник путаницы — значение-источник пустое. Связь передаёт пустую ссылку, и отбор Владелец = пустая ссылка возвращает пустой список. Пользователь видит пустую форму выбора и думает, что справочник не заполнен. Решение — проверка заполненности источника в НачалоВыбора с сообщением «Сначала выберите контрагента».
Скорость выбора: как не тормозить на больших справочниках
На справочнике в сотни тысяч элементов неудачный отбор превращает каждое нажатие кнопки выбора в паузу на несколько секунд.
Что помогает:
- 🗂️ Индекс по полю отбора. Для реквизита, по которому идёт отбор, включите свойство
Индексировать(вариант с доп. упорядочиванием — если список ещё и сортируется по нему). Владелец у подчинённого справочника индексируется платформой и так. - ⚡ Ввод по строке. Чем меньше полей в свойстве
Ввод по строке, тем быстрее поиск. Наименование плюс код — обычно достаточно. - 🔍 Полнотекстовый поиск при вводе по строке. Свойство справочника можно отключить, если индекс полнотекстового поиска не обновляется регулярно — иначе результаты будут неполными.
- 📄 Динамическое считывание данных. У динамического списка в форме выбора оставьте его включённым: список читает только видимую порцию строк.
- 🚫 Без произвольного запроса без нужды. Если список построен на произвольном запросе с соединениями, отбор накладывается на результат и может работать медленнее, чем на основной таблице.
- 🧮 Тяжёлая логика вне клиента. Сложные вычисления условия делайте один раз на сервере и кладите результат в фиксированный параметр, а не считайте при каждом открытии.
Для маленьких справочников (единицы измерения, ставки) включите Быстрый выбор: вместо формы откроется выпадающий список, и параметры выбора к нему тоже применятся.
Включение индекса меняет структуру таблиц базы. Обновление конфигурации базы данных с реструктуризацией требует монопольного доступа: пользователей придётся выгнать из базы. Делайте это в нерабочее время и после резервной копии.
Когда параметров выбора недостаточно
Связи выбора — это удобство интерфейса, а не правило целостности. В трёх случаях нужен дополнительный механизм:
| Задача | Чем решать |
|---|---|
| Запретить записать неверное значение любым способом | Проверка в ОбработкаПроверкиЗаполнения или ПередЗаписью объекта |
| Скрыть элементы от определённых пользователей | Ограничение доступа на уровне записей (RLS), а не отбор |
| Условие с несколькими таблицами | ОбработкаПолученияДанныхВыбора или своя форма выбора с запросом |
Отбор через параметры выбора не защищает данные: пользователь с правами может открыть справочник из меню и увидеть всё. Если элементы должны быть невидимы, это задача прав доступа.
Частые вопросы
Чем «Связи параметров выбора» отличаются от «Связи по владельцу» из старых версий?
Отбор.Владелец и позволяет связывать поля по любому реквизиту, а не только по владельцу.Можно ли отфильтровать по реквизиту табличной части справочника?
Отбор. — нет, отбор работает по реквизитам шапки. Для такой задачи нужна обработка в ОбработкаПолученияДанныхВыбора с запросом или своя форма выбора.