Как реализовать автоматическое изменение одного измерения регистра сведений относительно другого

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

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

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

Способ 1. Использование события «ПриИзменении» на форме регистра

Этот метод является основным для интерактивной работы пользователя. Если пользователь меняет Измерение_1 в форме списка или форме записи, система должна мгновенно отреагировать и подставить значение в Измерение_2. Рассмотрим этот процесс по шагам.

Для начала нам необходимо создать обработчик события ПриИзменении для элемента формы, связанного с первым измерением. В управляемых формах работа ведется с текущей строкой таблицы (если это форма списка) или с реквизитом Запись (если это форма записи).

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


&НаКлиенте
Процедура СписокИзмерение1ПриИзменении(Элемент)
    
    // Получаем текущую строку, которую редактирует пользователь
    ТекущаяСтрока = Элементы.Список.ТекущиеДанные;
    
    Если ТекущаяСтрока = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Вызываем серверную функцию для получения зависимого значения
    // Например, если Измерение_1 — это Договор, а Измерение_2 — Контрагент
    Если ЗначениеЗаполнено(ТекущаяСтрока.Измерение_1) Тогда
        ТекущаяСтрока.Измерение_2 = ПолучитьНужноеЗначениеНаСервере(ТекущаяСтрока.Измерение_1);
    КонецЕсли;

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

&НаСервереБезКонтекста
Функция ПолучитьНужноеЗначениеНаСервере(ЗначениеИзмерения1)
    
    // Здесь описывается логика поиска. 
    // Если это справочник, можно просто обратиться к реквизиту.
    // Если логика сложнее — используем запрос.
    Возврат ЗначениеИзмерения1.Владелец; 

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

Важно проанализировать ситуацию: использование метода &НаСервереБезКонтекста позволяет ускорить работу формы, так как при вызове не передается вся форма целиком, а только необходимые параметры. Это критично для производительности, если регистр содержит большой объем данных.

Способ 2. Контроль в модуле набора записей (событие ПередЗаписью)

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

Чтобы гарантировать, что Измерение_2 всегда будет соответствовать Измерению_1, необходимо использовать модуль набора записей самого регистра. Проанализируем, как это сделать через событие ПередЗаписью.

  1. Откройте конфигуратор и найдите ваш Регистр Сведений.
  2. Перейдите на закладку «Прочее» и нажмите кнопку «Модуль набора записей».
  3. Создайте обработчик события ПередЗаписью.

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


Процедура ПередЗаписью(Отказ, Замещение)
    
    // В модуле набора записей "ЭтотОбъект" представляет собой коллекцию записей
    Для Каждого Запись Из ЭтотОбъект Цикл
        
        // Проверяем наличие основного измерения
        Если ЗначениеЗаполнено(Запись.Измерение_1) Тогда
            
            // Определяем правильное значение для второго измерения
            НужноеЗначение = Запись.Измерение_1.Владелец;
            
            // Проверяем, нужно ли перезаписывать (чтобы избежать лишних действий)
            Если Запись.Измерение_2 <> НужноеЗначение Тогда
                Запись.Измерение_2 = НужноеЗначение;
            КонецЕсли;
            
        КонецЕсли;
        
    КонецЦикла;
    
КонецПроцедуры

Использование этого метода обеспечивает абсолютную целостность данных. Даже если сторонний программист напишет обработку, которая просто создает записи в регистре, не заботясь о втором измерении, система сама подставит верные значения непосредственно перед сохранением в SQL-таблицу.

Способ 3. Связи параметров выбора (Metadata Level)

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

Если мы укажем, что Измерение_2 связано с Измерением_1, то при открытии формы выбора для второго поля система автоматически применит фильтр. В некоторых случаях (в зависимости от настроек платформы и типа данных), если под фильтр попадает ровно одно значение, платформа может подставить его автоматически.

Разберем, как это настроить:

Архитектурный аспект: Измерение или Реквизит?

Проанализируем ситуацию с точки зрения производительности. Если значение Измерения_2 всегда и во всех случаях однозначно вычисляется из Измерения_1, то мы имеем дело с избыточностью данных. В теории баз данных это называется нарушением нормальных форм.

Почему это может быть плохо:

  1. Увеличивается размер базы данных.
  2. Замедляются операции записи, так как индексы по измерениям требуют обновления.
  3. Сложнее вносить изменения (если логика связи изменится, придется пересчитывать весь регистр).

Рекомендация: если вам нужно Измерение_2 только для отображения в отчетах или простых фильтров, рассмотрите возможность сделать его Реквизитом регистра. Если же по этому полю планируются массовые высоконагруженные запросы с использованием «Среза последних», тогда оставляйте его Измерением, но обязательно индексируйте.

Подведем итог: наиболее надежным решением является сочетание события на форме (для удобства пользователя) и кода в модуле набора записей (для гарантии корректности данных). Такой подход сделает вашу конфигурацию надежной и профессиональной.

← На главную