При интеграции кассовых аппаратов Атол с 1С через компоненту FprnM1C82_54FZ.dll разработчики нередко сталкиваются с аварийным завершением работы драйвера. Ошибка вида "Access violation at address ... in module 'FprnM1C82_54FZ.dll'. Read of address 00000000" возникает непосредственно в момент отправки XML-пакета на фискализацию чека, при этом открытие смены, печать X- и Z-отчетов могут проходить абсолютно штатно.
Разберем детально, почему возникает данное исключение и как правильно сформировать XML-пакет CheckPackage для успешной печати чека.
Внутренний XML-парсер библиотеки FprnM1C82_54FZ.dll (используемой в драйверах Атол версий 8.x/9.x для 54-ФЗ) крайне чувствителен к структуре входящего документа. Если в переданном XML отсутствует хотя бы один атрибут, который парсер ожидает прочитать по указателю в памяти, происходит попытка чтения нулевого адреса (Read of address 00000000), и драйвер аварийно падает с ошибкой Access violation.
Чаще всего сбой вызывают следующие пропущенные поля в структуре пакета:
<Payments>: даже если чек оплачивается исключительно наличными, парсер требует явного указания всех видов безналичных оплат со значением 0.<Parameters>: для фискализации по 54-ФЗ компонента может ожидать атрибуты электронной почты или телефона покупателя, даже если они передаются пустыми.FiscalString, атрибут Name). В XML двойные кавычки обязательно должны экранироваться как ".Проанализируем проблемный вариант формирования пакета и исправим его структуру.
Рассмотрим пример XML-пакета, который приводит к ошибке падения драйвера:
<?xml version="1.0" encoding="UTF-8"?>
<CheckPackage>
<Parameters PaymentType="1" TaxVariant="0"/>
<Positions>
<FiscalString Name="Товар подарочный" Quantity="1" Price="0.01" Amount="0.01" Department="1" Tax="18"/>
</Positions>
<Payments Cash="0.01"/>
</CheckPackage>
В приведенном фрагменте в теге <Payments> указан только атрибут Cash. Чтобы устранить аварийное завершение, разберем необходимые доработки:
CashLessType1="0", CashLessType2="0" и CashLessType3="0".CustomerEmail="", CustomerPhone="").Посмотрим на полностью корректный и валидный XML-пакет для компоненты FprnM1C82_54FZ.dll:
<?xml version="1.0" encoding="UTF-8"?>
<CheckPackage>
<Parameters PaymentType="1" TaxVariant="0" SenderEmail="" CustomerEmail="" CustomerPhone=""/>
<Positions>
<FiscalString Name="Пакет подарочный бум. с рисунком "Цветы" 26*38 см" Quantity="1" Price="0.01" Amount="0.01" Department="1" Tax="18"/>
</Positions>
<Payments Cash="0.01" CashLessType1="0" CashLessType2="0" CashLessType3="0"/>
</CheckPackage>
Рассмотрим, как правильно формировать строку XML через объект ЗаписьXML в конфигурации 1С:
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку("UTF-8");
ЗаписьXML.ЗаписатьОбъявлениеXML();
ЗаписьXML.ЗаписатьНачалоЭлемента("CheckPackage");
// Параметры чека
ЗаписьXML.ЗаписатьНачалоЭлемента("Parameters");
ЗаписьXML.ЗаписатьАтрибут("PaymentType", "1");
ЗаписьXML.ЗаписатьАтрибут("TaxVariant", "0");
ЗаписьXML.ЗаписатьАтрибут("SenderEmail", "");
ЗаписьXML.ЗаписатьАтрибут("CustomerEmail", "");
ЗаписьXML.ЗаписатьАтрибут("CustomerPhone", "");
ЗаписьXML.ЗаписатьКонецЭлемента(); // Parameters
// Позиции чека
ЗаписьXML.ЗаписатьНачалоЭлемента("Positions");
ЗаписьXML.ЗаписатьНачалоЭлемента("FiscalString");
ЗаписьXML.ЗаписатьАтрибут("Name", "Товар подарочный");
ЗаписьXML.ЗаписатьАтрибут("Quantity", "1");
ЗаписьXML.ЗаписатьАтрибут("Price", "0.01");
ЗаписьXML.ЗаписатьАтрибут("Amount", "0.01");
ЗаписьXML.ЗаписатьАтрибут("Department", "1");
ЗаписьXML.ЗаписатьАтрибут("Tax", "18");
ЗаписьXML.ЗаписатьКонецЭлемента(); // FiscalString
ЗаписьXML.ЗаписатьКонецЭлемента(); // Positions
// Оплаты (все типы безналичных оплат обязательны к заполнению)
ЗаписьXML.ЗаписатьНачалоЭлемента("Payments");
ЗаписьXML.ЗаписатьАтрибут("Cash", "0.01");
ЗаписьXML.ЗаписатьАтрибут("CashLessType1", "0");
ЗаписьXML.ЗаписатьАтрибут("CashLessType2", "0");
ЗаписьXML.ЗаписатьАтрибут("CashLessType3", "0");
ЗаписьXML.ЗаписатьКонецЭлемента(); // Payments
ЗаписьXML.ЗаписатьКонецЭлемента(); // CheckPackage
ПакетXML = ЗаписьXML.Закрыть();
Если правка структуры XML не решает проблему со стабильностью драйвера, рассмотрим другие пути интеграции:
OpenCheck, Registration, Payment, CloseCheck) в обход промежуточного XML-пакета.