При интеграции 1С со сторонними информационными системами (например, электронными торговыми площадками — ЭТП) разработчики часто сталкиваются с жесткими требованиями к форматам передаваемых данных. Одной из наиболее острых проблем является передача даты и времени. Несмотря на то что тип dateTime в 1С соответствует стандарту XML, принимающая сторона может требовать строгое соблюдение часового пояса или специфическое количество знаков после запятой в миллисекундах, которые стандартный механизм сериализации 1С может отсекать или форматировать иначе.
В этой статье мы подробно разберем, как обойти ограничения типизации 1С, изменив WSDL-ссылку, и как правильно работать с локальными копиями схем XSD для решения подобных задач.
Рассмотрим ситуацию: веб-сервис ожидает дату в формате YYYY-MM-DDThh:mm:ss+hh:mm. В 1С объект XDTO, созданный на основании стандартной WS-ссылки, ожидает значение типа Дата. При попытке присвоить этому свойству строковое значение, 1С выдаст ошибку несоответствия типов. При передаче же объекта типа Дата, платформа сама решает, как его сериализовать в XML, и этот формат не всегда устраивает внешнюю систему. Единственный надежный способ отправить "сырую" строку с нужным форматом даты через WS-ссылку — это изменить тип поля в самой схеме с dateTime на string.
Проанализируем процесс получения структуры веб-сервиса. Обычно у нас есть только URL-ссылка на WSDL. Однако сложная схема (как у ЭТП) часто состоит не из одного файла, а из целого набора связанных схем. В основном файле WSDL можно найти ссылки на дополнительные файлы, которые описываются тегом schemaLocation. Например:
<xsd:import namespace="http://example.com/types" schemaLocation="xsd/Procurement.xsd"/>
Для корректной работы нам необходимо выкачать все дерево файлов. Разберем способы, как это сделать:
SoapUI позволяют выполнить экспорт WSDL (Export WSDL). При этом программа автоматически скачивает все связанные XSD и корректирует пути в главном файле.schemaLocation в браузере и сохранять их как файлы. Важно воссоздать ту же структуру папок, которая указана в путях.После того как мы получили локальную копию всех файлов, приступим к исправлению. Нам нужно найти в файлах .xsd описание тех полей, которые вызывают ошибку формата. Выясним причину ошибки: если поле определено как type="xsd:dateTime", заменим его на type="xsd:string".
Важный нюанс: при ручной правке типов нельзя изменять targetNamespace. Если вы измените пространство имен, 1С не сможет сопоставить типы при вызове методов сервиса, что приведет к ошибке выполнения.
Рассмотрим пример правки:
Было:
<xs:element name="PublishDate" type="xs:dateTime"/>
Стало:
<xs:element name="PublishDate" type="xs:string"/>
Теперь 1С будет воспринимать это поле как обычную строку, и мы сможем передать туда любое значение, сформированное вручную.
Выясним, как заставить 1С работать не с удаленным URL, а с нашими исправленными файлами. Существует два основных способа. Для автоматизации регулярной передачи данных через эти подключения применяется программа регулярного обмена по расписанию.
Способ А: Статическая WS-ссылка в конфигураторе
При создании новой WS-ссылки в поле "URL WSDL" мы можем указать путь к локальному файлу. Формат пути должен быть следующим: file://C:/MySchemas/service.wsdl.
Обратите внимание на важные моменты:
XSD файлы должны лежать в той же папке (или по тем путям, которые прописаны в schemaLocation относительно основного файла).WSDL файле пути к схемам должны быть отредактированы так, чтобы они указывали на локальные копии (например, просто имя файла, если всё лежит в одном каталоге).Способ Б: Динамическое создание WS-прокси
Этот метод более гибкий, так как не требует изменения метаданных конфигурации и позволяет обновлять схему "на лету". Проанализируем пример кода для программного создания прокси:
ПутьКФайлу = "C:\Schemas\service.wsdl";
Определения = Новый ОпределенияWSDL(ПутьКФайлу);
// Параметры: Определения, ПространствоИменСервиса, ИмяСервиса, ИмяТочкиПодключения
Прокси = Новый WSПрокси(Определения, "http://www.example.com/trade", "TradeService", "TradePort");
// Теперь можно обращаться к методам
Результат = Прокси.GetDocuments();
После того как тип в схеме изменен на string, мы должны подготовить значение даты перед отправкой. Для этого воспользуемся функцией Формат или напишем собственную функцию для формирования строки по стандарту ISO 8601 с таймзоной.
Пример формирования строки:
Функция ДатаВФорматISO(Знач ДатаЗапроса)
// Формируем строку вида: 2023-10-25T12:00:00+03:00
СтрокаДаты = Формат(ДатаЗапроса, "ДФ=yyyy-MM-ddTHH:mm:ss");
Смещение = "+03:00"; // Можно вычислить программно или задать константой
Возврат СтрокаДаты + Смещение;
КонецФункции
Если работа с WS-ссылкой и XDTO пакетами кажется слишком громоздкой или система продолжает выдавать ошибки типизации, рассмотрим вариант с прямыми HTTP-запросами. Это позволяет полностью отказаться от автоматической генерации XML и формировать тело SOAP-сообщения вручную.
Разберем алгоритм действий:
ЗаписьXML.HTTPСоединение методом POST.Посмотрим на пример отправки:
Соединение = Новый HTTPСоединение("api.etp.ru", , , , , 30);
Заголовки = Новый Соответствие();
Заголовки.Вставить("Content-Type", "text/xml; charset=utf-8");
Заголовки.Вставить("SOAPAction", "http://example.com/ActionName");
Запрос = Новый HTTPЗапрос("/service/v1", Заголовки);
Запрос.УстановитьТелоИзСтроки(ТекстВашегоSOAPПакета);
Ответ = Соединение.ОтправитьДляОбъекта(Запрос);
Этот метод полностью снимает любые ограничения 1С на форматы данных, так как платформа в данном случае выступает просто как инструмент передачи текста. Если же программная интеграция невозможна, альтернативным способом автоматизации станет платформа для создания программных роботов.
Подводя итог, отметим, что изменение WSDL — это крайняя, но эффективная мера, когда сторонний сервис ожидает специфическую структуру данных, которую механизмы 1С не могут обеспечить "из коробки". Чаще всего проблема решается именно заменой типа dateTime на string в локальной копии XSD. Это позволяет сохранить удобство работы через WSПрокси, при этом получив полный контроль над строковым представлением дат и других сложных типов.