Как настроить интеграцию с сервисом 1С:Контрагент и разобрать XML-ответ по ИНН в 1С 7.7?

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

Автоматическое заполнение реквизитов контрагента по ИНН — одна из наиболее востребованных функций в программах 1С. В платформе «1С:Предприятие 7.7» отсутствует встроенный механизм прямого подключения к веб-сервисам, поэтому работу с сервисом «1С:Контрагент» (1C OrgRegister) приходится реализовывать с помощью системных COM-объектов WinHttp.WinHttpRequest.5.1 и Microsoft.XMLDOM.

Разберем по шагам, как правильно сформировать SOAP-запрос, исправить типичные ошибки при отправке ИНН и разобрать полученную XML-структуру с реквизитами организации.

Суть проблемы и составление SOAP-запроса

Для обращения к сервису автозаполнения необходимо отправить POST-запрос на WSDL-эндпоинт сервиса с валидным XML-телом SOAP-конверта и логином/паролем подписки ИТС.

Рассмотрим пример формирования и отправки запроса в 1С 7.7:


INN = "7721562305"; 
URL = "https://api.orgregister.1c.ru/orgregister/v5?wsdl"; 
WinHttp = СоздатьОбъект("WinHttp.WinHttpRequest.5.1"); 

// Формируем текст SOAP-конверта
t1 = "<?xml version=""1.0"" encoding=""UTF-8"" standalone=""no""?>
|<SOAP-ENV:Envelope xmlns:SOAPSDK1=""http://www.w3.org/2001/XMLSchema""
| xmlns:SOAPSDK2=""http://www.w3.org/2001/XMLSchema-instance""
| xmlns:SOAPSDK3=""http://schemas.xmlsoap.org/soap/encoding/""
| xmlns:SOAP-ENV=""http://schemas.xmlsoap.org/soap/envelope/""
| xmlns:ns1=""http://ws.orgregister.company1c.com/"">
|<SOAP-ENV:Body>
| <ns1:getCorporationRequisitesByINN>
| <ns1:INN>" + INN + "</ns1:INN>
| <ns1:configurationName>0</ns1:configurationName>
| </ns1:getCorporationRequisitesByINN>
|</SOAP-ENV:Body>
|</SOAP-ENV:Envelope>"; 

WinHttp.Open("POST", URL); 
WinHttp.SetCredentials("ЛогинИТС", "ПарольИТС", 0); 
WinHttp.Send(t1); 

Сообщить("Код ответа: " + WinHttp.Status);

Обратите внимание на ошибки в структуре XML:

  1. Все закрывающие теги должны содержать слэш (например, </ns1:getCorporationRequisitesByINN>). Если опечататься и написать открывающий тег вместо закрывающего, сервис вернет пустой ответ или статус 500.
  2. Параметр configurationName служит для сбора внутренней статистики обращения конфигураций к сервису. Передача значения "0" допустима.
  3. На современных операционных системах соединение с веб-сервисом требует поддержки протокола TLS 1.2. При возникновении ошибок подключения на операционных системах Windows 7 / Server 2008 R2 убедитесь, что в реестре включен параметр DefaultSecureProtocols для WinHttp.

Разделение запросов для юридических лиц и индивидуальных предпринимателей

Частая причина получения пустого ответа от сервиса или ошибки вида SERVER-11: Option exceeds maxVolume — некорректный вызов метода по типу контрагента:

Перед отправкой запроса проанализируем длину ИНН: если длина строки равна 12 символам, необходимо изменять имя вызываемого SOAP-метода.

Обработка и исправление кодировки полученного XML-ответа

Сервер возвращает текст ответа без указания заголовка кодировки Windows-1251, из-за чего COM-объект Microsoft.XMLDOM в 1С 7.7 может выдать ошибку парсинга символов (encoding error). Для предотвращения этой проблемы предварительно подготавливаем полученную строку ответа:


