Как настроить отбор в табличной части по реквизиту другого ссылочного поля в 1С?

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

При разработке документов и справочников в 1С часто возникает задача: ограничить выбор значений во второй колонке табличной части в зависимости от реквизита значения, выбранного в первой колонке. Например, в строке табличной части выбирается Проект (ссылка на справочник Проекты) и СтатьяБюджета (ссылка на справочник СтатьиБюджета). Оба справочника содержат реквизит птТипПроекта. Требуется сделать так, чтобы при выборе статьи бюджета пользователю были доступны только те статьи, у которых птТипПроекта совпадает с типом выбранного проекта, причем отбор должен корректно работать как при открытии формы выбора, так и при вводе текста с клавиатуры (всплывающие подсказки автоподбора).

Разберем, почему стандартная декларативная настройка через свойства элементов не всегда применима «в лоб», и проанализируем доступные способы решения этой задачи на управляемых формах.

Ограничение платформы: почему нельзя настроить связь через точку

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

Таким образом, настроить связь параметров выбора напрямую на реквизит другого ссылочного поля декларативно невозможно. Рассмотрим основные подходы к реализации нужного поведения.

Способ 1. Добавление реквизита только в табличную часть на форме

Если мы не хотим засорять структуру базы данных избыточными данными, нам не обязательно добавлять реквизит птТипПроекта в саму табличную часть объекта метаданных. Достаточно добавить его как колонку табличной части формы (реквизит формы).

Разберем по шагам алгоритм настройки:

  1. В редакторе формы открываем вкладку Реквизиты и разворачиваем дерево данных табличной части объекта.
  2. Добавляем новую колонку непосредственно в реквизит формы табличной части (отображается бордовым значком) с типом значения реквизита птТипПроекта.
  3. Перетаскиваем созданную колонку в элементы формы или оставляем ее только в данных (свойство Видимость можно отключить).
  4. Для элемента формы СтатьяБюджета настраиваем стандартное свойство Связи параметров выбора: указываем имя реквизита отбора Отбор.птТипПроекта и связываем его с нашей новой колонкой формы.
  5. В обработчике события ПриСозданииНаСервере заполняем эту колонку для всех существующих строк документа:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	Для Каждого СтрТЧ Из Объект.ТабличнаяЧасть Цикл
		Если ЗначениеЗаполнено(СтрТЧ.Проект) Тогда
			СтрТЧ.птТипПроекта = СтрТЧ.Проект.птТипПроекта;
		КонецЕсли;
	КонецЦикла;
КонецПроцедуры
  1. В событии элемента формы ПроектПриИзменении актуализируем значение типа проекта и при необходимости очищаем несоответствующую статью:

&НаКлиенте
Процедура ПроектПриИзменении(Элемент)
	ТекущиеДанные = Элементы.ТабличнаяЧасть.ТекущиеДанные;
	Если ТекущиеДанные = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	ТекущиеДанные.птТипПроекта = ПолучитьТипПроектаНаСервере(ТекущиеДанные.Проект);
	// Очищаем статью, если тип проекта изменился
	ТекущиеДанные.СтатьяБюджета = ПредопределенноеЗначение("Справочник.СтатьиБюджета.ПустаяСсылка");
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьТипПроектаНаСервере(СсылкаНаПроект)
	Если ЗначениеЗаполнено(СсылкаНаПроект) Тогда
		Возврат СсылкаНаПроект.птТипПроекта;
	КонецЕсли;
	Возврат Неопределено;
КонецФункции

Способ 2. Программная установка параметров выбора при активизации строки

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

Рассмотрим реализацию этого подхода:

  1. В обработчике события таблицы ТабличнаяЧастьПриАктивизацииСтроки получаем тип проекта текущей строки и устанавливаем массив параметров выбора для элемента СтатьяБюджета:

&НаКлиенте
Процедура ТабличнаяЧастьПриАктивизацииСтроки(Элемент)
	ОбновитьПараметрыВыбораСтатьи();
КонецПроцедуры

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

&НаКлиенте
Процедура ПроектПриИзменении(Элемент)
	ТекущиеДанные = Элементы.ТабличнаяЧасть.ТекущиеДанные;
	Если ТекущиеДанные <> Неопределено Тогда
		ТекущиеДанные.СтатьяБюджета = ПредопределенноеЗначение("Справочник.СтатьиБюджета.ПустаяСсылка");
	КонецЕсли;
	
	ОбновитьПараметрыВыбораСтатьи();
КонецПроцедуры

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

Способ 3. Переопределение «ОбработкаПолученияДанныхВыбора» в модуле менеджера

Если бизнес-логика фильтрации статей едина для всей конфигурации и должна применяться глобально при автоподборе, ее можно инкапсулировать на уровне метаданных справочника СтатьиБюджета.

В модуле менеджера справочника СтатьиБюджета переопределяется стандартный обработчик ОбработкаПолученияДанныхВыбора:


Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка)
	
	Если Параметры.Отбор.Свойство("птТипПроекта") Тогда
		// Логика формирования списка с учетом переданного типа проекта
		СтандартнаяОбработка = Истина; 
		// Платформа сама наложит фильтр по переданному значению отбора
	КонецЕсли;
	
КонецПроцедуры

Сравнение и выбор оптимального решения

Проанализируем плюсы и минусы рассмотренных подходов:

  1. Колонка на форме + декларативная связь (Способ 1): наиболее простой и прозрачный способ для типовой разработки. Не требует постоянного ручного управления массивом параметров выбора в событиях таблицы, платформа сама связывает поля.
  2. Динамическая установка ПараметрыВыбора (Способ 2): идеален, когда нельзя или нежелательно менять состав реквизитов формы, обеспечивая корректный автоподбор и форму выбора без избыточных данных.
  3. Добавление реквизита в метаданные объекта: оправдано только в том случае, если тип проекта действительно нужен для проведения документа или построения отчетов базы данных без соединения с таблицей проектов.
← На главную