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

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

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

Способ 1. Программное изменение цвета фона строки

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

Рассмотрим простейшую реализацию:


Перем ПредыдущийНомерСтроки;

Процедура ТабДокПриАктивизацииОбласти(Элемент)
    // Получаем индекс текущей строки
    НомерСтроки = ЭлементыФормы.ТабДок.ТекущаяОбласть.Верх;
    
    // Если мы перешли на новую строку, нужно сбросить цвет у старой
    Если ПредыдущийНомерСтроки <> Неопределено И НомерСтроки <> ПредыдущийНомерСтроки Тогда
        // Сбрасываем цвет всей строки (от колонки 0 до конца)
        ЭлементыФормы.ТабДок.Область(ПредыдущийНомерСтроки, , ПредыдущийНомерСтроки).ЦветФона = Новый Цвет;
    КонецЕсли;
    
    // Красим текущую строку
    ЭлементыФормы.ТабДок.Область(НомерСтроки, , НомерСтроки).ЦветФона = WebЦвета.АкварельноСиний;
    
    // Запоминаем текущую строку как предыдущую для следующего шага
    ПредыдущийНомерСтроки = НомерСтроки;
КонецПроцедуры

Проанализируем ситуацию: данный код хорошо работает, если у вас простая таблица с однородным белым фоном. Однако, если в таблице уже задано сложное оформление (например, "зебра" или выделение итогов цветом), использование Новый Цвет (который по умолчанию сбрасывает к белому или "авто") сотрет ваши настройки.

Способ 2. Сохранение исходного форматирования

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


Перем ПредыдущийНомерСтроки;
Перем ЦветаФонаСтроки; // Здесь будем хранить соответствие "НомерКолонки -> Цвет"

Процедура ТабДокПриАктивизацииОбласти(Элемент)
    ТабДок = ЭлементыФормы.ТабДок;
    
    // Инициализируем хранилище, если оно пустое
    Если ЦветаФонаСтроки = Неопределено Тогда
        ЦветаФонаСтроки = Новый Соответствие;
    КонецЕсли;
    
    НомерСтроки = ТабДок.ТекущаяОбласть.Верх;
    
    // 1. Восстанавливаем цвета предыдущей строки
    Если ПредыдущийНомерСтроки <> Неопределено И НомерСтроки <> ПредыдущийНомерСтроки Тогда
        Для НомерКолонки = 1 По ТабДок.ШиринаТаблицы Цикл
            ОбластьЯчейка = ТабДок.Область(ПредыдущийНомерСтроки, НомерКолонки, ПредыдущийНомерСтроки, НомерКолонки);
            ЦветДляВосстановления = ЦветаФонаСтроки.Получить(НомерКолонки);
            Если ЦветДляВосстановления <> Неопределено Тогда
                ОбластьЯчейка.ЦветФона = ЦветДляВосстановления;
            КонецЕсли;
        КонецЦикла;
    КонецЕсли;
    
    // 2. Запоминаем цвета текущей строки и красим её
    Если НомерСтроки <> ПредыдущийНомерСтроки Тогда
        ЦветаФонаСтроки.Очистить();
        Для НомерКолонки = 1 По ТабДок.ШиринаТаблицы Цикл
            ОбластьЯчейка = ТабДок.Область(НомерСтроки, НомерКолонки, НомерСтроки, НомерКолонки);
            // Сохраняем текущий цвет в память
            ЦветаФонаСтроки.Вставить(НомерКолонки, ОбластьЯчейка.ЦветФона);
            // Устанавливаем цвет выделения
            ОбластьЯчейка.ЦветФона = WebЦвета.АкварельноСиний;
        КонецЦикла;
    КонецЕсли;
    
    ПредыдущийНомерСтроки = НомерСтроки;
КонецПроцедуры

Важный нюанс: использование циклов Для НомерКолонки = 1 По ШиринаТаблицы может существенно замедлить работу интерфейса, если ваша таблица содержит сотни колонок. В таких случаях лучше использовать работу с целыми областями, если это позволяет логика оформления.

Способ 3. Принудительное расширение области выделения

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

Посмотрим на пример реализации:


Процедура РезультатПриАктивизацииОбласти(Элемент)
    // Получаем ширину таблицы, чтобы знать границы выделения
    ШиринаТаблицы = ЭлементыФормы.Результат.ШиринаТаблицы;
    
    Если ШиринаТаблицы <> 0 Тогда
        ТекОбласть = ЭлементыФормы.Результат.ТекущаяОбласть;
        
        // Формируем новую область, которая охватывает всю строку от 1-й до последней колонки
        НоваяТекОбласть = ЭлементыФормы.Результат.Область(ТекОбласть.Верх, 1, ТекОбласть.Низ, ШиринаТаблицы);
        
        // Проверяем, не является ли выделенная область уже расширенной, 
        // чтобы избежать бесконечного вызова события (рекурсии)
        Если ТекОбласть.Имя <> НоваяТекОбласть.Имя Тогда
            ЭлементыФормы.Результат.ТекущаяОбласть = НоваяТекОбласть;
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Выясним причину, почему этот способ часто является предпочтительным:

  1. Производительность: Нет необходимости обходить ячейки в цикле.
  2. Безопасность данных: Мы не меняем оформление самого документа (свойство ЦветФона), а значит, при печати или сохранении файла у нас не будет лишней "синевы", если мы этого не хотим.
  3. Простота: Минимальное количество строк кода.

Дополнительные рекомендации и оптимизация

При реализации любого из предложенных методов стоит учитывать следующие моменты:

1. Проблема "Авто" цвета. В 1С свойство ЦветФона может принимать значение "Авто" (пустой цвет). При программном сбросе цвета через Новый Цвет() платформа иногда может вести себя непредсказуемо в зависимости от настроек операционной системы. Для максимально корректного сброса рекомендуется использовать системные цвета, например WindowsЦвета.ПустоеЗначение.

2. Использование прозрачных рисунков. Для продвинутых интерфейсов можно применить графический метод: программно создавать объект Рисунок (прямоугольник), делать его полупрозрачным и перемещать его координаты так, чтобы он "накрывал" текущую строку. Это позволит сохранить видимость текста и исходного цвета ячеек, создав эффект "стекла" поверх строки.

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

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

← На главную