Почему при печати чека из ПКО возникает ошибка «Операция не выполнена» и как её исправить?

Программист 1С v8.3 (Обычные формы) Бухгалтерский учет Торговля и дистрибуция
← На главную

При оформлении кассовых операций в конфигурации «Управление производственным предприятием» (УПП) или других типовых решениях на обычных формах пользователи и программисты могут столкнуться с ситуацией, когда нажатие кнопки печати чека в документе Приходный кассовый ордер завершается неинформативным диалоговым окном с сообщением «Операция не выполнена!». При этом чек на контрольно-кассовой технике (ККТ) не печатается, а в Журнале регистрации не фиксируется никаких критических событий.

Разберем подробно механику возникновения этой ошибки, выясним, почему стандартный отладчик и Журнал регистрации молчат, и рассмотрим пошаговое исправление программного кода.

Причина проблемы: скрытое исключение в коде формы

Проанализируем процедуру обработки нажатия кнопки пробития чека в форме документа ПриходныйКассовыйОрдер. Типовой код обработки выглядит следующим образом:


Процедура ОсновныеДействияФормыЧек(Кнопка)
    
    Перем ФУ;
    
    Если НомерЧекаККМ <> 0 Тогда
        Предупреждение("Чек уже пробит на фискальном регистраторе!", 60);
        Возврат;
    КонецЕсли;

    Если Не РаботаСТорговымОборудованием.ПолучитьПроверитьПараметрыДляПробитияЧека(ФУ, Истина, Организация) Тогда
        Возврат;
    КонецЕсли;

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

Обратим внимание на конструкцию Попытка ... Исключение. Текст сообщения «Операция не выполнена!» — это не системная ошибка платформы 1С, а жестко прописанное разработчиками предупреждение внутри блока Исключение. Любая внештатная ситуация (ошибка в коде, невидимость экспортной процедуры, сбой драйвера, деление на ноль или ошибка блокировки) перехватывается этим блоком. В результате исходное системное сообщение об ошибке полностью подавляется и не попадает ни в окно сообщений, ни в Журнал регистрации.

Как диагностировать скрытую ошибку

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

  1. Включение остановки по перехватываемым исключениям: в конфигураторе перейдем в главное меню Отладка → Остановка по ошибке и установим флажок «Останавливаться при перехвате исключений». В этом случае отладчик остановится точно на строке сбоя до того, как управление будет передано в ветку Исключение.
  2. Вывод реального описания ошибки: временно модифицируем блок обработки исключения, добавив функцию получения подробной информации:
    
    Исключение
        ОтменитьТранзакцию();
        Сообщить("Описание ошибки: " + ОписаниеОшибки());
        Предупреждение("Операция не выполнена!");
    КонецПопытки;
    

Разбор ошибки области видимости процедуры

В релизах УПП (в частности, 1.3.89.x) при внедрении функционала онлайн-касс по 54-ФЗ была допущена ошибка размещения процедуры ПодготовитьДанныеДляФискализацииЧекаПКО. Она была помещена разработчиками в модуль набора записей/модуль формы или модуль менеджера без должного контекста вызова из формы объекта.

Когда форма документа пытается выполнить вызов:

ПодготовитьДанныеДляФискализацииЧекаПКО(Ссылка, ПараметрыЧека);

Платформа 1С не может обнаружить данную процедуру в контексте текущего модуля формы или модуля объекта, генерирует исключение «Процедура или функция не определена», после чего управление мгновенно передается в блок Исключение с выводом предупреждения «Операция не выполнена!».

Пошаговое решение проблемы

Для устранения сбоя и восстановления печати фискальных чеков выполним следующие шаги:

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

Дополнительные проверки при работе с ККТ

Если после исправления контекста процедуры ошибка сохраняется, обратим внимание на сопутствующие факторы фискализации:

  1. Статус кассовой смены: если смена на фискальном регистраторе превысила 24 часа, драйвер ККТ заблокирует команду фискализации. Перед пробитием чека убедимся, что смена открыта и не истекла.
  2. Корректность ставок НДС: проверим, заполнены ли ставки НДС в табличной части РасшифровкаПлатежа. Передача неверного формата ставки приводит к отказу драйвера оборудования.
  3. Версия драйвера торгового оборудования: убедимся, что установленный драйвер торгового оборудования совместим с используемой в базе обработкой обслуживания ККТ.
← На главную