Как правильно передать параметры в веб-сервис Яндекс.Спеллер из 1С и исправить ошибку соответствия типов

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Интеграция с внешними веб-сервисами через протокол SOAP — стандартная задача для разработчика 1С. Однако при работе с сервисом Яндекс.Спеллер (предназначенным для проверки орфографии) начинающие специалисты часто сталкиваются с ошибкой Несоответствие типов. В этой статье мы подробно разберем, почему возникает эта проблема, как правильно работать с фабрикой XDTO и какие существуют альтернативные способы взаимодействия с сервисом.

Разбор основной проблемы: Операция vs Тип данных

Рассмотрим ситуацию, когда при попытке создания параметра через ФабрикаXDTO.Создать() система возвращает Неопределено или ошибку соответствия. Выясним причину: в WSDL-описании сервиса имя метода (например, checkText) часто совпадает с именем обертки запроса, но 1С не всегда может неявно сопоставить их в контексте WSПрокси.

Проанализируем типичную ошибку: разработчик пытается получить тип, используя имя метода checkText. Однако checkText — это операция веб-сервиса, а не тип данных в пакете XDTO. Именно поэтому метод Получить() возвращает Неопределено, а последующая попытка создать объект по этому типу вызывает исключение.

Решение №1: Упрощенный вызов через WSПрокси

Самый простой и эффективный способ работы с Яндекс.Спеллером в 1С — это прямая передача параметров в метод прокси-объекта. Если веб-сервис ожидает простые типы данных (например, строку), 1С умеет самостоятельно упаковывать их в SOAP-конверт. Разберем этот пример кода:


// Создаем прокси на основании имеющейся в конфигурации WS-ссылки
Прокси = WSСсылки.Speller.СоздатьWSПрокси("http://speller.yandex.net/services/spellservice", "SpellService", "SpellServiceSoap");

// Текст, который мы хотим проверить
ТекстДляПроверки = "Проверка орфографии в этом притложении";

// Вызываем метод напрямую. 1С сама преобразует строку в нужный XML-тип
Ответ = Прокси.checkText(ТекстДляПроверки);

В данном случае нам не нужно вручную обращаться к ФабрикаXDTO, так как параметр text является строковым. Это значительно сокращает код и уменьшает вероятность ошибки в именовании типов.

Решение №2: Использование WSОпределения и явное указание типов

Если нам необходимо программно определять структуру параметров или работать с более сложными типами данных, воспользуемся объектом WSОпределения. Это позволяет динамически анализировать состав веб-сервиса. Рассмотрим этот процесс по шагам:

  1. Создаем объект WSОпределения, загружая WSDL-описание по URL.
  2. Получаем сервис и точку подключения.
  3. Обращаемся к операции сервиса для определения типа требуемого параметра.
  4. Создаем объект XDTO на основе типа параметра операции.

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


АдресWSDL = "https://speller.yandex.net/services/spellservice?WSDL";
Определение = Новый WSОпределения(АдресWSDL);

// Указываем URI пространства имен и имя сервиса
ПространствоИмен = "http://speller.yandex.net/services/spellservice";
ИмяСервиса = "SpellService";
ТочкаПодключения = "SpellServiceSoap";

// Создаем прокси
Прокси = Новый WSПрокси(Определение, ПространствоИмен, ИмяСервиса, ТочкаПодключения);

// Получаем операцию и тип ее первого параметра
Операция = Прокси.ТочкаПодключения.Интерфейс.Операции.Получить("checkText");
ТипПараметра = Операция.Параметры.Получить("text").Тип;

// Если нужно создать сложный объект (хотя для строки это избыточно)
ПараметрXDTO = Определение.ФабрикаXDTO.Создать(ТипПараметра, "Текст с ошипкой");

// Выполнение запроса
Результат = Прокси.checkText(ПараметрXDTO);

Решение №3: Ручное указание типов XML Schema

