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