Как автоматически заполнить реквизит-владелец при выборе значения в управляемой форме 1С

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

В процессе разработки на платформе 1С:Предприятие 8.3 часто возникает классическая задача: при выборе пользователем значения в одном поле (например, «Подразделение») необходимо автоматически заполнить другое поле, которое является его владельцем (например, «Организация»). Это не только ускоряет ввод данных, но и минимизирует количество ошибок, связанных с человеческим фактором.

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

Способ 1. Программное заполнение через обработчик события ПриИзменении

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

Для начала разберем типичную ошибку начинающих разработчиков. При обращении к реквизитам документа или справочника в модуле формы нельзя обращаться к ним напрямую по имени, как это делалось в обычных формах. Необходимо использовать префикс Объект.

Рассмотрим правильную реализацию задачи с использованием функций Библиотеки стандартных подсистем (БСП), что является промышленным стандартом разработки:


&НаКлиенте
Процедура Реквизит1ПриИзменении(Элемент)
    
    // Проверяем, что значение в поле было выбрано, а не очищено
    Если ЗначениеЗаполнено(Объект.Реквизит1) Тогда
        // Вызываем серверную функцию для получения владельца
        Объект.Реквизит2 = ПолучитьВладельцаНаСервере(Объект.Реквизит1);
    Иначе
        // Если поле очистили, решаем, нужно ли очищать владельца
        // Объект.Реквизит2 = ПредопределенноеЗначение("Справочник.Организации.ПустаяСсылка");
    КонецЕсли;
    
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьВладельцаНаСервере(СсылкаНаОбъект)
    // Используем типовую функцию БСП для эффективного получения реквизита
    Возврат ОбщегоНазначения.ЗначениеРеквизитаОбъекта(СсылкаНаОбъект, "Владелец");
КонецФункции

Почему мы используем &НаСервереБезКонтекста? Это критически важный момент для производительности. Директива &НаСервереБезКонтекста позволяет выполнить серверный вызов, не передавая на сервер всё состояние формы (данные всех реквизитов, элементов управления и прочее). Это значительно экономит трафик и ускоряет работу интерфейса, особенно в условиях медленного интернет-соединения.

Способ 2. Использование свойств пути к данным (без написания кода)

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

Выясним, как это работает по шагам:

  1. Выносим на форму поле надписи или поле ввода.
  2. В свойстве ПутьКДанным этого элемента указываем цепочку через точку: Объект.Реквизит1.Владелец.
  3. Платформа сама, без участия программиста, при выборе значения в Реквизит1 вытянет владельца из базы и отобразит его.

Однако помните, что такой способ подходит в основном для отображения. Если вам нужно, чтобы владелец стал частью данных документа и сохранился в базе, используйте Способ 1.

Оптимизация: получение нескольких реквизитов за один вызов

Часто вместе с владельцем нужно получить и другие данные (например, ИНН организации или код подразделения). Проанализируем ситуацию: делать несколько серверных вызовов для каждого реквизита — плохая практика. Вместо этого лучше использовать структуру.

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


&НаСервереБезКонтекста
Функция ПолучитьДанныеОбъекта(СсылкаНаПодразделение)
    
    // Формируем список нужных реквизитов через запятую
    НужныеРеквизиты = "Владелец, Код, Наименование";
    Результат = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(СсылкаНаПодразделение, НужныеРеквизиты);
    
    Возврат Результат; // Возвращается Структура
    
КонецФункции

&НаКлиенте
Процедура Реквизит1ПриИзменении(Элемент)
    
    Если Не Объект.Реквизит1.Пустая() Тогда
        СтруктураДанных = ПолучитьДанныеОбъекта(Объект.Реквизит1);
        
        // Заполняем реквизиты объекта из структуры
        Объект.Реквизит2 = СтруктураДанных.Владелец;
        // Можно заполнить и другие связанные поля
        // Объект.Комментарий = "Выбрано подразделение: " + СтруктураДанных.Наименование;
    КонецЕсли;
    
КонецПроцедуры

Нюансы работы со Связями параметров выбора

Важно не путать автозаполнение с ограничением выбора. Если вы хотите, чтобы при нажатии на кнопку выбора в поле «Подразделение» открывался список, уже отфильтрованный по «Организации», вам необходимо настроить свойство Связи параметров выбора (Choice Parameter Links) в метаданных или в свойствах элемента формы.

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

Обработка «битых» ссылок и пустых значений

При работе с программным заполнением всегда стоит учитывать сценарий, когда объект может быть удален или данные повреждены. При обращении к Объект.Реквизит1.Владелец через точку в серверном коде, если Реквизит1 пустой, вы не получите ошибку, но получите NULL или пустую ссылку.

Рассмотрим рекомендации по защите кода:

Заключение

Автозаполнение реквизитов — это стандарт гостеприимного интерфейса. Мы рассмотрели основной метод реализации через &НаСервереБезКонтекста и функции БСП, а также упрощенный метод через ПутьКДанным. Помните, что грамотное разделение кода на клиентскую и серверную части — залог быстродействия вашего приложения в управляемом интерфейсе.

← На главную