Как избежать ошибки "объект заблокирован" при отмене проведения чека ККМ на возврат сразу после его оформления в 1С 7.7?

Программист 1С v7.7 Управленческий учет Торговля и дистрибуция
← На главную

При работе с конфигурациями 1С 7.7, особенно в сфере розничной торговли, пользователи часто сталкиваются с необходимостью оформления возвратов товаров. Иногда возникает ситуация, когда после оформления и попытки проведения чека ККМ на возврат, система выдает ошибку "объект заблокирован", и документ автоматически становится непроведенным, несмотря на то что физический чек уже распечатан. Разберем эту проблему подробнее и найдем эффективное решение, основываясь на опыте сообщества 1С.

Анализируем исходную проблему: почему чек ККМ на возврат становится непроведенным?

Изначально, пользователь сталкивается со следующей ситуацией: оформляется документ "Чек ККМ" с видом операции "Чек на возврат". После нажатия кнопки "Провести", происходит попытка записи документа и, возможно, печать фискального чека. Однако сразу после этих действий документ в системе 1С помечается как непроведенный, и появляется сообщение об ошибке "Данный объект заблокирован (имя объекта)". Автор темы предположил, что это может быть связано с тем, что форма документа остается открытой, что препятствует программным изменениям его статуса проведения.

Пользователь предпринял попытку программно решить эту проблему, добавив в код модуля документа следующий фрагмент:


Если ВидОперации = Перечисление.ВидыОперацийЧекККМ.ЧекНаВозврат Тогда
    Провести();
    Чек = СоздатьОбъект("Документ.ЧекККМ");
    Чек.НайтиДокумент(ТекущийДокумент());
    Чек.СделатьНеПроведенным();
КонецЕсли;

Идея заключалась в том, чтобы сначала провести документ, а затем сразу же его распровести. Однако этот подход не сработал. Документ все равно оставался проведенным, или же ошибка блокировки не позволяла корректно выполнить метод СделатьНеПроведенным(). Были также попытки закрыть форму документа и использовать метод Блокировка(0), но безрезультатно. Интересным наблюдением стало то, что аналогичная операция по распроведению документа успешно выполнялась через внешнюю обработку, что явно указывало на особенности контекста выполнения кода.

Выясняем причины ошибки "Объект заблокирован" при попытке отмены проведения

Давайте подробнее рассмотрим, почему в 1С 7.7 возникает ошибка "Объект заблокирован" при попытке отмены проведения документа сразу после его записи или проведения, особенно из модуля формы:

  1. Блокировка объекта формой: Это одна из самых распространенных причин в 1С 7.7. Если документ открыт в форме, даже если она не находится в режиме редактирования, платформа 1С считает объект заблокированным для программных операций, изменяющих его статус проведения (например, СделатьНеПроведенным()). Контекст выполнения кода из модуля формы "привязан" к открытой форме, что создает эту блокировку.
  2. Особенности метода СделатьНеПроведенным(): Метод СделатьНеПроведенным() предназначен для объектов, которые были получены через функцию СоздатьОбъект(). Он не может быть использован непосредственно в теле предопределенной процедуры ОбработкаПроведения(), которая выполняется при попытке интерактивного или программного проведения документа. Попытка вызова этого метода сразу после Провести() может привести к конфликту, так как документ еще находится в активном транзакционном состоянии или временно заблокирован внутренними механизмами платформы.
  3. Транзакции и внутренние механизмы 1С: После выполнения Провести() документ может находиться в определенном транзакционном состоянии. Платформа 1С временно блокирует объект для обеспечения целостности данных. Немедленная попытка его "распроведения" из того же контекста или в рамках той же транзакции может нарушать эти внутренние механизмы.
  4. Различные контексты выполнения: Тот факт, что операция СделатьНеПроведенным() успешно выполнялась через внешнюю обработку, подтверждает проблему контекста. Внешняя обработка запускается в другом, более независимом контексте, который, возможно, не сталкивается с блокировкой, вызванной открытой формой документа.
  5. Другие факторы: Реже, но все же возможны ситуации, когда блокировки возникают из-за ограниченных прав пользователя на редактирование проведенных документов, закрытия периода для редактирования, или даже из-за многопользовательского режима работы базы данных (файловые блокировки .LCK или блокировки в SQL).

Таким образом, попытка проведения и немедленного распроведения документа в одном и том же контексте (особенно из модуля формы) в 1С 7.7 является сложной и часто приводит к описанной ошибке.

Эффективное решение: печать чека ККМ на возврат без проведения документа

