Как изменить расшифровку в ячейках готового табличного документа в 1С?

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

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

Выясним причину такого поведения платформы 1С:Предприятие и рассмотрим правильные варианты реализации задачи.

В чем заключалась ошибка: разница между ПолучитьОбласть() и Область()

Проанализируем исходный фрагмент кода, в котором возникла сложность:


Для Строка = 1 По ЭлементыФормы.ДокументРезультат.ВысотаТаблицы Цикл
    Для Колонка = 1 По ЭлементыФормы.ДокументРезультат.ШиринаТаблицы Цикл
        ЭлементыФормы.ДокументРезультат.ПолучитьОбласть("R" + Формат(Строка, "ЧГ=") + "C" + Формат(Колонка, "ЧГ=") + ":" + "R" + Формат(Строка, "ЧГ=") + "C" + Формат(Колонка, "ЧГ=")).ТекущаяОбласть.Расшифровка = Неопределено;
    КонецЦикла;
КонецЦикла;

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

  1. Метод ПолучитьОбласть() создает и возвращает совершенно новый независимый объект типа ТабличныйДокумент, куда копируются данные из указанного диапазона. Обращаясь к нему через конструкцию .ПолучитьОбласть(...).ТекущаяОбласть.Расшифровка = ..., мы меняем свойство внутри временного табличного документа, находящегося в памяти. Сразу после выполнения строки этот временный объект удаляется сборщиком мусора, а сам исходный документ на форме остается неизменным.
  2. Для прямой адресации к ячейкам существующего документа предназначен метод Область(). Он возвращает объект ОбластьЯчеекТабличногоДокумента, который является прямой ссылкой на ячейки в текущем табличном документе. Любые манипуляции с этим объектом сразу влияют на отображаемые данные.

Способ 1. Прямой обход ячеек с использованием метода Область()

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

Посмотрим на пример правильного обхода таблицы:


Для НомерСтроки = 1 По ЭлементыФормы.ДокументРезультат.ВысотаТаблицы Цикл
    Для НомерКолонки = 1 По ЭлементыФормы.ДокументРезультат.ШиринаТаблицы Цикл
        ТекущаяЯчейка = ЭлементыФормы.ДокументРезультат.Область(НомерСтроки, НомерКолонки);
        ТекущаяЯчейка.Расшифровка = НужнаяРасшифровка;
    КонецЦикла;
КонецЦикла;

Разберем по шагам важные технические особенности этого способа:

  1. Метод Область(НомерСтроки, НомерКолонки) принимает числовые координаты (начиная с 1) без необходимости форматировать строку адреса формата R1C1, что упрощает чтение кода и снижает нагрузку на строковые операции.
  2. Режим только для чтения: Чтобы пользователь мог дважды кликнуть по ячейке или нажать Enter для вызова расшифровки, у табличного документа обязательно должно быть установлено свойство ТолькоПросмотр = Истина. Если установлено Ложь, платформа перейдет в режим редактирования текста ячейки, игнорируя механизм расшифровки.
  3. Производительность: Данный способ имеет существенный недостаток. Если отчет содержит тысячи строк и десятки колонок, двойной цикл с тысячами обращений к объектной модели через Область() приведет к заметному зависанию интерфейса программы.

Способ 2. Перехват события «Обработка расшифровки» (рекомендуемый)

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

Для этого используем событие ОбработкаРасшифровки у элемента формы ПолеТабличногоДокумента.

Рассмотрим реализацию обработчика:


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

КонецПроцедуры

Преимущества перехвата события «на лету»:

  1. Мгновенное формирование отчета: Отчет выводится пользователю без задержек на поклеточный обход тысяч ячеек.
  2. Гибкость логики: Алгоритм обработки запускается только тогда, когда пользователь действительно кликнул по ячейке. При этом доступны как переданное значение в параметре Расшифровка, так и сама область через Элемент.ТекущаяОбласть.

Особенности расшифровки в отчетах на СКД

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

← На главную