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