вторник, 7 декабря 2010 г.

Web-сервисы 1С 8.1 и Apache. Первые шаги.

У 1С есть одна хорошая вещь, называется Web-сервисы. Т.е. с помощью этого инструментария можно получать доступ к функционалу и данным, хранящимся в базе 1С из внешней сети. Работает это на технологии SOAP.
Сразу буду описывать конкретный пример.
Для начала надо подружить 1С и apache (дай Бог, когда-нибудь подружат 1С и nginx). Для этого, в зависимости от версии apache, нужно подключить к нему следующую библиотеку:
- для 2.2.х wsap22.dll
- для 2.х.х wsapch2.dll
из директории 1cv81/bin следующим образом: в httpd.conf у apache нужно добавить, в зависимости от библиотеки
LoadModule _1cws_module "C:/Program Files/1cv81/bin/wsap22.dll"

Так же нужно в вашем виртуальном хосте настроить директорию, куда 1С будет экспортировать файлы описания сервисов.

 Alias /1c "path/to/directory/for/1c" # это по желанию

 <Location /1c>
        DirectorySlash Off
        SetHandler 1cws-process
        Allow from all
 </Location>

Теоретически, настройка apache должна быть окончена. Можно приниматься за 1С.

Есть база по картриджам для принтеров. Узнаем через web-сервис, например, сколько у нас картриджей находятся в работе. Для этого перейдем в режим Конфигуратора. В окне "Конфигурация" выберем вкладку "Общие" -> "Web-сервисы". Начнем добавлять новый. Я его назвал "CartridgeData". В окне нового сервиса, на вкладке "Операции" создадим новую функцию, которая и будет нам возвращать количество находящихся в работе картриджей. Назовем ее CartridgeCount. В окне свойств функции выберем тип возвращаемого значения "string", поставим галочку "Возможно пустое", "Имя метода" назовем так же "CartridgeCount". При таком действии откроется окно модуля, где уже будет создан скелет будущей функции. Пока ничего тут не будем набирать.
Вернемся во вкладку "Операции" и добавим новой функции параметр (правой кнопкой по названию, Добавить - Параметр. Назовем его "State". В его свойствах укажем тип "string", так же поставим галочку на "Возможно пустое" и выберем "Направление передачи" на "Входной".
Вернемся снова в окно сервиса. Пропустим вкладку "Подсистемы" и перейдем на вкладку "Прочее". Тут необходимо указать пространство имен. Это любое слово, я вписал "1с". В "Пакеты XDTO" я выбрал последний, ибо пока не разбирался в этих вещах. В "Имя файла публикации" я вписал "cartridge.1cws" - это просто название файла, который будет лежать в соответствующей директории на web-сервере. Теперь нажмем кнопку "Модуль", чтобы открылся модуль данного сервиса, там должна быть заготовка для функции, которая в моем случае получилась такой:

Функция CartridgeCount(State)
 Если State = Ложь Тогда //проверка, конечно, примитивная
  Возврат "Укажите состояние картриджа!";
 КонецЕсли;

 ЗапросНаКоличество = Новый Запрос;

 ЗапросНаКоличество.Текст =
      "ВЫБРАТЬ
      | КОЛИЧЕСТВО(Картридж.Код) КАК Количество
      |ИЗ
      | Справочник.Картридж КАК Картридж
      |ГДЕ
      | Картридж.СостояниеКартриджа = &State"; //оставим место для переменной

//так можно получить ссылку на объект перечисления, исходя из названия
 ЗапросНаКоличество.УстановитьПараметр(
      "State",
      Перечисления.СостояниеКартриджа[State]
 );

 Результат = ЗапросНаКоличество.Выполнить().Выбрать();
 Результат.Следующий();

 Возврат Результат.Количество;
КонецФункции

Теперь можно все сохранить (F7). Далее в главном меню Администрирование -> Публикация Web-сервисов. В поле "Путь" вы должны выбрать директорию на web-сервер, куда записывать экспортный 1cws файл. Это может быть локальная директория, либо удаленная на ftp-сервере. После выбора нужно нажать "Соединение", и ниже у Вас появится возможность выбирать из списка сервисов.
Собственно, все, с серверной частью покончено.
На PHP самый примитивный код, работающий с этим web-сервисом, будет выглядеть примерно так:

// параметр ?wsdl обязателен, только так сервис 1С отдаст WSDL описание Soap-клиенту
$soapClient = new SoapClient("http://severname/1c/cartridge.1cws?wsdl");
// обязательно все параметры передавать в массиве
$cartridgeCount = $soapClient->cartridgeCount(array("State" => "ВРаботе"));
echo $cartridgeCount->return; // результат находится в поле return
?>

Комментариев нет: