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