Как программно установить курсор в нужную ячейку табличной части на обычной форме 1С?

Программист 1С v8.3 (Обычные формы)
← На главную

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

Рассмотрим типичную ситуацию: перед записью документа необходимо проверить, что в каждой строке табличной части "Состав" заполнено поле "Сделка". Если поле пусто, запись нужно отменить, а курсор — переместить в эту пустую ячейку.

Анализ неверного подхода и его причин

Начинающий разработчик может попытаться решить задачу следующим образом:


// Неправильный код!
Для каждого Строка Из Состав Цикл
    Если ЗначениеНеЗаполнено(Строка.Сделка) Тогда
        Отказ = Истина;
        Сообщить("Не заполнено поле 'Сделка'!");
        
        ЭтаФорма.ЭлементыФормы.Состав.ТекущаяСтрока = Строка;
        // Попытка установить колонку, которая приводит к ошибке или неверному поведению
        ЭтаФорма.ЭлементыФормы.Состав.ТекущаяКолонка = Строка.Сделка;
        
        Прервать;
    КонецЕсли;
КонецЦикла;

В этом коде строка ЭтаФорма.ЭлементыФормы.Состав.ТекущаяСтрока = Строка; отработает корректно и выделит нужную строку. Однако попытка присвоить свойству ТекущаяКолонка значение из самой ячейки (Строка.Сделка) обречена на провал. Почему?

Проблема кроется в несоответствии типов. Свойство ТекущаяКолонка ожидает получить объект типа КолонкаТабличногоПоля, а не данные, которые хранятся в ячейке. В нашем случае Строка.Сделка содержит либо ссылку на документ, либо значение Неопределено, если поле не заполнено. Присвоение Неопределено, согласно документации, просто сбрасывает активную колонку, из-за чего курсор "исчезает". Попытка присвоить тип значения (например, Тип("ДокументСсылка.РеализацияТоваров")) также вызовет ошибку, так как тип данных — это не объект колонки.

Правильное решение: прямое указание объекта колонки

Чтобы корректно установить курсор, нужно обратиться к коллекции колонок табличного поля и выбрать нужную по имени. Давайте исправим наш предыдущий код.

Посмотрим на правильный синтаксис:

  1. Устанавливаем текущую строку, присваивая свойству ТекущаяСтрока объект нужной строки табличной части.
  2. Устанавливаем текущую колонку. Для этого обращаемся к коллекции колонок элемента формы (ЭлементыФормы.Состав.Колонки) и по имени (Сделка) получаем нужный объект колонки. Этот объект и присваиваем свойству ТекущаяКолонка.

Вот как выглядит итоговый рабочий код:


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

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

Важный момент: все манипуляции с элементами формы (ЭлементыФормы) должны выполняться в клиентском контексте. Процедура ПередЗаписью() на обычной форме выполняется на клиенте, поэтому данный код будет работать корректно.

Альтернативный и более современный подход: использование СообщениеПользователю

Хотя прямое позиционирование курсора работает отлично, в платформе 1С существует более гибкий и удобный для пользователя механизм информирования об ошибках — объект СообщениеПользователю. Он позволяет не только вывести текст, но и привязать его к конкретному полю данных.

Преимущества этого подхода:

Разберем, как его использовать. Для этого нужно указать путь к данным в свойстве Поле. Путь формируется по шаблону: "ИмяТабличнойЧасти[ИндексСтроки].ИмяКолонки". Важно помнить, что индексация строк начинается с нуля.

Посмотрим на пример:


// Процедура выполняется на клиенте, например, ПередЗаписью()
Процедура ПередЗаписью(Отказ)
    
    ПроверкаВыполнена = Истина;
    
    // Используем цикл со счетчиком для получения индекса строки
    Для сч = 0 По ЭтотОбъект.Состав.Количество() - 1 Цикл
        
        СтрокаТЧ = ЭтотОбъект.Состав[сч];
        
        Если ЗначениеНеЗаполнено(СтрокаТЧ.Сделка) Тогда
            
            // Создаем и настраиваем сообщение
            Сообщение = Новый СообщениеПользователю();
            Сообщение.Текст = "В строке " + (сч + 1) + " не заполнено поле 'Сделка'!";
            
            // Указываем путь к данным. Индекс строки - сч.
            Сообщение.Поле = "Состав[" + сч + "].Сделка";
            
            // Привязываем сообщение к данным формы
            Сообщение.УстановитьДанные(ЭтотОбъект);
            
            // Выводим сообщение пользователю
            Сообщение.Сообщить();
            
            ПроверкаВыполнена = Ложь;
        КонецЕсли;
        
    КонецЦикла;
    
    Если Не ПроверкаВыполнена Тогда
        Отказ = Истина;
    КонецЕсли;
    
КонецПроцедуры

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

← На главную