Работа с подписками на события — это мощный инструмент расширения функционала системы без изменения типовых механизмов. Однако при работе с такими высоконагруженными объектами, как Регистр бухгалтерии, возникает множество вопросов: «Увидит ли запрос новые данные?», «Не уйдет ли система в бесконечный цикл?» и «Как это отразится на скорости закрытия месяца?». Разберем эти аспекты подробно.
Рассмотрим ситуацию, когда в подписке на событие ПриЗаписи нам необходимо проанализировать данные регистра с помощью запроса. В этот момент выполнение кода происходит внутри транзакции записи. Согласно механизмам платформы 1С, данные физически уже записаны в таблицы базы данных, но транзакция еще не зафиксирована (не выполнен Commit).
Проанализируем, что это означает на практике:
ОстаткиИОбороты) внутри транзакции может быть менее эффективным или давать специфические результаты, если границы периода не указаны явно.Вывод: Запрос увидит данные, но использовать его нужно крайне осторожно.
Выясним, что произойдет, если внутри подписки ПриЗаписи выполнить метод НаборЗаписей.Записать(). Ответ однозначный: это приведет к повторному вызову этой же самой подписки. Если не предусмотреть защитный механизм, система уйдет в бесконечную рекурсию, что закончится аварийным завершением работы или ошибкой переполнения стека.
Рассмотрим правильный способ решения этой задачи с использованием свойства ДополнительныеСвойства. Этот объект позволяет передавать параметры «сквозь» вызовы процедур в рамках одного экземпляра объекта.
Разберем пример кода для обхода рекурсии:
Процедура ПриЗаписиРегистраБухгалтерии(Источник, Отказ) Экспорт
// Проверяем, не является ли этот вызов техническим (рекурсивным)
Если Источник.ДополнительныеСвойства.Свойство("ЭтоТехническаяЗапись") Тогда
Возврат;
КонецЕсли;
// Выполняем необходимые манипуляции с данными...
// Перед программной записью устанавливаем флаг
Источник.ДополнительныеСвойства.Вставить("ЭтоТехническаяЗапись", Истина);
Попытка
Источник.Записать();
Исключение
// Обработка ошибки записи
КонецПопытки;
КонецПроцедуры
Использование флага в ДополнительныеСвойства — это стандарт де-факто при разработке на платформе 1С для предотвращения зацикливания обработчиков событий.
В процессе обсуждения часто упоминается, что событие ПриЗаписи может вызываться дважды. Проанализируем причину этого явления. Это связано с механизмом работы набора записей при включенном замещении:
Однако чаще всего в подписке на событие ПриЗаписи мы имеем дело с уже сформированным набором. Важно проверять состояние объекта Источник и понимать, какие именно данные в нем находятся в данный момент. Если ваша логика должна срабатывать только один раз, обязательно используйте дополнительные проверки на наличие записей в коллекции Источник.
Особое внимание уделим ситуации с документом РегламентнаяОперация при закрытии месяца. Этот документ может порождать тысячи и десятки тысяч проводок. Выполнение тяжелых запросов внутри подписки на каждое такое движение может катастрофически замедлить процесс.
Рассмотрим основные риски:
Источник. Это коллекция записей, которая уже находится в оперативной памяти. Пробежаться циклом по Источник и собрать нужные суммы гораздо быстрее, чем дергать СУБД новым запросом.Проанализируем пример эффективной обработки данных без запроса:
Для Каждого Запись Из Источник Цикл
Если Запись.СчетДт = ПланыСчетов.Хозрасчетный.ОбщехозяйственныеРасходы Тогда
// Выполняем логику анализа данных на лету
КонецЕсли;
КонецЦикла;
В современных версиях конфигурации «Бухгалтерия предприятия 3.0» многие регламентные операции выполняются в фоновых заданиях. Если вы поставите точку останова в процедуре подписки и запустите закрытие месяца, отладчик может не сработать. Для анализа работы кода необходимо либо настроить автоматическое подключение к фоновым заданиям в параметрах отладчика, либо использовать запись в ЖурналРегистрации для проверки хода выполнения программы.
Подведем итог. Для обеспечения стабильной и быстрой работы системы при использовании подписки на ПриЗаписи регистра бухгалтерии следует придерживаться следующих правил:
Источник.ДополнительныеСвойства.