Иногда возникают ситуации, когда фабрика XDTO конкретного пакета не содержит нужного определения, но тип является стандартным для XML. В этом случае мы можем обратиться к стандартному пакету XMLSchema. Рассмотрим, как это сделать:


// Получаем тип string из стандартного пространства имен XMLSchema
ТипWSПараметра = Прокси.ФабрикаXDTO.Тип("http://www.w3.org/2001/XMLSchema", "string");
WSПараметр = Прокси.ФабрикаXDTO.Создать(ТипWSПараметра, "Ваш текст");

Важный момент: при использовании Прокси.ФабрикаXDTO.Пакеты.Получить(...) вы получаете доступ к типам, определенным именно в схеме Яндекс.Спеллера. Если вы ищете там тип checkText, его не будет, так как это действие (команда), а не структура данных.

Расширенные возможности: Параметры и фильтры

При работе с методом checkText важно помнить, что он принимает не только текст, но и дополнительные настройки. Выясним, как управлять проверкой с помощью параметра options. Это целое число, которое является суммой бит-флагов:

Проанализируем ситуацию: если мы хотим одновременно игнорировать ссылки и находить повторы, нам нужно передать в параметр options значение 12 (4 + 8). В коде 1С это будет выглядеть так:


// Пример вызова с дополнительными параметрами: текст, язык, опции
// "ru" - код языка, 516 - игнорировать заглавные (512) + игнорировать URL (4)
Ответ = Прокси.checkText("Текст для проверки", "ru", 516);

Обработка результата проверки

Веб-сервис возвращает массив объектов. Каждая ошибка содержит позицию в тексте, само слово и список вариантов исправлений (подсказок). Проанализируем, как правильно обработать эти данные в цикле:


Если ТипЗнч(Ответ) = Тип("ОбъектXDTO") Или ТипЗнч(Ответ) = Тип("СписокXDTO") Тогда
    // Если ошибок много, придет СписокXDTO, если одна - ОбъектXDTO
    // Для универсальности можно использовать проверку количества
    Для Каждого Ошибка Из Ответ Цикл
        Сообщить("Найдена ошибка в слове: " + Ошибка.word);
        Для Каждого Вариант Из Ошибка.s Цикл
            Сообщить("Возможно вы имели в виду: " + Вариант);
        КонецЦикла;
    КонецЦикла;
КонецЕсли;

Альтернативный подход: Использование HTTPСоединение и JSON

Работа через SOAP (WS-ссылки) в 1С иногда бывает громоздкой из-за строгой типизации XDTO. Яндекс.Спеллер поддерживает более современный интерфейс JSON через обычные HTTP-запросы. Рассмотрим этот способ как альтернативу, которая часто работает быстрее и стабильнее:


Соединение = Новый HTTPСоединение("speller.yandex.net", 443,,,,, Новый ЗащищенноеСоединениеOpenSSL());
Запрос = Новый HTTPЗапрос("/services/spellservice.json/checkText");
Запрос.УстановитьТелоИзСтроки("text=" + КодироватьСтроку("Текст с ошипкой", СпособКодированияСтроки.URLВКодировкеURL) + "&lang=ru");

Ответ = Соединение.ОтправитьДляОбъекта(Запрос);
Если Ответ.КодСостояния = 200 Тогда
    ЧтениеJSON = Новый ЧтениеJSON;
    ЧтениеJSON.УстановитьСтроку(Ответ.ПолучитьТелоИзСтроки());
    МассивОшибок = ПрочитатьJSON(ЧтениеJSON);
    ЧтениеJSON.Закрыть();
    // Обрабатываем массив структур
КонецЕсли;

Резюмируем: при возникновении ошибки Несоответствие типов первым делом проверьте, не пытаетесь ли вы использовать имя метода вместо имени типа XDTO. Для простых запросов к Яндекс.Спеллеру лучше использовать прямую передачу параметров в WSПрокси или перейти на HTTPСоединение с форматом JSON, что избавит от необходимости настройки XDTO-пакетов.

← На главную