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