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