После очередного планового обновления конфигурации «1С:Бухгалтерия предприятия, редакция 3.0» (начиная с релизов ветки 3.0.75.58 и выше) разработчики часто сталкиваются с неприятной проблемой. В отчетах, которые были добавлены через расширения или созданы как внешние, перестает работать механизм автоматического подсчета сумм выделенных ячеек табличного документа. При этом в стандартных (типовых) отчетах конфигурации все функционирует корректно, а в кастомных — реквизит формы КэшВыделеннойОбласти упорно принимает значение Неопределено или вызывает критические ошибки выполнения кода.
В этой статье мы подробно разберем, почему возникает данная техническая проблема, как устроен механизм кэширования выделенных областей в типовых решениях 1С на базе БСП (Библиотеки Стандартных Подсистем), как провести отладку и как правильно адаптировать ваш код под новые стандарты платформы.
Давайте проанализируем ситуацию. В процессе развития конфигурации разработчики фирмы «1С» регулярно оптимизируют и дорабатывают общие модули. В релизе 3.0.75.58 изменения затронули процедуру подсчета суммы выделенных ячеек, расположенную в общем модуле БухгалтерскиеОтчетыКлиент. А именно — изменилась сигнатура метода ВычислитьСуммуВыделенныхЯчеекТабличногоДокумента.
В старых версиях конфигурации вызов этой процедуры принимал 4 параметра. Давайте посмотрим на старый вариант вызова:
БухгалтерскиеОтчетыКлиент.ВычислитьСуммуВыделенныхЯчеекТабличногоДокумента(
ПолеСумма,
Результат,
КэшВыделеннойОбласти,
НеобходимоВычислятьНаСервере
);
После обновления сигнатура функции изменилась — разработчики добавили новый третий параметр, который ожидает непосредственно сам элемент формы типа «Табличный документ» (обычно это Элементы.Результат). Теперь вызов функции выглядит следующим образом (5 параметров):
БухгалтерскиеОтчетыКлиент.ВычислитьСуммуВыделенныхЯчеекТабличногоДокумента(
ПолеСумма,
Результат,
Элементы.Результат, // Новый 3-й параметр (Элемент формы)
КэшВыделеннойОбласти,
НеобходимоВычислятьНаСервере
);
Разберем механизм возникновения ошибки. Когда отчет из расширения или внешний отчет пытается выполнить старый код с четырьмя параметрами, платформа 1С сопоставляет их по порядку расположения. В результате переменная КэшВыделеннойОбласти передается на место третьего параметра (который в обновленном общем модуле теперь называется ПолеРезультат и ожидает элемент формы).
Внутри общего модуля БухгалтерскиеОтчетыКлиент система вызывает вспомогательную функцию проверки изменений НеобходимоОбновитьСумму. Код этой проверки выглядит примерно так:
Если НеобходимоОбновитьСумму(ПолеРезультат, КэшВыделеннойОбласти) Тогда
ВыделенныеОбласти = ПолеРезультат.ПолучитьВыделенныеОбласти();
// ... дальнейший расчет
КонецЕсли;
Поскольку вместо элемента формы в переменную ПолеРезультат попало значение вашего кэша (которое изначально равно Неопределено или имеет тип Структура), попытка вызвать метод ПолучитьВыделенныеОбласти() приводит к аварийному завершению работы программы. Платформа генерирует стандартное исключение: «Значение не является значением объектного типа (ПолучитьВыделенныеОбласти)».
Если же разработчик использует конструкцию Попытка ... Исключение или платформа «молча» обрабатывает ошибку внутри БСП, пользователь просто не видит сумму выделенных ячеек на форме, а переменная кэша так и остается незаполненной.
Давайте детально разберем, какую роль играет этот реквизит на форме отчета. КэшВыделеннойОбласти — это реквизит формы с типом значения Произвольный. Он создается вручную на форме отчета и служит исключительно для оптимизации производительности интерфейса.
Рассмотрим, как работает алгоритм оптимизации по шагам:
ПриАктивизацииОбласти.КэшВыделеннойОбласти.НеобходимоОбновитьСумму() текущие координаты выделенной области сравниваются с сохраненными в кэше. Если они совпадают, расчет мгновенно прерывается, экономя вычислительные ресурсы компьютера.Чтобы восстановить работоспособность подсчета суммы ячеек в вашем отчете, выполним следующие действия:
Подключаемый_РезультатПриАктивизацииОбласти или Подключаемый_ДокументРезультатПриАктивизацииОбласти.Посмотрим на пример правильного кода обработчика:
&НаКлиенте
Процедура Подключаемый_РезультатПриАктивизацииОбласти()
НеобходимоВычислятьНаСервере = Ложь;
// Передаем элемент формы Элементы.Результат третьим параметром
БухгалтерскиеОтчетыКлиент.ВычислитьСуммуВыделенныхЯчеекТабличногоДокумента(
ПолеСумма,
Результат,
Элементы.Результат,
КэшВыделеннойОбласти,
НеобходимоВычислятьНаСервере
);
Если НеобходимоВычислятьНаСервере Тогда
ВычислитьСуммуВыделенныхЯчеекТабличногоДокументаВКонтекстеНаСервере();
КонецЕсли;
ОтключитьОбработчикОжидания("Подключаемый_РезультатПриАктивизацииОбласти");
КонецПроцедуры
Обратите внимание! Если ваш табличный документ на форме называется иначе (например, Элементы.ТабличныйДокументОтчета), обязательно передавайте в качестве третьего параметра именно актуальное имя вашего элемента формы.
В некоторых случаях при самостоятельном переносе отчетов из старых конфигураций или при создании собственного отчета с нуля разработчики забывают добавить необходимую структуру данных. Давайте проверим и настроим форму отчета:
КэшВыделеннойОбласти.КэшВыделеннойОбласти и установите тип значения Произвольный. На форму этот реквизит перетаскивать не нужно — он должен оставаться исключительно внутренним реквизитом формы.Почему для расчета суммы выделенных ячеек используется обработчик ожидания, а не прямой вызов процедуры в событии ПриАктивизацииОбласти? Давайте выясним причину.
Интерактивные события интерфейса в платформе 1С («активизация строки», «активизация области» и т.д.) генерируются непрерывно в процессе движения мыши пользователя. Если выполнять тяжелые расчеты мгновенно, интерфейс программы начнет «дергаться» и «тормозить».
Правильный паттерн проектирования, который использует БСП, выглядит так:
РезультатПриАктивизацииОбласти мы не производим никаких расчетов. Мы лишь подключаем обработчик ожидания с минимальной задержкой (например, 0.1 или 0.2 секунды):
&НаКлиенте
Процедура РезультатПриАктивизацииОбласти(Элемент)
ПодключитьОбработчикОжидания("Подключаемый_РезультатПриАктивизацииОбласти", 0.1, Истина);
КонецПроцедуры
Подключаемый_РезультатПриАктивизацииОбласти, которая один раз выполняет расчет суммы и отключает сама себя через метод ОтключитьОбработчикОжидания.Технологии динамически развиваются, и при переходе на еще более свежие релизы конфигурации «1С:Бухгалтерия предприятия» (например, версии 3.0.96 и выше) вы можете столкнуться со следующим витком эволюции этого метода. Разработчики добавили в функцию НеобходимоОбновитьСумму и сопутствующие вызовы еще один параметр — РазделительДробнойЧасти.
Для того чтобы обезопасить свои разработки в расширениях от постоянных поломок при обновлениях БСП, рекомендуется:
&ИзменениеИКонтроль, чтобы оперативно получать предупреждения от платформы при изменении сигнатур типовых методов в процессе обновления конфигурации.Таким образом, мы выяснили техническую причину сбоя, подробно изучили измененную сигнатуру вызова процедур общего модуля и исправили ошибку, вернув пользователям удобный инструмент автоматического подсчета сумм выделенных ячеек в отчетах.