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