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