Основываясь на опыте участников форума и понимании архитектуры 1С 7.7, самым практичным и корректным решением для возвратных чеков ККМ является печать фискального чека без фактического проведения документа в информационной базе 1С. Этот подход позволяет:

  1. Избежать блокировок: Мы полностью исключаем попытку программного распроведения, а значит, и проблему "объект заблокирован", связанную с открытой формой или транзакционным состоянием.
  2. Соответствовать фискальной логике: Факт возврата денег покупателю должен быть зафиксирован на фискальном регистраторе (ККТ). Это основная задача чека возврата. Учет же самого возврата товаров в складском и бухгалтерском учете, как правило, осуществляется другими документами, о чем мы поговорим ниже.
  3. Упростить логику: Вместо сложной и проблемной последовательности "провести, затем распровести", мы просто выполняем необходимую фискальную операцию.

Реализация решения в коде 1С 7.7

Чтобы реализовать этот подход, нам потребуется внести изменения в процедуру, отвечающую за выполнение действий при нажатии на кнопки формы документа "Чек ККМ", обычно это Процедура ВыполнитьНажатиеНаКнопку(ИмяКнопки) или аналогичная, которая вызывает процедуру проведения.

Рассмотрим примерный фрагмент кода, демонстрирующий эту логику:


Процедура ВыполнитьНажатиеНаКнопку(ИмяКнопки) // Может быть "Ок" или "Провести"

    // ... ваш существующий код обработки кнопок ...

    Если ВидОперации = Перечисление.ВидыОперацийЧекККМ.ЧекНаВозврат Тогда
        // Это чек на возврат. Наша цель - пробить фискальный чек,
        // но не проводить документ в базе 1С.

        Если Касса.РежимККМ = Перечисление.РежимыККМ.ФР Тогда // Если используется фискальный регистратор
            Если глФРВкл = 1 Тогда // Если фискальный регистратор включен
                Если ЧекПробитККМ = 0 Тогда // Если чек еще не пробит на ККМ
                    // Попытка пробить чек на фискальном регистраторе
                    Если ПробитьЧекНаККМ() = 0 Тогда // Если пробитие чека не удалось

                        Сообщить("Чек ККМ не пробит!");
                        // Если пробитие не удалось, можно прервать дальнейшие действия
                        // или дать пользователю возможность исправить ошибку.
                        // Возврат; // Закомментировано, если нужно продолжить, но без проводки

                    Иначе // Чек успешно пробит на ККМ
                        ЧекПробитККМ = 1; // Устанавливаем флаг, что чек пробит
                        Записать();       // Записываем документ, но БЕЗ проведения!
                                          // Запись важна для сохранения номера чека, позиций и т.д.
                                          // но она не создает движений по регистрам.
                        // Здесь мы явным образом НЕ вызываем Провести() для возвратного чека.
                    КонецЕсли;
                КонецЕсли;
            КонецЕсли;
        КонецЕсли;
        // Если это возвратный чек, после обработки печати мы завершаем процедуру
        // и не даем команде Провести() выполниться для самого документа.
        Возврат; // Выходим из процедуры, чтобы не вызвать Провести()
    КонецЕсли;

    // ... остальной код процедуры, который выполняет Провести() для других видов операций ...
    // Если ИмяКнопки = "Ок" Тогда
    //     Провести();
    // КонецЕсли;
    // Или другой механизм вызова проведения.
    // Убедитесь, что Провести() НЕ вызывается для ВидОперации = ЧекНаВозврат
КонецПроцедуры

В этом примере ключевой момент — это блок Если ВидОперации = Перечисление.ВидыОперацийЧекККМ.ЧекНаВозврат Тогда. Внутри этого блока мы проверяем состояние фискального регистратора и вызываем процедуру ПробитьЧекНаККМ(). Если фискальный чек успешно пробит, мы Записать() документ (чтобы сохранить изменения, например, флаг ЧекПробитККМ), но намеренно пропускаем вызов Провести(). После этого мы используем оператор Возврат;, чтобы выйти из процедуры и предотвратить выполнение дальнейшего кода, который мог бы вызвать проведение документа.

Таким образом, мы достигаем желаемого результата: фискальный чек на возврат пробивается, но документ "Чек ККМ" в базе 1С 7.7 остается непроведенным. Это полностью устраняет проблему блокировки объекта и соответствует лучшим практикам учета возвратов.

