Автоматическое заполнение реквизитов контрагента по ИНН — одна из наиболее востребованных функций в программах 1С. В платформе «1С:Предприятие 7.7» отсутствует встроенный механизм прямого подключения к веб-сервисам, поэтому работу с сервисом «1С:Контрагент» (1C OrgRegister) приходится реализовывать с помощью системных COM-объектов WinHttp.WinHttpRequest.5.1 и Microsoft.XMLDOM.
Разберем по шагам, как правильно сформировать SOAP-запрос, исправить типичные ошибки при отправке ИНН и разобрать полученную XML-структуру с реквизитами организации.
Для обращения к сервису автозаполнения необходимо отправить 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:
</ns1:getCorporationRequisitesByINN>). Если опечататься и написать открывающий тег вместо закрывающего, сервис вернет пустой ответ или статус 500.configurationName служит для сбора внутренней статистики обращения конфигураций к сервису. Передача значения "0" допустима.DefaultSecureProtocols для WinHttp.Частая причина получения пустого ответа от сервиса или ошибки вида SERVER-11: Option exceeds maxVolume — некорректный вызов метода по типу контрагента:
getCorporationRequisitesByINN предназначен строго для юридических лиц (10-значный ИНН). Если передать в него 12-значный ИНН физического лица или ИП, сервис не вернет данные.getEntrepreneurRequisitesByINN.Перед отправкой запроса проанализируем длину ИНН: если длина строки равна 12 символам, необходимо изменять имя вызываемого SOAP-метода.
Сервер возвращает текст ответа без указания заголовка кодировки 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-файл и обойти его дерево элементов с помощью встроенной рекурсивной процедуры.
Загрузим файл в документ 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);
КонецЦикла;
Состояние("");
КонецПроцедуры
Для адресов в структуре ответа обратите внимание на атрибуты ТипАдрЭл и Тип:
10100000 — Почтовый индекс;1010 — Номер дома;2010 — Корпус / строение;3010 — Офис / помещение.Если требуется точечно вытаскивать реквизиты из документа XML без полного обхода дерева, удобно использовать компактную функцию на основе XPath:
Функция хмлПолучитьАтрибут(хмлДок, Знач ИмяУзла = "", Знач ИмяАтрибута = "", Знач ЗначениеПоУмолчанию = "")
Рез = "";
Попытка
Узел = ?(ИмяУзла = "", хмлДок, хмлДок.selectSingleNode(ИмяУзла));
Если ИмяАтрибута = "" Тогда
Рез = Узел.text;
Иначе
Рез = Узел.attributes.getNamedItem(ИмяАтрибута).Text;
КонецЕсли;
Исключение
Рез = ЗначениеПоУмолчанию;
КонецПопытки;
Возврат СокрЛП(Рез);
КонецФункции
Таким образом, сочетание вызова WinHttp.WinHttpRequest.5.1 для отправки SOAP-запросов и парсера Microsoft.XMLDOM позволяет полноценно интегрировать сервис «1С:Контрагент» в любую конфигурацию на платформе 1С 7.7.