Как в 1С автоматически подставить элемент второго справочника с таким же наименованием при выборе первого?

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

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

Анализируем ситуацию и частые ошибки

Начинающие разработчики часто пытаются напрямую присвоить наименование одного элемента другому или обратиться к несуществующим свойствам формы, получая ошибку «Поле объекта не обнаружено». Также попытка написать код вида Объект.Значение2 = Объект.Значение1.Значение2 не работает, так как реквизиты имеют ссылочный тип данных, а не являются текстовыми полями.

Для правильного выполнения этой операции необходимо:

  1. Отследить событие изменения первого реквизита на клиенте.
  2. Передать выбранную ссылку на сервер.
  3. Выполнить поиск соответствующего элемента во втором справочнике с помощью метода НайтиПоНаименованию().
  4. Записать полученную ссылку во второй реквизит объекта.

Пошаговое решение с примером кода

Разберем рабочий алгоритм. В форме документа для реквизита Реквизит1 создаем обработчик события ПриИзменении. Вся серверная работа выносится во внеконтекстную функцию &НаСервереБезКонтекста для обеспечения высокой производительности.

Рассмотрим готовый пример кода для модуля формы:


&НаКлиенте
Процедура Реквизит1ПриИзменении(Элемент)

    Если ЗначениеЗаполнено(Объект.Реквизит1) Тогда
        Объект.Реквизит2 = ЗаполнитьРеквизит2(Объект.Реквизит1);
    Иначе
        Объект.Реквизит2 = ПредопределенноеЗначение("Справочник.Справочник2.ПустаяСсылка");
    КонецЕсли;

КонецПроцедуры

&НаСервереБезКонтекста
Функция ЗаполнитьРеквизит2(Реквизит1)

    Возврат Справочники.Справочник2.НайтиПоНаименованию(Реквизит1.Наименование);

КонецФункции

Проанализируем, как работает данный код:

  1. На клиенте с помощью функции ЗначениеЗаполнено() мы проверяем, выбран ли элемент в первом поле. Если поле очищено, во второй реквизит записывается пустая ссылка.
  2. Если значение выбрано, вызывается серверная функция ЗаполнитьРеквизит2, куда передается ссылка Объект.Реквизит1.
  3. На сервере происходит обращение к реквизиту Наименование полученного элемента и выполняется поиск во втором справочнике через Справочники.Справочник2.НайтиПоНаименованию().
  4. Найденная ссылка возвращается на клиент и присваивается реквизиту Объект.Реквизит2.

Ограничения метода НайтиПоНаименованию и важные нюансы

При использовании метода НайтиПоНаименованию необходимо учитывать особенности работы платформы 1С:

1. Неполное соответствие строк: По умолчанию поиск может находить элементы по началу строки. Если во втором справочнике есть элементы «Товар 1» и «Товар 10», поиск по строке «Товар 1» без точного совпадения может вернуть не тот элемент. При необходимости точного поиска вторым параметром передают Истина: НайтиПоНаименованию(Наименование, Истина).

2. Дубликаты наименований: Если во втором справочнике есть несколько элементов с одинаковым названием, метод вернет только первый найденный элемент.

3. Помеченные на удаление элементы: Метод возвращает в том числе и помеченные на удаление элементы. Если их нужно исключать, лучше использовать запрос к базе данных с фильтром ПОМЕТКА_УДАЛЕНИЯ = ЛОЖЬ.

4. Оптимизация клиент-серверного взаимодействия: Не следует обращаться к свойству Объект.Реквизит1.Наименование непосредственно на клиенте. Это приводит к неявному вызову сервера. Передача самой ссылки в серверную функцию &НаСервереБезКонтекста является наиболее правильным подходом.

← На главную