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

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

При разработке в среде 1С (особенно на обычных формах в толстом клиенте) часто возникает задача программного заполнения документов. Трудности начинаются тогда, когда логика заполнения и расчета данных завязана на событиях формы, таких как ПриИзменении. Эти процедуры-обработчики часто требуют передачи в качестве параметра конкретного объекта — ЭлементУправления. Рассмотрим подробнее, как получить этот объект программно, если мы сами создаем строку в табличной части.

Проблема: Элемент управления не определен

Когда мы программно открываем форму и добавляем строку в объект документа, платформа не всегда автоматически «фокусирует» визуальные элементы на этой строке. Если просто вызвать метод Добавить() для табличной части документа, свойство формы ТекущийЭлемент может продолжать указывать на само табличное поле, а не на конкретную ячейку. В результате попытка передать ТекущийЭлемент в процедуру приводит к ошибке или некорректной работе кода, так как процедура ожидает поле ввода конкретной колонки.

Решение 1: Эмуляция интерактивного выбора строки

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

  1. Получаем форму документа и открываем её (это важно для инициализации элементов управления).
  2. Добавляем строку в данные (табличную часть).
  3. Устанавливаем свойство ТекущаяСтрока у элемента формы (табличного поля).
  4. Обращаемся к элементу управления через текущую колонку.

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


// 1. Получаем и открываем форму
Форма = ПолучитьФорму("Документ.СведенияОЗастрахованныхЛицахСЗВ_М.ФормаОбъекта");
Форма.Открыть();

// 2. Добавляем новую строку в табличную часть "РаботникиОрганизации"
НоваяСтрока = Форма.Объект.РаботникиОрганизации.Добавить();
НоваяСтрока.ФизЛицо = Сотрудник.Физлицо;

// 3. Синхронизируем визуальное состояние: устанавливаем текущую строку в табличном поле
Форма.ЭлементыФормы.РаботникиОрганизации.ТекущаяСтрока = НоваяСтрока;

// 4. Теперь мы можем получить элемент управления нужной колонки и вызвать обработчик
// Предположим, процедура ПриИзменении ожидает элемент управления колонки "ФизЛицо"
ЭлементФизЛицо = Форма.ЭлементыФормы.РаботникиОрганизации.Колонки.ФизЛицо.ЭлементУправления;

// Важно: если процедура считывает значение из элемента, нужно его обновить
ЭлементФизЛицо.Значение = НоваяСтрока.ФизЛицо;

// 5. Вызываем процедуру формы, передавая в неё полученный элемент управления
Форма.РаботникиОрганизацииФизЛицоПриИзменении(ЭлементФизЛицо);

Решение 2: Безопасное обращение через коллекцию колонок

Использование ТекущийЭлемент.ТекущаяКолонка не всегда надежно, так как активная колонка может измениться в процессе выполнения кода или зависеть от настроек пользователя. Безопаснее обращаться к элементу управления конкретной колонки напрямую через коллекцию Колонки табличного поля.

Выясним причину, почему это работает лучше. В обычных формах ЭлементУправления колонки табличного поля является общим для всех строк этой колонки. Когда вы устанавливаете ТекущаяСтрока, этот общий элемент управления «связывается» с данными именно этой строки. Поэтому, обратившись к ЭлементыФормы.ИмяТаблицы.Колонки.ИмяКолонки.ЭлементУправления, вы получите объект, который процедура формы сможет корректно обработать.

Важные нюансы:

Альтернативный подход: вынос логики из формы

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

Если процедура ПриИзменении выполняет важные расчеты, правильнее будет вынести этот код в экспортную процедуру Модуля объекта или Общего модуля. В этом случае вы сможете передавать туда просто строку табличной части (объект данных), не заботясь о наличии формы и её контролов:


// В модуле объекта документа
Процедура РассчитатьДанныеСтроки(СтрокаТЧ) Экспорт
    // Здесь логика, которая раньше была в форме
    СтрокаТЧ.Результат = СтрокаТЧ.Цена * СтрокаТЧ.Количество;
КонецПроцедуры

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

← На главную