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