Почему не заполняется КэшВыделеннойОбласти в отчетах из расширений БП 3.0 и как это исправить?

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

После очередного планового обновления конфигурации «1С:Бухгалтерия предприятия, редакция 3.0» (начиная с релизов ветки 3.0.75.58 и выше) разработчики часто сталкиваются с неприятной проблемой. В отчетах, которые были добавлены через расширения или созданы как внешние, перестает работать механизм автоматического подсчета сумм выделенных ячеек табличного документа. При этом в стандартных (типовых) отчетах конфигурации все функционирует корректно, а в кастомных — реквизит формы КэшВыделеннойОбласти упорно принимает значение Неопределено или вызывает критические ошибки выполнения кода.

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

Выясняем причину: что изменилось в релизах БП 3.0

Давайте проанализируем ситуацию. В процессе развития конфигурации разработчики фирмы «1С» регулярно оптимизируют и дорабатывают общие модули. В релизе 3.0.75.58 изменения затронули процедуру подсчета суммы выделенных ячеек, расположенную в общем модуле БухгалтерскиеОтчетыКлиент. А именно — изменилась сигнатура метода ВычислитьСуммуВыделенныхЯчеекТабличногоДокумента.

В старых версиях конфигурации вызов этой процедуры принимал 4 параметра. Давайте посмотрим на старый вариант вызова:


БухгалтерскиеОтчетыКлиент.ВычислитьСуммуВыделенныхЯчеекТабличногоДокумента(
    ПолеСумма, 
    Результат, 
    КэшВыделеннойОбласти, 
    НеобходимоВычислятьНаСервере
);

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


БухгалтерскиеОтчетыКлиент.ВычислитьСуммуВыделенныхЯчеекТабличногоДокумента(
    ПолеСумма, 
    Результат, 
    Элементы.Результат, // Новый 3-й параметр (Элемент формы)
    КэшВыделеннойОбласти, 
    НеобходимоВычислятьНаСервере
);

Почему происходит сбой и как ведет себя система

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

Внутри общего модуля БухгалтерскиеОтчетыКлиент система вызывает вспомогательную функцию проверки изменений НеобходимоОбновитьСумму. Код этой проверки выглядит примерно так:


Если НеобходимоОбновитьСумму(ПолеРезультат, КэшВыделеннойОбласти) Тогда
    ВыделенныеОбласти = ПолеРезультат.ПолучитьВыделенныеОбласти();
    // ... дальнейший расчет
КонецЕсли;

Поскольку вместо элемента формы в переменную ПолеРезультат попало значение вашего кэша (которое изначально равно Неопределено или имеет тип Структура), попытка вызвать метод ПолучитьВыделенныеОбласти() приводит к аварийному завершению работы программы. Платформа генерирует стандартное исключение: «Значение не является значением объектного типа (ПолучитьВыделенныеОбласти)».

Если же разработчик использует конструкцию Попытка ... Исключение или платформа «молча» обрабатывает ошибку внутри БСП, пользователь просто не видит сумму выделенных ячеек на форме, а переменная кэша так и остается незаполненной.

Зачем вообще нужен реквизит КэшВыделеннойОбласти?

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

Рассмотрим, как работает алгоритм оптимизации по шагам:

  1. При каждом перемещении курсора, выделении новых ячеек или клике мыши в табличном документе отчета срабатывает интерактивное событие ПриАктивизацииОбласти.
  2. Обработчик этого события вызывается очень часто. Если выполнять полный пересчет суммы выделенных ячеек при каждом микроклике (даже когда границы выделенной области фактически не изменились), это вызовет серьезные зависания интерфейса у пользователя на больших отчетах.
  3. Чтобы избежать лишней нагрузки, система сохраняет координаты и свойства предыдущей выделенной области в специальный реквизит — КэшВыделеннойОбласти.
  4. При повторном вызове функции НеобходимоОбновитьСумму() текущие координаты выделенной области сравниваются с сохраненными в кэше. Если они совпадают, расчет мгновенно прерывается, экономя вычислительные ресурсы компьютера.

Пошаговая инструкция по исправлению ошибки в расширении

Чтобы восстановить работоспособность подсчета суммы ячеек в вашем отчете, выполним следующие действия:

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

Посмотрим на пример правильного кода обработчика:


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

Обратите внимание! Если ваш табличный документ на форме называется иначе (например, Элементы.ТабличныйДокументОтчета), обязательно передавайте в качестве третьего параметра именно актуальное имя вашего элемента формы.

Что делать, если реквизит отсутствует на форме отчета?

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

  1. Откройте форму отчета в редакторе форм.
  2. Перейдите на вкладку Реквизиты (в правой части экрана).
  3. Убедитесь, что в списке реквизитов присутствует реквизит с именем КэшВыделеннойОбласти.
  4. Если его нет, нажмите кнопку Добавить реквизит, укажите имя КэшВыделеннойОбласти и установите тип значения Произвольный. На форму этот реквизит перетаскивать не нужно — он должен оставаться исключительно внутренним реквизитом формы.

Разбираем сопутствующий механизм: обработчики ожидания

Почему для расчета суммы выделенных ячеек используется обработчик ожидания, а не прямой вызов процедуры в событии ПриАктивизацииОбласти? Давайте выясним причину.

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

Правильный паттерн проектирования, который использует БСП, выглядит так:

  1. В событии табличного документа РезультатПриАктивизацииОбласти мы не производим никаких расчетов. Мы лишь подключаем обработчик ожидания с минимальной задержкой (например, 0.1 или 0.2 секунды):
  2. 
    &НаКлиенте
    Процедура РезультатПриАктивизацииОбласти(Элемент)
        ПодключитьОбработчикОжидания("Подключаемый_РезультатПриАктивизацииОбласти", 0.1, Истина);
    КонецПроцедуры
    
  3. Если пользователь продолжает двигать мышь, событие срабатывает заново, и обработчик ожидания перезапускается.
  4. Как только пользователь останавливает выбор ячеек, срабатывает процедура Подключаемый_РезультатПриАктивизацииОбласти, которая один раз выполняет расчет суммы и отключает сама себя через метод ОтключитьОбработчикОжидания.

Важное замечание для последующих обновлений (БП 3.0.96+)

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

Для того чтобы обезопасить свои разработки в расширениях от постоянных поломок при обновлениях БСП, рекомендуется:

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

← На главную