Про "ОтборСтрок" я уже писал в недалеком прошлом поэтому не буду повторяться. Что это и для чего это используется можно изучить в статье Отборы (поиск) в табличной части либо таблице значений (управляемые формы)
Для демонстрации механизма я снова подготовил небольшую конфигурацию, которую можно скачать.
Конфигурация состоит из двух справочников: "Контрагенты" и "Товары" и одного документа "Поступление товаров". Данный документ имеет 2 соответствующие табличные части и предназначен для получения товаров от разных клиентов в одном документе.
Визуально форма выглядит так:
Мы хотим сделать так, чтобы клиенту было удобно и он выбирая клиента видел только те товары, которые приходят от него.
В качестве ключа связи мы будем использовать само значение контрагента. При этом можно в качестве ключа связи использовать произвольные ключи, уникальные в пределах документа или любые ссылочные элементы, например договора контрагентов — все зависит только от вашей необходимости.
Для нашей левой табличной части "Контрагенты" нам надо добавить следующие обработчики событий:
Нам надо при активизации строки показывать только товары, принадлежащие выбранному контрагенту (События "При активизации строки" и "При окончании редактирования") и так же отработать ситуацию удаления контрагента — нам надо удалить все товары со второй табличной части.
&НаКлиенте
Процедура КонтрагентыПриАктивизацииСтроки(Элемент)
ТекДанные = Элемент.ТекущиеДанные;
УстановитьОтборПоКлючу(ТекДанные,Элементы.Товары,НаименованиеКлючаСвязи);
КонецПроцедуры
&НаКлиенте
Процедура КонтрагентыПередУдалением(Элемент, Отказ)
ОбщаяПроцедураУдалитьСтроки(Элемент.ТекущиеДанные,Объект.Товары,НаименованиеКлючаСвязи);
КонецПроцедуры
&НаКлиенте
Процедура КонтрагентыПриОкончанииРедактирования(Элемент, НоваяСтрока, ОтменаРедактирования)
ТекДанные = Элемент.ТекущиеДанные;
ТекНаименованиеКлюча = НаименованиеКлючаСвязи;
Если ТекДанные[ТекНаименованиеКлюча] <> ТекДанные[ТекНаименованиеКлюча + "Начальный"] Тогда
ПерезаполнитьЗначениеКлюча(ТекДанные[ТекНаименованиеКлюча+"Начальный"],ТекДанные[ТекНаименованиеКлюча],"Товары",ТекНаименованиеКлюча);
ТекДанные[ТекНаименованиеКлюча + "Начальный"] = ТекДанные[ТекНаименованиеКлюча];
КонецЕсли;
УстановитьОтборПоКлючу(ТекДанные,Элементы.Товары,ТекНаименованиеКлюча);
КонецПроцедуры
Сами процедуры обработки:
&НаКлиенте
Процедура УстановитьОтборПоКлючу(ТекДанные,ТекЭлем,НаименованиеКлюча)
Если ТекДанные = Неопределено Тогда
Возврат;
КонецЕсли;
// Создаем структуру отбора
Отбор = Новый Структура;
Отбор.Вставить(НаименованиеКлюча, ТекДанные[НаименованиеКлюча]);
// Задаем фиксированную структуру отбора для таблицы формы
ТекЭлем.ОтборСтрок = Новый ФиксированнаяСтруктура(Отбор);
КонецПроцедуры
&НаКлиенте
Процедура ОбщаяПроцедураУдалитьСтроки(ТекДанные,ТекЭлем,НаименованиеКлюча)
Если ТекДанные <> Неопределено Тогда
МассивСтрок = ТекЭлем.НайтиСтроки(Новый Структура (НаименованиеКлюча,ТекДанные[НаименованиеКлюча]));
Для Каждого СтрМассива ИЗ МассивСтрок Цикл
ТекЭлем.Удалить(СтрМассива);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ПерезаполнитьЗначениеКлюча (ЗначениеКлючаНачальный,ЗначениеКлюча,НаименованиеТабЧасти,НаименованиеКлюча)
Если ЗначениеЗаполнено(ЗначениеКлючаНачальный) Тогда
ТекЭлем = Объект[НаименованиеТабЧасти];
МассивСтрок = ТекЭлем.НайтиСтроки(Новый Структура (НаименованиеКлюча,ЗначениеКлючаНачальный));
Для Каждого СтрМассива ИЗ МассивСтрок Цикл
СтрМассива[НаименованиеКлюча] = ЗначениеКлюча;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Для правой табличной части "Товары" нам также надо обработать несколько событий:
Мы должны отклонить выбор номенклатуры если у нас нет или не выбран контрагент и автоматически заполнять значение ключа связи — в нашем случае это ссылка на контрагента. Сами процедуры:
&НаКлиенте
Процедура ТоварыПередНачаломДобавления(Элемент, Отказ, Копирование, Родитель, Группа, Параметр)
Если Элементы.Контрагенты.ТекущиеДанные = Неопределено Тогда
Отказ = Истина;
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ТоварыПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование)
Если НоваяСтрока И НЕ Копирование Тогда
Элемент.ТекущиеДанные[НаименованиеКлючаСвязи] = Элементы.Контрагенты.ТекущиеДанные[НаименованиеКлючаСвязи];
КонецЕсли;
КонецПроцедуры
Ну и в основном для вопросов отладки нам надо посмотреть все товары всех клиентов, для этого добавляем команду по очистке отборов и размещаем ее в интерфейсе с ограничением по правам (если требуется). Процедура простейшая:
&НаКлиенте
Процедура ОчиститьОтбор(Команда)
СнятьОтборСЭлементов(Элементы.Товары);
КонецПроцедуры
UPD 1. 26.01.2024
Для того, чтобы учесть возможность смены самого контрагента, мы добавили в форме реквизит табличной части :
Сделали его заполнение при открытии формы и обрабатываем его изменение в коде:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
//Определим ключ связи
НаименованиеКлючаСвязи = "Контрагент";
ДозаполнитьТабЧасть();
КонецПроцедуры
&НаСервере
Процедура ПослеЗаписиНаСервере(ТекущийОбъект, ПараметрыЗаписи)
ДозаполнитьТабЧасть();
КонецПроцедуры
&НаСервере
Процедура ДозаполнитьТабЧасть ()
Для Каждого СтрТаб ИЗ Объект.Контрагенты Цикл
СтрТаб[НаименованиеКлючаСвязи+"Начальный"] = СтрТаб[НаименованиеКлючаСвязи];
КонецЦикла;
КонецПроцедуры
Для большей универсальности стал использовать реквизит формы "НаименованиеКлючаСвязи", который устанавливаю 1 раз и использую потом везде.
При этом хочу обратить ваше внимание вопрос повторности контрагентов остается открытым — т.е. при выборе слева одного контрагента 2 раза система не сможет различить номенклатуру по строкам. Вам либо надо контролировать, чтобы информация слева была уникальная и/или неизменной.
Для презентации того, как можно учесть и данный случай, я добавил в конфигурацию еще один документ "ПродажаТовара", в котором в качестве ключа связи испльзуется уникальный индекс — простое число, которое уникально для каждой строки слева и привязка идет непосредственно к нему:
Механизм реализации такой абсолютно такой же.
Изменили контрагента и имеем несвязанные строки номенклатуры, которые ни кто не увидит и которые так и будут «болтаться» вечно в документе.
(1) Да, согласен, не продумал. Исправил статью и конфигурацию и добавил возможность менять контрагента