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