Как в управляемой форме выводить разные реквизиты строки в одной колонке в зависимости от флажка?

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

При разработке интерфейсов на управляемых формах 1С часто возникает задача: в зависимости от признака в строке табличной части (например, флажка или переключателя) отображать и давать пользователю редактировать разные реквизиты объекта. Первое интуитивное решение, к которому прибегают разработчики, — объединить колонки в группу с типом ГруппировкаКолонок.ВЯчейке и наложить условное оформление. Однако в этом случае платформа ведет себя некорректно: ячейка может полностью потерять фокус или заблокироваться для ввода. Разберем, почему это происходит и как правильно решить поставленную задачу.

Почему не работает группировка колонок в ячейке

Проанализируем поведение платформы. При установке режима ГруппировкаКолонок.ВЯчейке система визуально склеивает несколько полей в одну графическую область. Если при этом на одно из полей накладывается условное оформление со свойством Отображать или Видимость, маршрутизация фокуса ввода и событий клика мыши нарушается. Свойство Отображать скрывает только отрисовку текста, но сам элемент управления остается в ячейке, перехватывая события клика. В результате пользователь видит пустую область, в которую невозможно нажать или ввести данные.

Решение 1. Использование двух независимых колонок и условного оформления видимости

Рассмотрим основной способ, предложенный в обсуждении. Откажемся от использования группы колонок в ячейке и выведем оба реквизита как самостоятельные столбцы таблицы формы.

Разберем реализацию по шагам:

  1. Удалим группу колонок из состава элементов таблицы формы. Поместим реквизиты напрямую в таблицу в виде двух отдельных колонок.
  2. Настроим условное оформление динамического списка или табличной части в свойствах формы. Создадим два правила:
    1. Правило 1: Условие: Флажок = Истина. Оформляемые поля: КолонкаРеквизит2. Оформление: свойство Видимость = Ложь.
    2. Правило 2: Условие: Флажок = Ложь. Оформляемые поля: КолонкаРеквизит1. Оформление: свойство Видимость = Ложь.
  3. Устраним скачки колонок по ширине при переходе между строками. Если оставить автоподбор, таблица будет непрерывно пересчитывать сетку при навигации курсора. Для обеих колонок установим одинаковые фиксированные настройки:
    1. Свойство РастягиватьПоГоризонтали = Ложь.
    2. Свойство Ширина = фиксированное число (например, 15) для обеих колонок.
    3. Свойство ИзменениеРазмера = НеИзменять.

Важно помнить об ограничении этого подхода: поскольку колонки остаются физически разделенными, возникает визуальный эффект небольшого смещения («шахматки»). Колонка 1 всегда будет находиться левее Колонки 2, из-за чего в одной строке заполненное поле будет отображаться чуть левее, чем в другой.

Решение 2. Вычисляемая колонка формы с обработкой ввода

Если визуальное смещение двух колонок недопустимо и требуется строго одна колонка без изменения метаданных конфигурации, применим паттерн вычисляемой колонки. Рассмотрим подробнее этот подход.

Разберем по шагам создание такой схемы:

  1. В реквизиты формы (внутрь табличной части объекта) добавим не реквизит базы данных, а реквизит формы с составным типом, объединяющим типы обоих целевых реквизитов, либо с типом Произвольный.
  2. Перетащим добавленный реквизит в элементы таблицы формы — получится одна колонка.
  3. При чтении данных документа (в обработчике ПриЧтенииСозданииНаСервере или ПослеЗагрузкиДанныхИзИнформационнойБазы) программно заполним это поле значением первого или второго реквизита согласно флагу.
  4. В событии ПриИзменении вычисляемой ячейки пропишем код сохранения значения в нужный реквизит строки:

&НаКлиенте
Процедура ТЧТоварыЗначениеВычисляемоеПриИзменении(Элемент)
    СтрокаТЧ = Элементы.ТЧТовары.ТекущиеДанные;
    Если СтрокаТЧ = Неопределено Тогда
        Возврат;
    КонецЕсли;

    Если СтрокаТЧ.Флажок Тогда
        СтрокаТЧ.Реквизит1 = СтрокаТЧ.ЗначениеВычисляемое;
        СтрокаТЧ.Реквизит2 = Неопределено;
    Иначе
        СтрокаТЧ.Реквизит2 = СтрокаТЧ.ЗначениеВычисляемое;
        СтрокаТЧ.Реквизит1 = Неопределено;
    КонецЕсли;
КонецПроцедуры

В событии ПриИзменении самого флажка реализуем переключение текущего отображаемого значения:


&НаКлиенте
Процедура ТЧТоварыФлажокПриИзменении(Элемент)
    СтрокаТЧ = Элементы.ТЧТовары.ТекущиеДанные;
    Если СтрокаТЧ = Неопределено Тогда
        Возврат;
    КонецЕсли;

    Если СтрокаТЧ.Флажок Тогда
        СтрокаТЧ.ЗначениеВычисляемое = СтрокаТЧ.Реквизит1;
    Иначе
        СтрокаТЧ.ЗначениеВычисляемое = СтрокаТЧ.Реквизит2;
    КонецЕсли;
КонецПроцедуры

Динамическое ограничение типа ввода

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

Чтобы избежать появления диалога выбора типа, используем ограничение типа на лету. В обработчике НачалоВыбора поля ввода или таблицы укажем платформе, какой тип ожидается для текущей строки:


&НаКлиенте
Процедура ТЧТоварыЗначениеВычисляемоеНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    СтрокаТЧ = Элементы.ТЧТовары.ТекущиеДанные;
    Если СтрокаТЧ = Неопределено Тогда
        Возврат;
    КонецЕсли;

    Если СтрокаТЧ.Флажок Тогда
        Элемент.ОграничениеТипа = Новый ОписаниеТипов("СправочникСсылка.Номенклатура");
    Иначе
        Элемент.ОграничениеТипа = Новый ОписаниеТипов("СправочникСсылка.Контрагенты");
    КонецЕсли;
КонецПроцедуры

Выясним причину эффективности этого способа: установка свойства ОграничениеТипа перед активацией выбора указывает платформе однозначный тип для строки. В результате стандартный диалог выбора типа пропускается, и пользователь сразу попадает в форму выбора нужного справочника или документа.

← На главную