Как программно добавить строку в табличную часть и установить на нее фокус?

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

При разработке в среде 1С:Предприятие 8.3 на управляемых формах программисты часто сталкиваются с ситуацией, когда стандартного добавления строки в табличную часть недостаточно. Задача кажется простой: добавить строку и сразу перевести на нее курсор, чтобы пользователь мог продолжить ввод без лишних кликов мышью. Однако на практике платформа может вести себя неочевидно: строка добавляется в «фоновом» режиме, а фокус остается на старом элементе или пропадает вовсе. Разберем подробно, почему так происходит и какие методы позволяют гарантированно активировать новую строку.

Проблема разделения данных и их отображения

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

Метод 1: Использование «ДобавитьСтроку()» элемента формы

Самый простой и правильный способ сымитировать интерактивное нажатие кнопки «Добавить» — это вызвать метод у самого элемента таблицы. Рассмотрим пример кода:


&НаКлиенте
Процедура ДобавитьИПерейти(Команда)
    // Мы обращаемся не к данным объекта, а к элементу формы
    Элементы.Товары.ДобавитьСтроку();
КонецПроцедуры

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

Метод 2: Программная установка текущей строки

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


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

Обратите внимание на метод ПолучитьИдентификатор(). Если вы попытаетесь присвоить свойству ТекущаяСтрока саму переменную НоваяСтрока, платформа может не отработать переход корректно, так как ей нужен уникальный внутренний индекс элемента в таблице формы.

Метод 3: Активация конкретной колонки и режима редактирования

Даже если строка стала текущей, курсор может просто подсветить ее, но не войти в режим ввода текста. Чтобы пользователь сразу мог начать печатать, нам нужно указать ТекущийЭлемент для всей формы и, при необходимости, вызвать метод ИзменитьСтроку(). Проанализируем расширенный пример:


&НаКлиенте
Процедура ДобавитьСАктивациейКолонки()
    НоваяСтрока = Объект.Товары.Добавить();
    Идентификатор = НоваяСтрока.ПолучитьИдентификатор();
    
    // Устанавливаем строку
    Элементы.Товары.ТекущаяСтрока = Идентификатор;
    
    // Переводим фокус на конкретное поле ввода (например, Номенклатура)
    Элементы.ТекущийЭлемент = Элементы.ТоварыНоменклатура;
    
    // Принудительно открываем ячейку для редактирования
    Элементы.Товары.ИзменитьСтроку();
КонецПроцедуры

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

Метод 4: Использование обработчика ожидания (решение для сложных случаев)

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

Решением является использование метода ПодключитьОбработчикОжидания(). Это позволяет выполнить код установки фокуса сразу после того, как платформа завершит свои текущие визуальные обновления. Рассмотрим, как это реализовать:


&НаКлиенте
Процедура ТоварыПриОкончанииРедактирования(Элемент, НоваяСтрока, ОтменаРедактирования)
    // Если это была новая строка и мы хотим добавить еще одну автоматически
    Если НоваяСтрока Тогда
        // Вызываем процедуру установки фокуса через 0.1 секунды
        ПодключитьОбработчикОжидания("УстановитьФокусНаНовуюСтроку", 0.1, Истина);
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура УстановитьФокусНаНовуюСтроку()
    // Теперь, когда платформа закончила обработку предыдущей строки, добавляем новую
    Элементы.Товары.ДобавитьСтроку();
КонецПроцедуры

Параметр Истина в методе ПодключитьОбработчикОжидания означает, что процедура выполнится всего один раз. Это самый надежный способ «победить» платформенные алгоритмы перехвата фокуса.

Важные настройки свойств колонок

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

  1. Пропускать при вводе: Если у колонки стоит это свойство, фокус на нее никогда не упадет при автоматическом переходе. Проверьте, чтобы для ключевых полей ввода стояло значение Нет (или флажок был снят).
  2. Только просмотр: Если таблица или колонка находятся в режиме «Только просмотр», метод ИзменитьСтроку() или ДобавитьСтроку() не сможет активировать режим редактирования.
  3. Видимость: Элемент, на который устанавливается ТекущийЭлемент, обязательно должен быть видимым на форме в данный момент.

Почему не стоит использовать WScript.Shell (SendKeys)

В некоторых старых советах можно встретить использование COM-объекта WScript.Shell для имитации нажатия клавиши Insert. Мы настоятельно не рекомендуем использовать этот метод по следующим причинам:

Подведем итог. Для качественной реализации добавления строки используйте сочетание ДобавитьСтроку() или ТекущаяСтрока вместе с ТекущийЭлемент. Если же платформа сопротивляется — используйте небольшую задержку через обработчик ожидания. Это сделает интерфейс вашего решения профессиональным и удобным для конечного пользователя.

← На главную