Если WinHttp.Status = 200 Тогда
    // Добавляем заголовок кодировки windows-1251 и форматируем теги
    Ответ = "<?xml version=""1.0"" encoding=""windows-1251"" standalone=""no""?>" + СокрЛП(WinHttp.ResponseText());
    Ответ = СтрЗаменить(Ответ, "/><", "/>" + РазделительСтрок + "<");
    Ответ = СтрЗаменить(Ответ, "><", ">" + РазделительСтрок + "<");
    
    // Сохраняем во временный файл для загрузки в XMLDOM
    ИмяФайла = "c:\temp_kontragent.xml";
    Т = СоздатьОбъект("Текст");
    Т.ДобавитьСтроку(Ответ);
    Т.Записать(ИмяФайла);
КонецЕсли;

Чтение и парсинг XML-ответа с помощью Microsoft.XMLDOM

Разберем, как прочитать сохраненный XML-файл и обойти его дерево элементов с помощью встроенной рекурсивной процедуры.

Загрузим файл в документ DOM и вызовем процедуру обработки:


Иксемель = СоздатьОбъект("Microsoft.XMLDOM");
Иксемель.Load(ИмяФайла);
Корень = Иксемель.DocumentElement;

// Запускаем обход узлов
ОбработатьУзел(Корень, 0);
Иксемель = "";

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


Процедура ОбработатьУзел(Узел, Уровень = 0)
    Состояние(Уровень);
    КолвоУзлов = Узел.childNodes.length;
    
    Для СчУзлов = 0 По КолвоУзлов - 1 Цикл
        ТекУзел = Узел.childNodes.item(СчУзлов);
        Если ТекУзел.nodeType <> 1 Тогда 
            Продолжить; 
        КонецЕсли;
        
        Стр = Формат("", "С" + Уровень * 4);
        
        // Сбор атрибутов узла
        СтрАтрибуты = "";
        Для счАтрибутов = 0 По ТекУзел.attributes.length - 1 Цикл
            Атрибут = ТекУзел.attributes.item(счАтрибутов);
            СтрАтрибуты = СтрАтрибуты + ?(СтрАтрибуты = "", "", "; ") + Атрибут.nodename + "=" + Атрибут.value;
        КонецЦикла;
        
        // Получение текста узла
        ТекстУзла = "";
        Если ТекУзел.childNodes.length = 1 Тогда
            Если ТекУзел.childNodes.item(0).nodetype = 3 Тогда 
                ТекстУзла = ТекУзел.childNodes.item(0).text; 
            КонецЕсли;
        КонецЕсли;
        
        Стр = Стр + ТекУзел.tagName + ?(СтрАтрибуты = "", "", " (" + СтрАтрибуты + ")") + ": " + ТекстУзла;
        Сообщить(Стр);
        
        // Рекурсивный переход на уровень ниже
        ОбработатьУзел(ТекУзел, Уровень + 1);
    КонецЦикла;
    
    Состояние("");
КонецПроцедуры

Для адресов в структуре ответа обратите внимание на атрибуты ТипАдрЭл и Тип:

Если требуется точечно вытаскивать реквизиты из документа XML без полного обхода дерева, удобно использовать компактную функцию на основе XPath:


Функция хмлПолучитьАтрибут(хмлДок, Знач ИмяУзла = "", Знач ИмяАтрибута = "", Знач ЗначениеПоУмолчанию = "")
    Рез = "";
    Попытка
        Узел = ?(ИмяУзла = "", хмлДок, хмлДок.selectSingleNode(ИмяУзла));
        Если ИмяАтрибута = "" Тогда
            Рез = Узел.text;
        Иначе
            Рез = Узел.attributes.getNamedItem(ИмяАтрибута).Text;
        КонецЕсли;
    Исключение
        Рез = ЗначениеПоУмолчанию;
    КонецПопытки;
    Возврат СокрЛП(Рез);
КонецФункции

Таким образом, сочетание вызова WinHttp.WinHttpRequest.5.1 для отправки SOAP-запросов и парсера Microsoft.XMLDOM позволяет полноценно интегрировать сервис «1С:Контрагент» в любую конфигурацию на платформе 1С 7.7.

← На главную