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