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