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