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