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

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

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

Анализ задачи: точки входа для обработки

Прежде всего, проанализируем ситуацию. Пользователь может взаимодействовать с деревом двумя основными способами:

  1. Нажатием на стандартную кнопку «Добавить» (командная панель таблицы).
  2. Выбором конкретного значения в уже существующей или только что созданной строке (редактирование ячейки).

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

Вариант 1: Использование события ПриИзменении в колонке

Если ваша основная цель — реагировать на выбор значения в конкретной ячейке (например, в колонке «Номенклатура» или «Объект»), то самым надежным способом будет использование события ПриИзменении. Обратите внимание, что это событие элемента формы, который находится внутри колонки, а не самой таблицы.

Рассмотрим по шагам, как реализовать этот механизм:

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

Посмотрим на пример кода, который реализует эту логику:


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

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

Вариант 2: Перехват события ОбработкаВыбора

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

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

Вариант 3: Работа со стандартной кнопкой «Добавить»

Если вы хотите, чтобы при нажатии на кнопку «Добавить» (плюсик в командной панели) происходила особая логика, рассмотрите событие таблицы ПередНачаломДобавления.

Важный момент: если вы установите параметр Отказ = Истина в этом событии, стандартное создание пустой строки будет отменено, и вы сможете программно добавить свою структуру строк, вызвав метод Добавить() у коллекции Элементы дерева.


&НаКлиенте
Процедура ДеревоПередНачаломДобавления(Элемент, Отказ, Копирование, Родитель, Группа)
    
    // Если мы хотим полностью заменить логику добавления:
    // Отказ = Истина;
    // ... здесь вызываем свою форму выбора или модальное окно ...
    
КонецПроцедуры

Вариант 4: Оптимизация через событие ПриРазворачивании (Lazy Loading)

Проанализируем ситуацию, когда дерево очень большое. Заполнять все группы сразу при выборе «родителя» может быть накладно для производительности системы. В 1С существует элегантное решение — ленивая загрузка.

Суть метода заключается в следующем:

  1. При выборе группы мы не загружаем её элементы сразу.
  2. Мы добавляем в дерево только саму группу и одну «фиктивную» пустую подстроку, чтобы у узла появился значок «плюс».
  3. Используем событие таблицы ПриРазворачивании. Оно срабатывает в тот момент, когда пользователь нажимает на «плюс».
  4. В этот момент мы проверяем, загружены ли реальные данные, и если нет — выполняем запрос к базе.

Пример использования ПриРазворачивании:


&НаКлиенте
Процедура ДеревоПриРазворачивании(Элемент, ИдентификаторСтроки, Отказ)
    
    Строка = Дерево.НайтиПоИдентификатору(ИдентификаторСтроки);
    
    // Проверяем, не загружали ли мы данные ранее
    Если Строка.ПолучитьЭлементы().Количество() = 1 
        И Строка.ПолучитьЭлементы()[0].Номенклатура = ПредопределенноеЗначение("Справочник.Номенклатура.ПустаяСсылка") Тогда
        
        // Вызываем сервер для реальной загрузки данных
        ЗагрузитьДанныеУзлаНаСервере(ИдентификаторСтроки);
        
    КонецЕсли;
    
КонецПроцедуры

Резюме и рекомендации

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

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

← На главную