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