Как получить данные строки таблицы в событии ПриИзменении, если ТекущиеДанные возвращает Неопределено?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей IT и автоматизация бизнеса
← К списку

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

Выясним причину: почему ТекущиеДанные становятся Неопределено?

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

Основная причина кроется в контексте выполнения события. Когда срабатывает событие ПриИзменении для колонки таблицы, фокус ввода находится не на строке в целом, а внутри конкретной ячейки — элемента управления (поля ввода, флажка и т.д.). В этот самый момент платформа может считать, что у таблицы как таковой нет активной строки, поскольку вся "активность" сосредоточена внутри ее элемента.

Рассмотрим самый яркий пример, который и стал причиной обсуждения на форуме:

  1. На форме есть таблица, для которой установлен динамический отбор. Например, отображаются только строки, у которых установлен некий флажок.
  2. Пользователь снимает этот флажок в одной из строк.
  3. Срабатывает событие ПриИзменении для колонки с флажком.
  4. Платформа немедленно пересчитывает динамический отбор. Строка, в которой сняли флажок, перестает удовлетворять условию отбора и моментально исчезает из видимой части таблицы.
  5. Поскольку строка исчезла, у таблицы больше нет текущей строки. Соответственно, обращение к Элементы.МояТаблица.ТекущиеДанные совершенно справедливо возвращает Неопределено.

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

Решение 1: Получение данных через идентификатор строки (рекомендуемый способ)

Это самый надежный и правильный способ получить данные строки в событии ПриИзменении. Даже если ТекущиеДанные становятся Неопределено, платформа все еще "помнит" идентификатор строки, в которой произошло изменение.

Разберем по шагам, как это работает:

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

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

Посмотрим на практический пример. Допустим, у нас есть табличная часть на форме с именем МояТаблица, которая связана с реквизитом формы Объект.МояТаблица. В таблице есть колонка МойФлажок.

Создадим для поля МойФлажок обработчик события ПриИзменении:


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

Важный момент: мы обращаемся к Объект.МояТаблица, то есть к данным объекта, а не к элементам формы. Именно там хранятся все строки, независимо от того, видимы они на форме в данный момент или нет.

Решение 2: Использование другого события

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

В этом событии строка еще гарантированно видима, и свойство ТекущиеДанные будет заполнено. Однако у этого подхода есть серьезный недостаток: событие происходит до того, как пользователь изменил значение. Это значит, что вы получите доступ к старым данным, а не к новым.

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

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

← К списку