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