Как в 1С реализовать автоматическое заполнение одного реквизита на основании другого?

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

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

Вариант 1. Программное заполнение через событие формы «ПриИзменении»

Разберем самый быстрый способ, который часто применяют начинающие разработчики. Нам необходимо создать обработчик события, который будет срабатывать в тот момент, когда пользователь выбирает значение в поле Производитель.

Проанализируем шаги реализации:

  1. Откроем форму справочника Товары в конфигураторе.
  2. Выберем на форме элемент Производитель и в палитре свойств найдем событие ПриИзменении.
  3. Нажмем на лупу, чтобы система создала заготовку процедуры.

Рассмотрим пример кода, который позволит нам подставить страну:


&НаКлиенте
Процедура ПроизводительПриИзменении(Элемент)
    ПроизводительПриИзмененииНаСервере();
КонецПроцедуры

&НаСервере
Процедура ПроизводительПриИзмененииНаСервере()
    // Простая проверка по наименованию (не рекомендуется для крупных систем)
    Если СокрЛП(Объект.Производитель.Наименование) = "Hartmann" Тогда
        Объект.Страна = "Германия";
    КонецЕсли;
КонецПроцедуры

Важное замечание: Этот метод имеет существенный недостаток. Если завтра производитель сменит название в справочнике (например, на «Paul Hartmann»), программный код перестанет работать. Программисту придется вручную лезть в конфигуратор и исправлять текст. Посмотрим, как сделать это более профессионально.

Вариант 2. Нормализация данных и использование реквизитов справочника

Выясним, как избежать «жесткого» кодирования названий. Самый правильный путь — хранить информацию о стране непосредственно в справочнике Производители. Это называется нормализацией базы данных.

Добавим в справочник Производители новый реквизит СтранаПроисхождения. Теперь нам не нужно писать условия Если...Тогда. Мы просто будем «вытягивать» данные из выбранного объекта.

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


&НаСервере
Процедура ПроизводительПриИзмененииНаСервере()
    Если ЗначениеЗаполнено(Объект.Производитель) Тогда
        // Просто копируем значение из связанного справочника
        Объект.Страна = Объект.Производитель.СтранаПроисхождения;
    КонецЕсли;
КонецПроцедуры

Такой подход универсален: он будет работать для любого производителя — российского, китайского или немецкого — без изменения программного кода. Пользователь сам сможет менять страны в справочнике Производители в режиме «1С:Предприятие».

Вариант 3. Использование Регистров сведений для сложных связей

Бывают ситуации, когда связь «Производитель — Страна» не является жесткой. Например, один и тот же бренд может производить разные группы товаров в разных странах. В этом случае нам поможет объект РегистрСведений.

Создадим регистр СоответствиеПроизводителейИСтранам с измерениями Производитель и ресурсом Страна. Это позволит хранить настройки соответствий отдельно от самих справочников.

Разберем, как получить данные из регистра:


&НаСервере
Процедура ПроизводительПриИзмененииНаСервере()
    Если ЗначениеЗаполнено(Объект.Производитель) Тогда
        // Ищем актуальное значение в регистре сведений
        Запрос = Новый Запрос;
        Запрос.Текст = 
            "ВЫБРАТЬ
            |   СоответствиеПроизводителейИСтранам.Страна КАК Страна
            |ИЗ
            |   РегистрСведений.СоответствиеПроизводителейИСтранам КАК СоответствиеПроизводителейИСтранам
            |ГДЕ
            |   СоответствиеПроизводителейИСтранам.Производитель = &Производитель";
        
        Запрос.УстановитьПараметр("Производитель", Объект.Производитель);
        РезультатЗапроса = Запрос.Выполнить();
        
        Если Не РезультатЗапроса.Пустой() Тогда
            Выборка = РезультатЗапроса.Выбрать();
            Выборка.Следующий();
            Объект.Страна = Выборка.Страна;
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Этот метод считается наиболее гибким и масштабируемым в крупных корпоративных системах.

Вариант 4. Работа с предопределенными элементами

Если логика вашей программы всё же требует привязки к конкретному системному значению (например, «Hartmann» — это ваш главный партнер, по которому идет особая отчетность), используйте предопределенные элементы.

В конфигураторе создайте у справочника Производители предопределенный элемент с именем Хартманн. Теперь код будет выглядеть так:


Если Объект.Производитель = Справочники.Производители.Хартманн Тогда
    Объект.Страна = Справочники.СтраныМира.Германия;
КонецЕсли;

Преимущество в том, что даже если пользователь переименует «Hartmann» в «Хартманн ООО», внутренний идентификатор (UUID) останется прежним, и программа продолжит работать корректно.

Дополнительные рекомендации по разработке

Рассмотрим несколько важных нюансов, которые отличают профессиональный код от любительского:

  1. Подписки на события: Если вы хотите, чтобы заполнение страны происходило не только в форме, но и при загрузке данных из Excel или через API, размещайте логику в модуле объекта (событие ПередЗаписью) или используйте Подписку на событие.
  2. Проверка на заполненность: Перед перезаписью реквизита Страна проверьте, не заполнил ли его пользователь вручную. Иногда стоит добавить вопрос: «Перезаполнить страну на основании производителя?», чтобы не затереть специфические данные.
  3. Групповая обработка: Помните, что код в форме работает только для новых или открытых объектов. Если в вашей базе уже есть тысячи товаров, вам потребуется написать небольшую обработку, которая один раз пройдет по всем записям и заполнит пустые поля Страна.

Таким образом, мы проанализировали путь от простого условия к надежной архитектуре. Главное правило: старайтесь избегать строковых названий в коде и всегда ищите возможность вынести настройки в данные (реквизиты справочников или регистры).

← На главную