Как программно выделить несколько ячеек в табличной части или таблице значений в 1С?

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

Разработчики при создании интерактивных интерфейсов в управляемых формах «1С:Предприятие 8» часто сталкиваются с задачей выделения нескольких ячеек в табличной части или таблице значений. Например, это может потребоваться для подсчета суммы выделенных показателей, визуального сопоставления данных или реализации нестандартной логики работы (вплоть до интерактивных игр вроде тетриса или планировщиков).

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

Анализ ограничений платформы «1С:Предприятие 8»

Давайте разберем, как устроена работа с выделением в стандартном элементе формы типа Таблица (связанном с табличной частью или таблицей значений). На уровне платформы у этого элемента существуют лишь два инструмента для управления фокусом и выделением:

  1. Свойство ТекущийЭлемент (или ТекущаяКолонка) — отвечает за фокус на одной конкретной ячейке. Платформа физически не позволяет передать в это свойство массив колонок или ячеек. Попытка присвоить туда массив вызовет ошибку выполнения.
  2. Свойство ВыделенныеСтроки — представляет собой массив идентификаторов строк. Этот механизм позволяет выделить несколько строк целиком (например, при зажатой клавише Ctrl), но он абсолютно не умеет работать с отдельными ячейками или колонками внутри этих строк.

Таким образом, выделить произвольную область ячеек в стандартной таблице программно или интерактивно (мыкой с Ctrl) штатными методами невозможно. Но не спешите расстраиваться. Давайте рассмотрим пошагово рабочие обходные пути, которые успешно решают эту задачу.

Решение №1: Имитация выделения через «Условное оформление» (Рекомендуемый способ)

Если ваша главная цель — визуально подсветить ячейки для пользователя (чтобы они выглядели как выделенные), отличным решением станет использование механизма Условного оформления управляемой формы. Вместо реального выделения мы будем динамически изменять цвет фона нужных ячеек, имитируя системное выделение.

Рассмотрим по шагам процесс реализации данного метода:

Шаг 1. Добавление служебных колонок в структуру данных.

Для того чтобы система знала, какие именно ячейки в данный момент «выделены», нам понадобятся служебные булевы колонки. Например, если у нас есть колонка Сумма, которую пользователь должен уметь выделять, мы добавим в нашу таблицу значений скрытую колонку Сумма_Выделена с типом данных Булево. Для пользователя эта колонка будет невидима.

Шаг 2. Обработка клика по ячейке.

Свяжем событие таблицы ПриАктивизацииЯчейки с обработчиком на клиенте. В этом обработчике мы будем переключать состояние нашей булевой колонки при клике на ячейку.


&НаКлиенте
Процедура ТаблицаПриАктивизацииЯчейки(Элемент)
    
    ТекущиеДанные = Элементы.Таблица.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Определяем имя колонки, на которую кликнул пользователь
    ИмяТекущейКолонки = Элементы.Таблица.ТекущийЭлемент.Имя;
    
    // Если кликнули по целевой колонке "Сумма"
    Если ИмяТекущейКолонки = "Сумма" Тогда
        // Инвертируем состояние "выделения" в служебной колонке
        ТекущиеДанные.Сумма_Выделена = Не ТекущиеДанные.Сумма_Выделена;
    КонецЕсли;
    
КонецПроцедуры

Шаг 3. Программная настройка Условного оформления.

Теперь нам нужно заставить платформу автоматически перекрашивать ячейку, у которой служебный флаг установлен в значение Истина. Настроим условное оформление формы на сервере, например, при создании формы.


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    НастроитьВизуальноеВыделениеЯчеек();
    
КонецПроцедуры

&НаСервере
Процедура НастроитьВизуальноеВыделениеЯчеек()
    
    // Создаем новый элемент условного оформления
    ЭлементОформления = УсловноеОформление.Элементы.Добавить();
    
    // 1. Задаем оформление: цвет фона, имитирующий выделение
    ЭлементОформления.Оформление.УстановитьЗначениеПараметра("ЦветФона", ЦветаСтиля.ВыделениеЦвет);
    
    // 2. Устанавливаем условие: Сумма_Выделена Равно Истина
    ЭлементОтбора = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Объект.Таблица.Сумма_Выделена");
    ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
    ЭлементОтбора.ПравоеЗначение = Истина;
    
    // 3. Указываем оформляемое поле на форме
    ОформляемоеПоле = ЭлементОформления.Поля.Элементы.Добавить();
    ОформляемоеПоле.Поле = Новый ПолеКомпоновкиДанных("ТаблицаСумма");
    
КонецПроцедуры

При такой реализации пользователь будет кликать по ячейкам колонки Сумма, а их фоновый цвет будет мгновенно переключаться на цвет выделения. Программа в любой момент сможет обойти таблицу значений, прочитать строки с флагом Сумма_Выделена = Истина и выполнить необходимые математические или логические операции с данными.

Решение №2: Использование «Поля табличного документа»

Бывают ситуации, когда имитации через условное оформление недостаточно. Например, если пользователю жизненно необходим полноценный Excel-подобный функционал: выделение рамочкой с помощью мыши, протягивание выделения, зажатие клавиш Shift и Ctrl для выделения несвязанных областей, стандартное копирование данных в буфер обмена.

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

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


&НаКлиенте
Процедура ПолучитьДанныеИзВыделенныхЯчеек()
    
    ТабДок = Элементы.ПолеТабличногоДокумента;
    
    // Получаем коллекцию всех выделенных областей (их может быть несколько при Ctrl)
    ВыделенныеОбласти = ТабДок.ВыделенныеОбласти;
    
    Для Каждого Область Из ВыделенныеОбласти Цикл
        
        // Каждая область описывается прямоугольником: Верх, Лево, Низ, Право
        Для НомерСтроки = Область.Верх По Область.Низ Цикл
            Для НомерКолонки = Область.Лево По Область.Право Цикл
                
                ТекущаяЯчейка = ТабДок.Область(НомерСтроки, НомерКолонки);
                ЗначениеЯчейки = ТекущаяЯчейка.Текст;
                
                // Выполняем бизнес-логику с полученным значением
                Сообщить(СтрШаблон("Выделена ячейка (%1, %2) со значением: %3", 
                    НомерСтроки, НомерКолонки, ЗначениеЯчейки));
                
            КонецЦикла;
        КонецЦикла;
        
    КонецЦикла;
    
КонецПроцедуры

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

Решение №3: Поле HTML-документа для сложного UI

Этот способ упомянут на форуме в контексте нестандартных задач (например, разработки мини-игр или интерактивных графиков внутри 1С). Если интерфейс таблицы должен вести себя абсолютно уникально, вы можете использовать элемент формы Поле HTML-документа.

В поле HTML-документа загружается сверстанная таблица на HTML/CSS, а логика множественного выделения ячеек пишется на чистом JavaScript с обработкой событий нажатия клавиш. Передача информации о выделенных элементах обратно в код 1С осуществляется с помощью механизма интеграции, например, через вызов функции оповеститьОбИсточнике или генерацию пользовательского события в JS, которое перехватывается в 1С событием ПриНажатии или ДокументСформирован.

Резюме и рекомендации

Подводя итоги, выделим ключевые правила выбора архитектурного решения:

← На главную