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