В процессе разработки на платформе 1С:Предприятие 8 (особенно при работе с обычными формами, не УФ) часто возникает задача программного управления интерфейсом. Типичный сценарий: вы заполнили таблицу значений данными, вывели её на форму в виде табличного поля и хотите облегчить жизнь пользователю — автоматически сфокусировать его внимание на определённой строке (например, только что добавленной или самой последней в списке). В этой статье мы подробно разберем, как правильно реализовать эту задачу, избежав популярных ошибок позиционирования.
Начинающие разработчики часто пытаются установить активную строку интуитивным путем — передавая числовой индекс строки в свойство табличного поля. Например, так:
// Ошибочный код, который вызовет ошибку выполнения!
ЭлементыФормы.ТЗ_1.ТекущаяСтрока = ТЗ_1.Количество() - 1;
При выполнении этого кода платформа выдаст ошибку, сообщающую о несовместимости типов или о том, что индекс не может быть указан напрямую. Давайте проанализируем ситуацию и выясним, почему так происходит.
Дело в том, что свойство ТекущаяСтрока объекта ТабличноеПоле ожидает получить не числовой индекс (номер по порядку), а саму строку таблицы данных как объект (тип значения СтрокаТаблицыЗначений). Число ТЗ_1.Количество() - 1 — это просто целочисленный индекс в коллекции, и платформа не может автоматически сопоставить его с объектом строки табличного поля.
Для того чтобы программно активировать строку, нам необходимо обратиться к источнику данных (в данном случае к таблице значений ТЗ_1), получить из неё конкретный объект строки по индексу и присвоить его свойству ТекущаяСтрока нашего табличного поля.
Рассмотрим безопасный шаблон кода, который сначала проверяет наличие записей в таблице (чтобы избежать критической ошибки при пустой таблице), а затем активирует последнюю строку:
// Проверяем, есть ли вообще строки в нашей таблице значений
Если ТЗ_1.Количество() > 0 Тогда
// Получаем объект строки по индексу последнего элемента и передаем его в ТекущаяСтрока
ЭлементыФормы.ТЗ_1.ТекущаяСтрока = ТЗ_1[ТЗ_1.Количество() - 1];
КонецЕсли;
В этом примере конструкция ТЗ_1[ТЗ_1.Количество() - 1] возвращает непосредственно объект типа СтрокаТаблицыЗначений. Платформа сопоставляет эту строку с визуальным отображением в элементе управления и мгновенно выделяет её на форме.
При работе с табличными полями крайне важно не путать два созвучных свойства элемента формы. Давайте разберем их принципиальное различие:
ТекущаяСтрока — это свойство доступно как для чтения, так и для записи. Оно хранит идентификатор строки (в случае ТЗ — саму строку). Именно его мы используем для того, чтобы программно выделить нужную позицию на экране.ТекущиеДанные — это свойство доступно только для чтения. Оно возвращает объект, содержащий данные текущей (активной в данный момент) строки. Попытка записать туда значение напрямую (например, ЭлементыФормы.ТЗ_1.ТекущиеДанные = ...) приведет к ошибке компиляции или выполнения. Данное свойство незаменимо, когда нам нужно прочитать информацию из выделенной пользователем строки:
// Пример безопасного получения данных из текущей строки
ТекущаяСтрокаДанных = ЭлементыФормы.ТЗ_1.ТекущиеДанные;
Если ТекущаяСтрокаДанных <> Неопределено Тогда
ВыбранныйТовар = ТекущаяСтрокаДанных.Номенклатура;
КонецЕсли;
Описанный выше классический метод активации строки по индексу отлично работает в "чистых" таблицах. Однако на практике разработчики часто сталкиваются со следующими проблемами:
ТЗ_1.Количество() - 1 активирует строку, которая в памяти является последней, но на экране она визуально переместится.Для обхода этих ограничений при сложной логике отображения рекомендуется обращаться к строкам не напрямую через исходную таблицу значений, а анализировать структуру построителя или оформление строк, если это критично для бизнес-логики.
Поведение свойства ТекущаяСтрока напрямую зависит от того, какой объект назначен источником данных (свойство Данные) для вашего табличного поля:
1. Динамические списки (СправочникСписок, ДокументСписок и др.)
Если ваше табличное поле отображает список документов или справочников из базы данных, у него нет индексов. В этом случае свойству ТекущаяСтрока нужно передавать конкретную ссылку на объект базы данных:
// Активируем конкретный документ в списке на форме
ЭлементыФормы.СписокДокументов.ТекущаяСтрока = НайденнаяСсылкаНаДокумент;
2. Дерево значений (ДеревоЗначений)
Для дерева значений свойству ТекущаяСтрока нужно передавать объект типа СтрокаДереваЗначений. Получить его можно, например, обратившись к строкам первого уровня или подчиненным веткам:
// Активируем первую строку первого уровня дерева значений
Если ДеревоДанных.Строки.Количество() > 0 Тогда
ЭлементыФормы.ДеревоНаФорме.ТекущаяСтрока = ДеревоДанных.Строки[0];
КонецЕсли;
Часто просто выделить строку цветом недостаточно — пользователю всё равно приходится брать в руки мышь, чтобы кликнуть по таблице и начать вводить данные. Мы можем сделать форму максимально отзывчивой, программно передав фокус ввода на само табличное поле и активировав конкретную ячейку.
Для этого выполним комплексную настройку активности:
Если Заказы.Количество() > 0 Тогда
// 1. Делаем активной саму строку
ЭлементыФормы.Заказы.ТекущаяСтрока = Заказы[Заказы.Количество() - 1];
// 2. Указываем, какую колонку сделать активной (например, "Количество")
ЭлементыФормы.Заказы.ТекущаяКолонка = ЭлементыФормы.Заказы.Колонки.Количество;
// 3. Передаем фокус ввода на элемент управления "ТабличноеПоле"
ЭтаФорма.ТекущийЭлемент = ЭлементыФормы.Заказы;
КонецЕсли;
После выполнения этой последовательности команд строка не просто выделится цветом — на нужной колонке сразу появится мигающий курсор (активная ячейка перейдет в режим редактирования), и пользователь сможет продолжить работу с клавиатуры без лишних кликов мышью.
В обычных формах у табличного поля есть замечательное свойство ВыделенныеСтроки. Если в свойствах элемента управления на форме включен флаг "Множественный выбор", мы можем программно выделить целую группу строк:
// Очищаем предыдущее выделение
ЭлементыФормы.ТЗ_1.ВыделенныеСтроки.Очистить();
// Добавляем нужные строки в коллекцию выделения
ЭлементыФормы.ТЗ_1.ВыделенныеСтроки.Добавить(ТЗ_1[0]);
ЭлементыФормы.ТЗ_1.ВыделенныеСтроки.Добавить(ТЗ_1[2]);
Поскольку мы рассматриваем контекст обычных форм ("не уф"), крайне полезно знать, как этот механизм изменился в современных управляемых формах 1С 8.3. Это убережет вас от ошибок при конвертации кода или разработке новых решений.
В управляемых формах свойство ТекущаяСтрока элемента формы работает совершенно иначе:
СтрокаТаблицыЗначений), а её уникальный числовой идентификатор.ПолучитьИдентификатор() у строки данных:
// Код для Управляемых Форм (Выполняется на Клиенте)
ИндексПоследней = Объект.ТЗ_1.Количество() - 1;
Если ИндексПоследней >= 0 Тогда
// Получаем строку данных
СтрокаДанных = Объект.ТЗ_1[ИндексПоследней];
// Присваиваем идентификатор строки свойству ТекущаяСтрока элемента формы
Элементы.ТЗ_1.ТекущаяСтрока = СтрокаДанных.ПолучитьИдентификатор();
КонецЕсли;
Понимание этой разницы между парадигмами обычных и управляемых форм является ключевым признаком профессионального разработчика 1С, позволяя безболезненно поддерживать как устаревшие конфигурации, так и современные прикладные решения.