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