Как в 1С 7.7 сохранить полученные с портала ЭСЧФ данные в XML-файл через EInvVatService

Программист 1С v7.7 Налоговый учет IT и автоматизация бизнеса
← На главную

При интеграции 1С:Предприятия 7.7 с порталом электронных счетов-фактур (ЭСЧФ) с использованием внешней COM-библиотеки EInvVatService часто возникает задача сохранения полученных электронных документов на локальный диск в формате XML. Разберем по шагам, как правильно выгружать полученные данные, какие встроенные методы предоставляет компонента и с какими особенностями платформы 1С 7.7 можно столкнуться при обработке кодировок и проверке подписей.

Анализ проблемы и базового сценария

Рассмотрим типовой фрагмент кода для получения входящих документов с портала, на котором обычно останавливается разработчик:


EVatService = СоздатьОбъект("EInvVatService.Connector");
InvList = EVatService.GetList(ПреобрДаты(НаДату) + "T00:00:01Z");
InvVatNumber = InvList.GetItemAttribute(i, "document/number");    
Попытка
    InvVatXml = EVatService.GetEDoc(InvVatNumber);
Исключение
    Сообщить("Не удалось получить ЭСЧФ № " + InvVatNumber + ": " + EVatService.LastError); 
    Продолжить;
КонецПопытки;
ДанныеXML = InvVatXml.Document.GetData(0);

После вызова метода GetData(0) разработчик получает текстовую строку, содержащую XML-структуру документа. Возникает вопрос: как корректно записать эту строку или сам объект документа на диск? Попытка использовать стандартные файловые механизмы платформы 1С 7.7 может привести к искажению кириллических символов, так как ЭСЧФ формируются в кодировке UTF-8, а встроенный объект Текст в 1С 7.7 работает исключительно с ANSI (Windows-1251). Объекта ЗаписьТекста в платформе 1С 7.7 нет — он появился только в 1С 8.

Способ 1. Штатные методы сохранения через объект InvVatXml (Рекомендуемый)

Самый простой, надежный и быстродействующий способ — использование встроенных методов сохранения самой COM-библиотеки EInvVatService. Объект документа предоставляет специализированные методы, которые автоматически выгружают файлы в требуемых кодировках и форматах без привлечения сторонних средств 1С.

Разберем различия методов сохранения:

  1. Метод InvVatXml.SaveToFile(ПутьКФайлу) — сохраняет полный подписанный пакет электронного документа (бинарный контейнер с электронными цифровыми подписями в формате Base64/транспортном виде).
  2. Метод InvVatXml.Document.SaveToFile(ПутьКФайлуXML) — сохраняет чистое тело XML-документа без сигнатур, в исходной кодировке UTF-8, пригодной для дальнейшего парсинга и сопоставления номенклатуры или контрагентов.

Посмотрим на практический пример реализации:


КаталогВыгрузки = "C:\ESF_XML\";
ФайлПакета = КаталогВыгрузки + InvVatNumber + ".edoc";
ФайлXML = КаталогВыгрузки + InvVatNumber + ".xml";

// Сохраняем подписанный контейнер
res = InvVatXml.SaveToFile(ФайлПакета);
Если res <> 0 Тогда
    Сообщить("Ошибка при сохранении пакета ЭСЧФ: " + EVatService.LastError);
КонецЕсли;

// Сохраняем чистый XML-документ
res = InvVatXml.Document.SaveToFile(ФайлXML);
Если res <> 0 Тогда
    Сообщить("Ошибка при сохранении XML ЭСЧФ: " + EVatService.LastError);
Иначе
    Сообщить("Документ " + InvVatNumber + " успешно сохранен в XML.");
КонецЕсли;

Способ 2. Обработка XML напрямую в оперативной памяти

Если цель сохранения XML-файла заключается исключительно в последующем разборе данных (чтении реквизитов, разделов документа, строк с товарами и суммами НДС), создавать промежуточный файл на диске вовсе не обязательно. Выясним причину: метод GetData(0) возвращает расшифрованное тело XML-документа в виде текстовой строки (в то время как GetData(1) возвращает данные в Base64).

Полученную строку можно сразу передать в объект MSXML2.DOMDocument для разбора структуры в памяти:


ДанныеXML = InvVatXml.Document.GetData(0);

XML = СоздатьОбъект("MSXML2.DOMDocument.6.0");
XML.async = 0;
XML.resolveExternals = 0;

Если XML.LoadXML(ДанныеXML) = 1 Тогда
    // Получаем необходимые узлы документа
    УзелНомера = XML.selectSingleNode("//general/number");
    Если ПустоеЗначение(УзелНомера) = 0 Тогда
        Сообщить("Успешно прочитан номер из памяти: " + УзелНомера.text);
    КонецЕсли;
Иначе
    Сообщить("Ошибка парсинга XML: " + XML.parseError.reason);
КонецЕсли;

Способ 3. Программное сохранение строки в UTF-8 через ADODB.Stream

Если по каким-либо причинам требуется записать именно полученную через GetData(0) строку на диск силами скрипта, для исключения повреждения кириллицы используем COM-объект ADODB.Stream:


ДанныеXML = InvVatXml.Document.GetData(0);
ФайлXML = "C:\ESF_XML\" + InvVatNumber + ".xml";

Поток = СоздатьОбъект("ADODB.Stream");
Поток.Type = 2; // Текстовый режим (adTypeText)
Поток.Charset = "utf-8";
Поток.Open();
Поток.WriteText(ДанныеXML);
Поток.SaveToFile(ФайлXML, 2); // 2 - перезаписать существующий файл (adSaveCreateOverWrite)
Поток.Close();

Особенности проверки ЭЦП и типичные ошибки

Проанализируем частые ошибки при работе с методами библиотеки:

  1. Ошибка при вызове функции VerifyAllSigns: Метод VerifyAllSigns() не входит в состав методов библиотеки EInvVatService. Это пользовательская функция из официальных примеров SDK, реализующая перебор и вызов метода проверки подписи VerifySign. Если функция не объявлена в глобальном модуле или модуле обработки 1С 7.7, платформа выдаст ошибку отсутствия функции.
  2. Ограничения портала и обработка исключений: Блоком Попытка ... Исключение обязательно следует оборачивать именно вызов EVatService.GetEDoc(InvVatNumber), так как портал может возвращать временную ошибку доступа или сообщение о том, что документ уже запрашивался в течение установленного лимита времени (например, 12 часов).
  3. Разрядность и регистрация библиотеки: Поскольку 1С 7.7 является 32-разрядным приложением, библиотека eInvVat.dll и криптопровайдер Avest CSP должны быть зарегистрированы через 32-битный regsvr32.exe (в 64-битных ОС Windows исполняемый файл находится по пути C:\Windows\SysWOW64\regsvr32.exe).
← На главную