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

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

При работе с обычными формами в 1С разработчики часто сталкиваются с задачей получения данных из строки, которую только что выделил пользователь. Классический сценарий — обработка события ПриАктивизацииСтроки у элемента ТабличноеПоле. Интуитивно кажется, что для этого нужно использовать свойство ТекущиеДанные, но на практике оно может вернуть Неопределено, что ставит в тупик. Разберемся, почему так происходит и как надежно получить нужную информацию.

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

Почему `ТекущиеДанные` бывает `Неопределено`? Разбираемся в механизме событий

Основная причина проблемы кроется в последовательности выполнения событий в платформе 1С. Событие ПриАктивизацииСтроки для элемента формы ТабличноеПоле срабатывает в самый первый момент, когда фокус перемещается на новую строку. В этот момент платформа еще не всегда успевает полностью обновить все связанные с этим действием свойства, включая структуру ТекущиеДанные.

Чтобы понять, как действовать, необходимо четко различать два ключевых свойства табличного поля:

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

Таким образом, ТекущиеДанные — это про "что мы видим", а ТекущаяСтрока — это про "что мы выбрали в источнике". И в момент события ПриАктивизацииСтроки идентификатор уже известен, а вот структура с видимыми данными еще может быть не сформирована.

Ключевое различие: `ТекущиеДанные` vs. `ТекущаяСтрока`

Рассмотрим эти два свойства подробнее, чтобы закрепить понимание.

Свойство ЭлементыФормы.МояТаблица.ТекущиеДанные

Свойство ЭлементыФормы.МояТаблица.ТекущаяСтрока

Практические решения: как получить данные строки

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

Решение 1: Надежный способ через `ТекущуюСтроку` и источник данных

Это самый правильный и рекомендуемый метод, который будет работать стабильно во всех ситуациях. Алгоритм действий прост:

  1. В обработчике события ПриАктивизацииСтроки получить идентификатор строки из свойства ТекущаяСтрока.
  2. Используя этот идентификатор, найти соответствующую строку непосредственно в источнике данных (например, в реквизите формы типа ТаблицаЗначений).
  3. Работать с найденной строкой, получая из нее любые данные, даже из скрытых колонок.

Посмотрим на пример для источника данных ТаблицаЗначений.

Предположим, у нас есть форма с реквизитом СписокТоваров (тип ТаблицаЗначений) и элементом формы Товары (тип ТабличноеПоле), который связан с этим реквизитом.


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

Этот метод имеет ключевые преимущества:

Решение 2: Работа с источником данных `ДинамическийСписок`

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

Посмотрим на пример, где табличное поле СписокДокументов отображает журнал реализаций.


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

Здесь важно понимать, что работа с ДинамическимСписком уже подразумевает работу со ссылками, и свойство ТекущаяСтрока идеально вписывается в эту концепцию.

Решение 3 (Ситуативное): Прямой доступ через `ТекущиеДанные`

Несмотря на ненадежность в событии ПриАктивизацииСтроки, свойство ТекущиеДанные очень удобно и прекрасно работает в других сценариях, например, в обработчиках команд кнопок или при двойном клике (Выбор), когда контекст формы уже полностью установлен.

Пример использования в команде:


Процедура ПоказатьИнформациюОТоваре(Кнопка)
    
    // В обработчике команды кнопки ТекущиеДанные уже гарантированно заполнены
    ДанныеСтроки = ЭлементыФормы.Товары.ТекущиеДанные;
    
    Если ДанныеСтроки <> Неопределено Тогда
        Сообщить("Информация по товару: " + ДанныеСтроки.Номенклатура);
    Иначе
        Сообщить("Сначала выберите строку в таблице!");
    КонецЕсли;
    
КонецПроцедуры

Этот способ проще и короче, но его следует применять только тогда, когда вы уверены, что событие происходит не в момент смены строки, а после.

Распространенная ошибка: `ТекущаяСтрока` — это не индекс!

Важно раз и навсегда запомнить: свойство ТекущаяСтрока не является индексом строки (порядковым номером) в таблице. Это уникальный внутренний идентификатор, который присваивается строке при ее добавлении в ТаблицуЗначений. Он не меняется при сортировке, фильтрации или удалении других строк.

Попытка использовать его как индекс приведет к ошибкам:


// НЕПРАВИЛЬНО! Этот код может работать случайно, но сломается при первой же сортировке!
НеправильнаяСтрока = СписокТоваров[ЭлементыФормы.Товары.ТекущаяСтрока - 1]; 

Всегда используйте метод НайтиПоИдентификатору() для поиска строки в ТаблицеЗначений.

Выводы и рекомендации

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

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

← На главную