Рекомендации и лучшие практики для обработки возвратов в 1С 7.7

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

  1. Использование отдельного документа для учета возврата: В типовых конфигурациях 1С 7.7 для отражения факта возврата товаров от покупателей рекомендуется использовать специализированные документы, например, "Поступление товаров" с соответствующим видом поступления ("Возврат от покупателя"). Это позволяет корректно отразить движение товаров на складе, скорректировать взаиморасчеты и сформировать необходимые бухгалтерские проводки, не привязываясь к статусу проведения документа "Чек ККМ".
  2. Возврат без чека продажи: Если покупатель возвращает товар, но у него нет первоначального фискального чека о покупке, необходимо все равно оформить возврат. В этом случае оформляется документ "Возврат продажи" (если такой документ предусмотрен конфигурацией) или "Поступление товаров" с видом операции "Возврат", а затем пробивается фискальный чек ККМ на возврат. Этот чек на возврат не будет иметь в основании первоначальный чек реализации, но зафиксирует факт возврата денежных средств.
  3. Чек возврата прихода как фискальный документ: Важно понимать, что кассовый чек с признаком "возврат прихода" (чек возврата) является фискальным документом, подтверждающим возврат покупателю ранее полученных денежных средств. Он используется не только при возврате товара, но и для исправления ошибочно пробитого чека. Необходимо отличать его от чека коррекции, который имеет другое назначение и формируется при выявлении ошибок в расчетах, не связанных с конкретной продажей или возвратом.
  4. Аннулирование ошибочно пробитого чека: Если чек был пробит ошибочно, и вы хотите его аннулировать, существуют различные подходы. Если чек еще не распечатан и данные не были переданы оператору фискальных данных (ОФД), его можно просто аннулировать. Однако после отправки данных в ОФД для аннулирования чека прихода потребуется оформить либо "чек коррекции", либо "чек возврата", в зависимости от конкретной ситуации и требований законодательства. Чек коррекции формируется через кассу и требует составления объяснительного документа о причинах корректировки.
  5. Удаление непробитых чеков: В некоторых конфигурациях 1С 7.7 предусмотрен функционал для автоматического удаления непробитых чеков ККМ при закрытии кассовой смены. Это помогает поддерживать порядок в информационной базе и уменьшать объем данных. Также возможны групповые обработки для снятия с проведения, пометки на удаление и удаления непробитых чеков вручную, если они были созданы ошибочно и не были пробиты.

Альтернативные подходы и управление блокировками (опыт из других версий)

Хотя представленное решение является наиболее прямым и эффективным для данной проблемы в 1С 7.7, полезно рассмотреть и другие аспекты, которые могут пригодиться в схожих ситуациях или при переходе на более новые версии платформы:

  1. Процедура ПриОтменеПроведенияДокумента(): В 1С 7.7 существует предопределенная процедура ПриОтменеПроведенияДокумента(). Она вызывается, когда пользователь пытается интерактивно отменить проведение документа. В этой процедуре можно программно установить СтатусВозврата(0), чтобы отменить действие пользователя и не позволить документу распровестись, если это противоречит какой-либо бизнес-логике. Это не решает проблему автоматического распроведения, но полезно для контроля действий пользователя.
  2. Внешние обработки для распроведения: Как мы уже выяснили, выполнение операции СделатьНеПроведенным() через внешнюю обработку часто работает, в отличие от выполнения из модуля формы документа. Это связано с тем, что внешняя обработка запускается в другом контексте, не связанном с открытой формой документа, и, следовательно, не сталкивается с ее блокировками. Внешние обработки могут быть временным решением для "починки" или массового изменения статусов документов, если прямое решение в модуле документа невозможно или слишком сложно реализовать.
  3. Управление блокировками в 1С 8: В более новых версиях платформы 1С (начиная с 8-й) значительно улучшены механизмы управления блокировками данных. Разработчики имеют больше инструментов для явного контроля блокировок при проведении документов (например, с помощью объекта БлокировкаДанных), что позволяет более гибко управлять доступом к данным и избегать конфликтов в многопользовательском режиме. Однако эти механизмы недоступны в 1С 7.7.
  4. Изменение логики проведения: Вместо того чтобы пытаться провести, а затем сразу отменить проведение, всегда предпочтительнее изначально пересмотреть логику в процедуре проведения документа. Если система знает, что это возвратный чек, она может просто предотвратить его проведение, ограничившись только необходимыми фискальными действиями (печатью). Именно этот подход мы и реализовали в нашем основном решении.

Заключение

Проблема "объект заблокирован" в 1С 7.7 при попытке отмены проведения документа сразу после его оформления является характерной особенностью этой платформы, обусловленной, в первую очередь, механизмом блокировки объектов при открытой форме документа. Мы выяснили, что наиболее эффективным и корректным решением для возвратных чеков ККМ является модификация логики работы документа таким образом, чтобы выполнялась только фискальная печать чека на ККТ, без фактического проведения документа в информационной базе 1С. Этот подход позволяет не только избежать технических ошибок, но и соответствует лучшим практикам ведения учета возвратов в розничной торговле.

← На главную