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