ВНЕДРЕНИЕ 1С:ERP и 1С:Управление холдингом     Главная     Проекты, результаты     Консультации (Новый раздел!!)     Обратная связь. Отзывы, рекомендации    
 












Интеграция & Обмены данными

  • Архив

    «   Июль 2018   »
    Пн Вт Ср Чт Пт Сб Вс
                1
    2 3 4 5 6 7 8
    9 10 11 12 13 14 15
    16 17 18 19 20 21 22
    23 24 25 26 27 28 29
    30 31          

1с web сервисы, web сервисы 1с 8.2, 1с soap, 1c php exchange


Цель этой статьи – помочь разобраться «как устроены» WEB-сервисы в «1С», понять «как механизмы работают» и «для каких задач» рационально использовать эти механизмы.

Особенностью статьи является то, что:
  • Рассматриваются (и сравниваются между собой) разные способы и приемы, которые можно применять при интеграции «1С», WEB (php) и мобильных (Ios, Android) приложений;
У разных способов есть свои плюсы/минусы,, и рационьно выбрать для конкретной задачи наиболее простой из них, компактный.
  • Одновременно приведены примеры решения как на стороне «1С», так и на стороне WEB-серверов (PHP);
Примеры решения могут быть полезными как 1С: программистам, так и WEB-специалистам, тем - кто работает на стыке направлений.
  • Собрана вместе вся необходимая информация (пошаговые инструкции), чтобы осуществить «быстрый старт», начать разработку. Т.е, что бы «не убить много времени» на изучение и настройку WEB-серверов, windows, «борьбу» с системными ошибками и пр.
Cтатья адресована:
  • 1C: Программистам и WEB-специалистам, изучающим интеграцию с использованием технологии web-сервисов;


  • Проектировщикам, IT-аналитикам - понять «суть» и сделать рациональный выбор технологий при создании проектов.
В заключение вводной части стоит сказать, что если у вас уже был опыт работы с технологиями COM/Ole, то это хорошо поможет вам и в понимании технологии WEB-сервисов.

1.1 Возможности технологий, поддержка платформой 1С




1.2 Применимость технологий по задачам клиент-серверного взаимодействия.




2. Быстрый старт. С чего начать ?


Пункт №0.
Прежде всего, необходимо выбрать (определиться) с технологией интеграции и понять "суть" - т.е как это будет работать.
Иначе говоря, нужно ответить на два вопроса:
  • Какая база 1С (или другая программа) будет выступать в роли клиента, и какая в роли сервера;
При определении того, что будет клиентом, а что сервером можно руководствоваться простым правилом: клиент может "вызвать" (управлять) сервером, а обратный вызов не возможен.
  • Какая технология взаимодействия клиента и сервера более подходит вам и будет использоваться.
Свои рекомендации по выбору технологии я изложил выше.

Пункт №1.
Итак, "суть" клиент-серверного взаимодействия - осознана. Технология взаимодействия - определена. Теперь следует создать "полигон", на котором и будет осуществляться разработка.

В данной статье, на примерах будут рассмотрены две технологии:

Работа с механизмом WEB -сервисов.

Будут рассмотрены примеры работы со стороны 1С 8 и PHP;

Работа с механизмом http-запросов (REST Web-сервисы).


Так же будут рассмотрены примеры работы со стороны 1С 8 и PHP;
В задачах, связанных с WEB-разработкой, традиционно принято:
  • Создавать "полигон" для разработки и отладки на локальном WEB-сервере программиста (localhost);
  • После того, как разработка завершена, результаты необходимо перенести на "боевой" WEB-сервер.


На практике (особенно когда начинаешь "знакомство" с технологией WEB-сервисов) при создании "полигона", а так же при переносе проекта на "боевой" сервер, возникает много "грабель".

Так вот, что бы «не убить» много времени на "борьбу" c настройками IIS (Internet Information Server) / освоение сервера apache, и настройку прав доступа Windows, я рекомендую следующее:

  • (1) "Полигон" создавать на вашей локальной рабочей машине. Операционная система - Windows 7 (проф или максимальная). Все работу - выполнять под учетной записью администратора.
  • (2) Базу 1С 8 развернуть в клиент-серверном режиме (MS SQL сервер, рекомендую 2008 R2). Использование 1С 8 в режиме клиент-сервера снимет необходимость выполнять доп. настройки по правам доступа к базе 1С со стороны WEB-сервера.
  • (3) Установить IIS, если он отсутствует. В windows его можно штатно "доустановить"




"Галочки" для опций установки компонентов IIS можно ставить "по умолчанию".
Существенным, на что требуется обратить внимание, это следующие опции (расширения ISAPI - это нужно для работы soap-соединений в WEB-сервисах, и CGI - это потребуется для работы PHP)



После завершения установки IIS убедимся, что он заработал. Для этого, в адресной строке WEB-браузера введем:



(4) Публикация (подключение) базы 1С на WEB-сервере.

И так, WEB-сервер IIS установлен и работает. Опубликуем нашу базу 1С и проверим, что теперь доступ к ней возможен и через WEB-клиента тоже.

Публиковать на WEB-сервере целесообразно ту базу 1С, в которой предусмотрена работа в режиме управляемого приложения (тонкого клиента).

Публикация базы 1С выполняется так:
В режиме конфигуратора, нужно вызвать пункт "Публикация на веб-сервере"




б) Указать параметры публикации:



Т.е в каталоге (папке) wwwroot вашего IIS нужно создать отдельную папку (каталог) для публикации вашей базы 1С.

каталог wwwroot будет создан автоматически, при установке IIS
Cоздадим и выберем такую папку (wsBase10), укажем имя для публикации (тоже назовем ee wsBase10).

После этого, нажмем на "Опубликовать".

Если, вдруг, в ответ вы получите сообщение,



то не пугайтесь. :-)

Механизм публикации 1С весьма капризный. Попробуйте нажать на "Опубликовать" еще раз.

И если в результате вы получите сообщение,



то значит все заработало.

Очень важно понимать, что при публикаации базы 1С и ее WEB-сервисов на "боевом" сервере (на пример, Windows 2008 R2) часто возникают ошибки, если вы решите использовать web-cервер IIS.

Cовет: не ставьте на "боевой" сервер IIS! Установите apache.

Это оградит вам от многих системеных ошибок. И публикация (перепубликация - при изменениях в конфигурации) будет проходить для apache гладко, без необходимости "ковыряться" в vrd - файликах и настройках IIS.

В данной статьe я не будут рассматривать процесс установки и настройки apache. На эту тему существует другие источники.

Однако, для совместной работы apache c базой 1С (и web-сервисами) есть несколько очень важных требований, которые нужно знать (донесите это до вашего системного администратора).


1. При установке apache обязательно включите поддержку расширений ISAPI.

2. Включите поддержку cgi-bin, если вам предстоит работать с PHP;

3. В базу 1С потребуется ввести специального «пользователя»…



У этого пользователя должна быть аутентификация операционной системы. И нужно указать того пользователя, от имени которого и запускается apache.

... С apache закончили и снова вернемся на наш "Полигон".

После того, как база 1С опубликовалась, убедимся, что доступ к ней через WEB-браузер работает. Для этого в адресной строке введем следующий URL:



Вот видим – 1С запускается. WEB-сервер совместно с 1С - заработал.
4. Установить службу PHP для WINDOWS.

Она понадобиться, если в рамках вашей задачи необходимо разрабатывать клиентские (web-страницы доступа к 1С) или серверные (сценарии обработки http-запросов со стороны 1С) на PHP.

Скачать диструбутив PHP для Windows рекомендую здесь:



5 Добавим в IIS каталог wsClient10, в котором будут работать наши PHP-скрипты.

PHP скрипты мы будем использовать:
  • Для создания клиентской части, при разработке WEB-сервисов 1С;
  • Для разработки серверной части, при разработке REST web сервисов (http-запросы).



6. Установим программу Notepap++. Эту компактую и удобную программу советую использоваться для редактирования PHP-скриптов.



После установки Notepad++ сразу же проверим, что PHP у нас работает. Создадим для этого простейший скрипт hello.php. Разместим его в каталоге wsClient и запустим скрипт из браузера:



Все ОК. PHP заработал. Тестовый "Полигон" полностью готов.

3. Создание WEB-сервиса, soap запросы, XDTO и JSON. Примеры 1С и PHP. На данном этапе "Полигон" должен быть у вас готов и можно приступать к разработке WEB-сервисов.

- С чего же начать изучение этой технологии? Конечно же, с классической задачки типа "Hello word"!

1. Задача создания простейшего WEB -сервиса. Рассмотрим примеры на 1С и PHP.

1.1. Добавим в базу (wsBase10) web-сервис "_РасчетыПоТарифам"



Имя файла публикации зададим "calcOrder10.1cws". URI-пространство имен так же необходимо указать. В принципе, можно указать любое имя.

1.2. Добавим в рамках web-сервиса "_РасчетыПоТарифам" операцию "getHello".

Суть выполнения операции будет простейшая - принять на входе (с клиента) три параметра (строки, числа) и вернуть ему назад (в виде результата) объединяющую строку. Тип возвращаемого значения будет примитивный - string.

Галочку "В транакции" ставить не будем, так как операция не будет изменять данные в самой базе 1С.

Если бы наша операция изменяла данные в базе 1С, то установка данной галочки имела бы смысл.
Имя метода (функции), которая будет обрабатывать входящие данные (и возвращать результат) зададим - "getHello".



1.3. Добавим для операции "getHello" входящие параметры.





Направление передачи - "входной". Т.е передаются с клиента на сервер.

1.4. В модуле web-сервиса напишем обработчик операции "getHello"
//////////////////////////////////////////////////////////////////////////////

Функция getHello(strParametr, floatParametr, integerParametr)
// Вставить содержимое обработчика.
возврат strParametr+строка(floatParametr+integerParametr)
КонецФункции


///////////////////////////////////////////////////////////////////////////////

1.5. На этом, работа по созданию простейшего WEB-сервиса завершена. И теперь, необходимо опубликовать WEB-сервис "_РасчетыПоТарифам".

Раннее, мы опубликовали на WEB-сервере базу wsBase10. Но WEB-сервисов у нас на тот момент не было. Пора опубликовать их.

Перед тем как публиковать на "полигоне" web-сервис, удалим всех пользователей из списка пользователей нашей информационной базы. Т.е список пользователей сделаем "пустым".



- Зачем это делать ?

На "полигоне" подключаться к WEB-сервисам будет только разработчик, а по этому обеспечивать аутентификацию пользователя при подключения к WEB-сервису – нет смысла.

Т.е мы осознано упростим себе работу с WEB-сервисами на тестовом "полигоне".

Нам не нужно будет указывать логин и пароль при устновке соединения.
А вот на "боевом" сервере обеспечивать аутентификацию, разумеется, придется.
Для этого (как уже было сказана ранее) в "боевой" базе нужно будет отдельно создать пользователя, от имени которого запускается сам WEB-сервер. И тогда, при установлении соединения с WEB-сервисом (soap соединение) нужно будет еще указывать логин и пароль данного пользователя.

1.6. И так, опубликуем WEB-сервис:



Замечу, что устанавливать флажок "Использовать аутентификацию операционной системы на веб-сервере" нам не придется. Это потому, что данный режим предусмотрен только для WEB-сервера IIS, а на "боевом" сервере будет работать Apache.

1.7. Создадим клиенскую часть и протестируем работу WEB-сервера.

а) Сначала, осуществим клиентский вызов из 1С.

Поступим просто. В любой другой базе 1с, которая у вас есть, создадим внешнюю обработку. В этот обработке подключимся к WEB-сервису, воспользуется операцией "getHello", передадим туда параметры и получим ответ от сервера.
Код на "1С" будет примерно таким:

///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////

&НаКлиенте
Процедура ВыполнитьЗапрос10(Команда)
// Вставить содержимое обработчика.
СтрокаРезультат = СЕРВЕР_ВыполнитьWSЗапрос10();
Предупреждение(СтрокаРезультат);
КонецПроцедуры
&НаСервереБезКонтекста
Функция СЕРВЕР_ВыполнитьWSЗапрос10()
// Аутентификацию на тестовом полигоне осуществлять не будем!
ИмяПользователя = неопределено;
Пароль = неопределено;
//
Определения = новый WSОпределения("http://localhost/wsBase10/ws/calcOrder10.1cws?wsdl",ИмяПользователя,Пароль);
Прокси = новый WSПрокси(Определения,"www.URI.com","_РасчетыПоТарифам","_РасчетыПоТарифамSoap" );
Прокси.Пользователь = ИмяПользователя;
Прокси.Пароль = Неопределено;
strРезультат = Прокси.getHello("Иванов",100.35,20);
возврат strРезультат;
КонецФункции
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Протестируем работу функции СЕРВЕР_ВыполнитьWSЗапрос10().



Ок. Работает!
б) Теперь осуществим клиентский вызов web-сервиса из PHP.
Код скрипта PHP будет примерно таким:

//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////

<?php
error_reporting( E_ERROR ); // 1. Отключаем лишние сообщения
// 2. Отключаем кэширование для SOAP. Если этого не сделать,
// функции веб-сервисов будут работать некорректно.
ini_set("soap.wsdl_cache_enabled", "0" );
// 3. Устанавливаем soap-соединение
$client = new SoapClient("http://localhost/wsBase10/ws/calcOrder10.1cws?wsdl",
array(
'login' => null, //логин, аутентификацию выполнять не будем
'password' => null, //пароль
'trace' => true,
'features' => SOAP_USE_XSI_ARRAY_TYPE,
//'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP | 5
)
);
// 4. Заполнием массив передаваемых параметров
$params["strParametr"] = "test_Soap10:";
$params["floatParametr"] = 10.34;
$params["integerParametr"] = 12;
// 5. Выполняем операцию getHello
$result = $client->getHello($params);
// 6. Выводим результат на экран
var_dump($result);
?>


///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////

Вызовем скрипт из браузера и проверим его работу:



Все отлично, вызов 1С из WEB-страницы - работает!

Подведем некоторые итоги:
Задача по простейшему WEB-сервису решена. И теперь, можно браться за создание более сложных WEB-сервисов.

А усложнение будет в том, что (пока) мы оперировали только с примитивными типами данных. Разумеется, нам необходимо будет передавать/принимать и объектные (агрегированные) типы данных.

2. Задача создания WEB -сервиса, использующего XDTO -пакеты.

Как и ранее, рассмотрим примеры на 1С и PHP.

Поставим себе такую задачу: WEB-сервис должен возвращать нам не строку, а объектные данные - "таблицу значений" (а точнее говоря, это будет массив объектов!).

Для того, что бы описывать разнообразные структуры данных (которые потребуются при приеме/передаче на WEB-сервер) в платформе 1С:8 предусмотрен механизм XDTO-пакетов.

Т.е. сначала описываем все необходимые нам типы данных, а затем уже укажем:
  • C какими пакетами XDTO может работать наш WEB-сервис (можно указать как один, так и перечень пакетов);
  • Для каждого параметра операции и возвращаемого ею результата можно указать: какого типа данных (из пакета XDTO) он будет.
Далее, работу с XDTO рассмотрим на примере получения с сервере некой «таблицы тарифов»:



Создадим операцию GetTzTariffs_0, которая будет возвращать данные типа tzTariffs.



На рисунке показано, что tzTariffs включает в себя неограниченное количество объектов el. Фактически, tzTariffs - это таблица объектов типа el.

- Как это увидеть ?
  • Если параметр "максимальное" указан как "-1", то значит количество этих объектов не ограничено (таблица с неограниченным количеством строк);
  • Если же таблица нам не нужна, а нужна просто структура (одна строка), то максимальное и минимальное значение нужно указать равными "1".
  • В свою очередь, объект el представляет из себя структуру, в которой есть реквизит объектного типа (eTariff) и реквизиты примитивного типа (cPrice, comment).



Продвигаясь по иерархии вниз, можно увидеть, что тип tariff является структурой (максимальное и минимально количество = 1), в один из реквизитов которой входит тип kindOfTariff.



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

Cовет: Лучше использовать для web -сервиса один пакет XDTO , что бы не усложнять и избежать ошибок проектирования.
Идем далее... После того, как:
  • Пакет XTDO cоздан;
  • Все типы данных описаны;
  • Для WEB-сервиса указано использование данного пакета;
  • Для параметров и результатов операций выбраны соответствующие типы (из пакета XDTO)

то можно переходить к "наполнению" объектов (структур, массивов структур) данными.

В нашем примере операция GetTzTariffs_0 должна возвращать массив строк, cодержащих объекты Tariffs.

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Функция GetTzTariffs_0()
// Вставить содержимое обработчика.
Возврат ПолучитьТЗТарифов_0();
КонецФункции


Функция ПолучитьТЗТарифов_0()
tzTariffsТип = ФабрикаXDTO.Тип("http://www.vnedrenie-upp.ru/tariffs", "tzTariffs" );
tzTariffs = ФабрикаXDTO.Создать(tzTariffsТип);
elementTZТип = ФабрикаXDTO.Тип("http://www.vnedrenie-upp.ru/tariffs", "elementTZ" );
tariffТип = ФабрикаXDTO.Тип("http://www.vnedrenie-upp.ru/tariffs", "tariff" );
kindOfTariffТип = ФабрикаXDTO.Тип("http://www.vnedrenie-upp.ru/tariffs", "kindOfTariff" );
// Заполнение ТЗ
// 1-я строка
//
kindOfTariff = ФабрикаXDTO.Создать(kindOfTariffТип);
kindOfTariff.name = "Перевозка";
kindOfTariff.active = ложь;
//
tariff = ФабрикаXDTO.Создать(tariffТип);
tariff.fullName = "Тариф 1";
tariff.begdate = ТекущаяДата();
tariff.kind = kindOfTariff;
//
elementTZ = ФабрикаXDTO.Создать(elementTZТип);
elementTZ.eTariff = tariff;
elementTZ.cPrice = 100;
elementTZ.comment = "Описание тарифа 1";
// Добавляем 1-ю строку в таблицу
tzTariffs.el.Добавить(elementTZ);
//
// 2-я строка
//
kindOfTariff = ФабрикаXDTO.Создать(kindOfTariffТип);
kindOfTariff.name = "Доставка";
kindOfTariff.active = истина;
//
tariff = ФабрикаXDTO.Создать(tariffТип);
tariff.fullName = "Тариф 2";
tariff.begdate = ТекущаяДата();
tariff.kind = kindOfTariff;
//
elementTZ = ФабрикаXDTO.Создать(elementTZТип);
elementTZ.eTariff = tariff;
elementTZ.cPrice = 200;
elementTZ.comment = "Описание тарифа 2";
// Добавляем 2-ю строку в таблицу
tzTariffs.el.Добавить(elementTZ);
//
Возврат tzTariffs;
КонецФункции


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Далее, приведем пример вызова операции "GetTzTariffs_0" с клиентской части, из 1С.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

&НаКлиенте
Процедура ВыполнитьЗапрос20(Команда)
// Вставить содержимое обработчика.
Предупреждение(СЕРВЕР_ВыполнитьWSЗапрос20());
КонецПроцедуры
&НаСервереБезКонтекста
Функция СЕРВЕР_ВыполнитьWSЗапрос20()
Определения = новый WSОпределения("http://localhost/wsBase10/ws/calcOrder10.1cws?wsdl" );
Прокси = новый WSПрокси(Определения,"www.URI.com","_РасчетыПоТарифам","_РасчетыПоТарифамSoap" );
XDTOРезультат = Прокси.GetTzTariffs_0();
ПримерРезультат_НаименованиеВидаТарифа = XDTOРезультат.el[0].eTariff.kind.name;
// Обратимся к строке по индексу ноль, далее к рекизиту eTariff, далее к вложенному реквизиту kind, далее к вложенному реквизиту name.
Возврат ПримерРезультат_НаименованиеВидаТарифа;
КонецФункции


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Аналогичный вызов из PHP и обработка результатов XDTO будет такой:
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////

<?php
error_reporting( E_ERROR ); // Отключаем сообщения
// Отключаем кэширование для SOAP. Если этого не сделать,
// функции веб-сервисов будут работать некорректно.
ini_set("soap.wsdl_cache_enabled", "0" );
$client = new SoapClient("http://localhost/wsBase10/ws/calcOrder10.1cws?wsdl" );
$result = $client->GetTzTariffs_0();
$mResult = $result->return->el;
// mResult - массив объектов. Обойдем элементы массива и выведем результаты на экран
for ($i=0; $i<count($mResult); $i++)
{
echo "<br>";
$eTariff = iconv('utf-8','cp1251',$mResult[$i]->eTariff->fullName);
var_dump($eTariff);
//
$cPrice = $mResult[$i]->cPrice;
var_dump($cPrice);
//
$cComment = $mResult[$i]->cComment;
var_dump($cComment);
//
echo "</br>";
}
?>


//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////

Теперь еще усложним задачу. Передадим с клиента на WEB-сервис (в качестве параметра) то же объектный тип данных. Пусть это будет tzKind.
Для этого сначала опишем этот тип в пакете dataTariffs, а затем добавим операцию GetTzTariffs_1.

Укажем тип параметра tzKind.




Пример работы WEB-сервиса с входящим параметром XDTO:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Функция ПолучитьТЗТарифов_1(tzKind)
tzTariffsТип = ФабрикаXDTO.Тип("http://www.vnedrenie-upp.ru/tariffs", "tzTariffs" );
tzTariffs = ФабрикаXDTO.Создать(tzTariffsТип);
elementTZТип = ФабрикаXDTO.Тип("http://www.vnedrenie-upp.ru/tariffs", "elementTZ" );
tariffТип = ФабрикаXDTO.Тип("http://www.vnedrenie-upp.ru/tariffs", "tariff" );
kindOfTariffТип = ФабрикаXDTO.Тип("http://www.vnedrenie-upp.ru/tariffs", "kindOfTariff" );
// Заполнение ТЗ
// 1-я строка
//
kindOfTariff = ФабрикаXDTO.Создать(kindOfTariffТип);
kindOfTariff.name = "Перевозка";
kindOfTariff.active = ложь;
//
tariff = ФабрикаXDTO.Создать(tariffТип);
tariff.fullName = "Тариф 1";
tariff.begdate = ТекущаяДата();
tariff.kind = kindOfTariff;
//
elementTZ = ФабрикаXDTO.Создать(elementTZТип);
elementTZ.eTariff = tariff;
elementTZ.cPrice = 100;
elementTZ.comment = "Описание тарифа 1";
// Добавляем 1-ю строку в таблицу
tzTariffs.el.Добавить(elementTZ);
//
// 2-я строка
//
kindOfTariff = ФабрикаXDTO.Создать(kindOfTariffТип);
kindOfTariff.name = "Доставка";
kindOfTariff.active = истина;
//
tariff = ФабрикаXDTO.Создать(tariffТип);
tariff.fullName = "Тариф 2";
tariff.begdate = ТекущаяДата();
tariff.kind = kindOfTariff;
//
elementTZ = ФабрикаXDTO.Создать(elementTZТип);
elementTZ.eTariff = tariff;
elementTZ.cPrice = 200;
elementTZ.comment = "Описание тарифа 2";
// Добавляем 3-ю строку в таблицу (заполним ее по входящим данным)
tzTariffs.el.Добавить(elementTZ);
//
// 3-я строка
//
kindOfTariff = ФабрикаXDTO.Создать(kindOfTariffТип);
kindOfTariff.name = tzKind.el[0].eKind.name;
kindOfTariff.active = tzKind.el[0].eKind.active;
//
tariff = ФабрикаXDTO.Создать(tariffТип);
tariff.fullName = "Тариф 3";
tariff.begdate = ТекущаяДата();
tariff.kind = kindOfTariff;
//
elementTZ = ФабрикаXDTO.Создать(elementTZТип);
elementTZ.eTariff = tariff;
elementTZ.cPrice = 300;
elementTZ.comment = "Описание тарифа 3";
// Добавляем 3-ю строку в таблицу
tzTariffs.el.Добавить(elementTZ);
//
Возврат tzTariffs;
КонецФункции


//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
Cо стороны клиента "1С" нам потребуется подготовить данные типа tzKind и передать их на WEB-cервис.

Приведу пример такого вызова:
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////

&НаКлиенте
Процедура ВыполнитьЗапрос30(Команда)
// Вставить содержимое обработчика.
Предупреждение(СЕРВЕР_ВыполнитьWSЗапрос30());
КонецПроцедуры
&НаСервереБезКонтекста
Функция СЕРВЕР_ВыполнитьWSЗапрос30()
Определения = новый WSОпределения("http://localhost/wsBase10/ws/calcOrder10.1cws?wsdl" );
Прокси = новый WSПрокси(Определения,"www.URI.com","_РасчетыПоТарифам","_РасчетыПоТарифамSoap" );
// Сформируем таблицу параметров, передаваемых в WS
//
tzKindТип = Прокси.ФабрикаXDTO.Тип("http://www.vnedrenie-upp.ru/tariffs", "tzKind" );
tzKind = Прокси.ФабрикаXDTO.Создать(tzKindТип);
//
kindOfTariffТип = Прокси.ФабрикаXDTO.Тип("http://www.vnedrenie-upp.ru/tariffs", "kindOfTariff" );
kindOfTariff = Прокси.ФабрикаXDTO.Создать(kindOfTariffТип);
kindOfTariff.name = "Тестовый вид тарифа";
kindOfTariff.active = ложь;
//
elementKindТип = Прокси.ФабрикаXDTO.Тип("http://www.vnedrenie-upp.ru/tariffs", "elementKind" );
elementKind = Прокси.ФабрикаXDTO.Создать(elementKindТип);
elementKind.eKind = kindOfTariff;
elementKind.qty = 10;
// Добавляем строку в таблицу
tzKind.el.Добавить(elementKind);
//
XDTOРезультат = Прокси.GetTzTzriffs_1(tzKind);
ПримерРезультат_НаименованиеВидаТарифа = XDTOРезультат.el[2].eTariff.kind.name;
Возврат ПримерРезультат_НаименованиеВидаТарифа;
КонецФункции


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Обращу ваше внимание на конструкцию: Прокси.ФабрикаXDTO.Тип("...

Т.е создавая на клиенте объект пакета XDTO мы должны обращаться не к собственной фабрике XDTO!, а через Прокси. Т.е к фабрике XDTO сервера.

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
А теперь настала пора задаться вопросом: нет ли альтернативы объектам XDTO ?

Можно ли вообще "не связываться" с фабрикой XDTO , передавать/принимать с WEB -сервиса как-то иначе.. (тем более, если клиент не 1С, а например WEB -страница, приложение на Android , iOS и пр) .

Ответ такой – да, можно!
Например, можно в качестве типов параметров использовать строку. А в нее "упаковывать" (сериализовывать) структуры данных.

Такая технология в WEB-программировании давно разработана и называется JSON.
Большим подспорьем является и то, что в PHP упаковка/извлечение любой структуры/массива строку выполняется в одно действие!
Пример в PHP упаковки объектов в JSON/извлечения, передачи/приемки на WEB-сервис:

///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////

// сериализация массив mDelivery в строку и поместим в параметр delivery
// * Сначала опишем структуру delivery
class delivery {
var $id;
var $checked;
var $value;
}
// Заполним структуру некоторыми данными
$sDelivery = new delivery;
$sDelivery->id = '000000005';
$sDelivery->checked = TRUE;
$sDelivery->value = 0;
// Добавим ее в массив объектов mDelivery
$mDelivery[] = $sDelivery;
// Преобразуем массив mDelivery в JSON строку и поместим результат в параметр delivery
$params["delivery"] = json_encode($mDelivery);
// Вызовем операцию ExitCalcOrder на WEB-сервисе и передадим в нее параметр (строку - delivery);
$result = $client->ExitCalcOrder($params);
// Получим в переменную jsCalcResult (строку) результат выполнения операции ExitCalcOrder
$jsCalcResult = $result->return;
// Выполним обратное преобразование: из строки jsCalcResult в объект (массив объектов, типа соответствие) arrCalcResult
$arrCalcResult = json_decode($jsCalcResult);
// Выведем информацию на экран , об объекте arrCalcResult
var_dump($arrCalcResult);

/////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

- А как же выполнять JSON преобразования в 1С ?
Платформа 1С 8 не поддерживает стандарт JSON, но это - не беда.
Существует, доступна и прекрасно работет обработка преобразования/извлечения из JSON от
// Copyright © 2010-2012 Александр Переверзев
// 1С:JSON. JavaScript Object Notation парсер и сериализатор.

Таким образом, достаточно поместить эту обработку вашу конфигурацию и вы сможете с лекгостью выполнять прямые и обратные JSON-преобразования:
Пример сериализации объекта 1С в JSON строку:

///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////

ДанныеПоГрузу = новый Структура;
ДанныеПоГрузу.Вставить("code",КодГруза);
ДанныеПоГрузу.Вставить("number",НомерГруза);
ДанныеПоГрузу.Вставить("plan",КолвоПлан);
ДанныеПоГрузу.Вставить("character",ХарактерГруза);
ДанныеПоГрузу.Вставить("packing",Упаковка);
ДанныеПоГрузу.Вставить("damage",ПовреждениеУпаковки);
ДанныеПоГрузу.Вставить("volume",Объем);
ДанныеПоГрузу.Вставить("weight",Вес);
ДанныеПоГрузу.Вставить("status",Статус);
JSON = Обработки.JSON.Создать();
jsResult = JSON.ЗаписатьJSON(ДанныеПоГрузу); //Преобразуем результат в JSON
Возврат jsResult;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Пример извлечения объекта в 1С из JSON строки:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// 1. Восстановим объекты из JSON
JSON = Обработки.JSON.Создать();
мdelivery = JSON.ПрочитатьJSON(delivery);
// в результате, мdelivery - это массив. Элемент массива - соответствие.
// Т.е, например, мdelivery[0].["id"] будет содержать '000000005'


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
В завершении, приведу пример вызова web-сервиса 1с из PHP, c получением возвращаемой JSON структуры ее обратного преобразования в объекты PHP.

Обратим внимание на преобразования iconv('cp1251','utf-8',"
и iconv('utf-8','cp1251', которые потребуются (при взаимодействии PHP - 1 C ) для преобразования строк кириллицы из кодировки cp 1251 в utf -8 и обратно.

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

<?php
error_reporting( E_ERROR ); // Отключаем сообщения
// Отключаем кэширование для SOAP. Если этого не сделать,
// функции веб-сервисов будут работать некорректно.
ini_set("soap.wsdl_cache_enabled", "0" );
$client = new SoapClient("http://localhost/wsBase10/ws/wsQuery.1cws?wsdl" );
$params["fname"] = iconv('cp1251','utf-8',"dataFreight" );
$params["param1"] = iconv('cp1251','utf-8',$_GET['code'] );
$params["param2"] = iconv('cp1251','utf-8',$_GET['number'] );
$result = $client->executeQuery($params);
$jsResult = $result->return;
$dataFreight = json_decode($jsResult);
$statusFreight = $dataFreight->codeNm;
$numberFreight = iconv('utf-8','cp1251',$dataFreight->nameRus);
?>


///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////

В заключении данного раздела хочу еще поделиться советом в части отладки WEB -сервисов 1С.

Вероятный сценарий такой: удаленный пользователь из некой своей программы (например, с WEB-сайта, мобильного приложения и др.) вызывает ваш WEB-сервис и… не получает результатов.. Либо получает, но что-то не то. :-(

Вопрос: - Как узнать о таких ошибках и отлаживать работу WEB-сервиса?
Рекомендую вам использовать для мониторинга ошибок (и сбора входящих параметров «что привело web-сервис к ошибке) журнал регистрации.

Т.е. в месте возможного возникновения логических ошибок програмно сохранять информацию о входящих параметрах в журнале регистрации (ЗаписьЖурналаРегистрации)

Если вы «боретесь» с «ошибками времени исполнения», то их можно перехватывать (попытка – исключение) и «точечно» протоколировать всю ситуацию.

В итоге, по журналу регистрации вы сможете увидеть информацию об ошибках, воспроизвести параметры возникновения и уже в интерактивном режиме, в отладчике, «победить» ее.

Подведем итоги: Примеры работы с WEB-сервисами из 1С и PHP рассмотрены. Для передачи объектных структур данных между клиентом и сервером мы воспользовались двумя технологиями:
  • (1) Пакеты XDTO
  • (2) JSON объекты.




4. Альтернатива - REST Web-сервисы (http-запросы). Примеры реализации в 1С и PHP.
В предыдущем разделе мы подробно рассматривали технологию WEB-сервисов. В этом же разделе рассмотрим альтернативную технологию, т.н. REST Web-сервисы.

Возникает справедливый вопрос: - Зачем ?

WEB-сервисы вполне функциональны и позволяют решать задачи любой сложности.

Что бы понять "зачем", сформулируем базовые различия между этими технологиями.

В основе технологии WEB-сервисов - 2 момента:
  • (1) Используется SOAP-соединение. Другими словами, выполняется SOAP-запрос.
В "1С" soap соединение форомируется так:
/////////////////////////////////////////////////////////////////////////////////////////

Определения = новый WSОпределения("http://localhost/wsBase10/ws/calcOrder10.1cws?wsdl",ИмяПользователя,Пароль);
Прокси = новый WSПрокси(Определения,"www.URI.com","_РасчетыПоТарифам","_РасчетыПоТарифамSoap" );


/////////////////////////////////////////////////////////////////////////////////////////

В PHP так:

/////////////////////////////////////////////////////////////////////////////////////////

$client = new SoapClient("http://localhost/wsBase10/ws/calcOrder10.1cws?wsdl",
array(
'login' => login, //логин,
'password' => pass, //пароль
'trace' => true,
'features' => SOAP_USE_XSI_ARRAY_TYPE,
//'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP | 5
)
);


/////////////////////////////////////////////////////////////////////////////////////////

  • (2) Для отработки soap-соединения в режиме сервера, в платформе 1С 8 предусмотрен специальный объект метаданных WEB-cервисы.



Более того, если в вашей задаче «1С» должна выступать в роли сервера, то альтернативы технологии WEB-серсивов 1С - нет.

- А когда же возможна альтернатива ?
  • Во-первых, когда «1С» выступает только в роли клиента;
  • Во-вторых, когда сервере с которым нужно работать (например сайт или какое-то WEB-приложение), не планируется поддержка SOAP-соединения.

- А какая альтернатива SOAP -соединению возможна ?

Очень "ходовой" вариант - http соединение.

В web-ориентированных системах (PHP, Android, iOS) работать с http-запросами проще, чем в SOAP-запросами. И для не очень сложных проектов технология http-запрос вполне подходит.

Классическим вариантом решения (методом http-запроса) является задача интеграции базы «1С» и WEB-сайта. Например, на сайт передается информацию по номенклатуре и ценам, обратно с сайта - информация о принятых заказах.

Характерно, что в типовых конфигурациях "1С" интеграция с сайтами как раз реализовывается средствами http -запросов.
И так, рассмотрим технологию http -запросов на примере взаимодействия 1С (клиент, 1 C 8 ) и WEB - cайта ( PHP , сервер).

1. Установка соединения и методы передачи параметров в http -запросе

Пример установки соединения с сервером со стороны 1С:
/////////////////////////////////////////////////////////////////////////////

Защищенное = Ложь;
HTTPConnect = новый HTTPСоединение("localhost/wsClient10/json/testHTTPQuery11.php",,,,,Защищенное);


////////////////////////////////////////////////////////////////////////////
Как известно, для передачи параметров от клиента на сервер, по http-протоколу, существуют два метода:

(1) Метод " get ";

Параметры (например, name и password) указываются непосредственно в URL-адресе вызова сервера.

Т.е интерактивный вызов скрипта (непосредственно из WEB-браузера) выглядел бы так:



В 1С:8 для программного вызова сервера (и передачи ему параметров методов Get) предусмотрен метод "Получить".

Пример:
Защищенное = Ложь;
HTTPConnect = новый HTTPСоединение("localhost",,,,,Защищенное);
HTTPConnect.Получить("wsClient10/json/testHTTPQuery11.php?nameVasya&password=123",ИмяВыходногоФайла);



где ИмяВыходногоФайла: Имя файла, в который помещаются данные возвращаемые с сервера.
Т.е в результате отработки запроса сервер возвращает в «1С» результат и далее (автоматически) формируется файл, в котором и содержится результат.

Соответственно, после этого в «1С» необходимо (программно) прочитать данный файл и извлечь из него полученный результат. Вот и все.

(2) Метод "post";

В этом варианте параметры не помещаются в URL-адрес, а передаются отдельно, в теле http соединения.

Понятно, что ключевым ограничение метода get является объем и содержание передаваемых данных. Т.е с помощью get можно передавать только символы, и длина URL-строки ограничена.

Методом post можно передавать данные различного содержания, в т.ч. и произвольные файлы.
Таким образом, post для задач интеграции более функционален и далее, будем работать с ним.

Для приема/передачи данных между «1С» и «WEB-сайтом» мы будет использовать текстовые файлы.
А "упаковывать/извлекать" данные из файлов будет с использование уже знакомой нам технологии JSON! Это практически избавит нас от необходимости "парсить" файл на стороне «1С» и на стороне PHP.

Для вызова сервера и передачи ему параметров методом "post" в 1С:8 предусмотрен метод: ОтправитьДляОбработки

И так, приведем пример, в котором на стороне выполняются все действия по отработке http -запроса:

Сначала, распишем план действий (укрупнено):
  • Шаг A : Подготовка данных к передаче на сервер;
  • Шаг B : Установка http-соединения с сервером;
  • Шаг C : Формирование http-запроса и передача данных (точнее, файла с данными) методом "post";
  • Шаг D : Получение ответа от сервера (точнее входящего файла) и извеление полученных результатов из файла;
  • Шаг E : Удаление отработанных временных файлов (они больше нам не нужны :-))

А теперь, его программная реализация в «1С:8»

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// 1. Заполним структуру передаваемых данных
postDataToPHP = новый Структура;
postDataToPHP.Вставить("param1","ivanon" );
postDataToPHP.Вставить("param2","ivan" );
postDataToPHP.Вставить("param3","ivanovich" );


// 2. Конвертируем данные в JSON строку
JSON = Обработки.JSON.Создать();
jsPostDataToPHP = JSON.ЗаписатьJSON(postDataToPHP);


// 3. Создадим временный исходящий (передаваемый на сервер методом POST)
// файл, поместим в него JSON строку.
тФайл = новый ТекстовыйДокумент;
строкаДанные = jsPostDataToPHP;
тФайл.ДобавитьСтроку(строкаДанные);


// 4. Получим имя для временного иcходящего файла. В нем будут содержаться исходящие данные в виде JSON-строки
ИмяИсходящегоФайла = ПолучитьИмяВременногоФайла(".txt" );

тФайл.Записать(ИмяИсходящегоФайла,КодировкаТекста.UTF);

// 5. Получим имя для временного входящего файла. В нем будет получена JSON-строка: ответ сервера PHP
ИмяВходящегоФайла = ПолучитьИмяВременногоФайла(".txt" );


// 6. Установим HTTP соединение с сервером
Защищенное = Ложь;
HTTPConnect = новый HTTPСоединение("localhost/wsClient10/json/testHTTPQuery10.php",,,,,Защищенное);


// 7. Выполним HTTP - запрос. Передадим на сервер исходящий файл (файл содержит JSON-объект, т.е исходящие параметры)


HTTPConnect.ОтправитьДляОбработки(ИмяИсходящегоФайла,"/json/",ИмяВходящегоФайла);


// И получим ответ от сервера (входящий файл). Файл содержит //JSON-объект (т.в возвращаемые с сервера данные)

// 8. Извелечем полученные от сервера данные из входящего файл
ФайлОтвета = новый ТекстовыйДокумент;
ФайлОтвета.Прочитать(ИмяВходящегоФайла,КодировкаТекста.UTF);
json_Data = ФайлОтвета.ПолучитьСтроку(1);
mData = JSON.ПрочитатьJSON(json_Data);


// 9. Выведем полученные данные для пользователя
Сообщить(mData["v1"] );
Сообщить(mData["v2"] );


// 10. Удалим использованные (не нужные более) временные файлы.
УдалитьФайлы(ИмяИсходящегоФайла);
УдалитьФайлы(ИмяВходящегоФайла);


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Ну и наконец, пример на PHP по отработки запроса на стороне сервера:

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

<?php
// 1. Получим строковые данные из входящего файла
$json_filedata = file_get_contents('php://input');
// 2. Отрежем все лишнее (добавляются 2 служебных символа), что // мешает преобразованию из JSON
$jsData = trim(ltrim($json_filedata));
$dlinaStr = strlen($jsData);
$_jsData = '';
$i=1;
while ($i<$dlinaStr) {
if ($i>2) {
$_jsData = $_jsData.substr($jsData, $i, 1);
}
$i++;
}
// 3. Преобразуем данные из JSON в объект (структуру)
$mData = json_decode($_jsData);
// 4. Сформируем другую структуру, которую заполним данными и // вернем в 1С
class returnData {
var $v1;
var $v2;
}
$sReturnData = new returnData;
$sReturnData->v1 = $mData->param1;
$sReturnData->v2 = $mData->param2;
// 5. Преобразуем данные структуры в JSON строку
$json_returnData = json_encode($sReturnData);
// 6. Вернем данные в 1С (выводимые данные будут перенаправлены в файл, который и вернется в 1С)
echo $json_returnData;
?>


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Вот и все. Компактно и функционально!


5. Востребованные задачи (кейсы проектов)

В заключении, приведу примеры прикладных задач, которые де-факто сейчас наиболее востребованы заказчиками, и которые решаются с использование WEB-сервисов и http-запросов.

Обмен данными 1с 8.2 и 7.7



Содержание статьи:

  1. Вступительная часть.
  2. Основные способы организации обмена данными между информационными базами "1С:Предприятия".
  3. Моя методика обмена данными: пример использования.
1. Вступительная часть

Прошло уже более 8-ми лет, как фирма «1С» выпустила на рынок первое прикладное решение «Управление торговлей» на платформе «1С:Предприятие 8.0», однако многие серьезные компании до сих пор используют в своей работе программы на платформе «1С:Предприятие 7.7».

Т.е. «как минимум» часть информационных баз этих компаний существует и продолжает работать «на семерке». Конечно, большинство руководителей понимают, что следует перейти на более современные программные продукты, однако на практике – все сложнее.

И причины – разные, но для адекватного понимая общей ситуации (в этой сфере), перечислю основные:

1) Организационная неготовность к "решительному" переходу на «восьмерку».

а) Суть в том, что 8-ка более сложная система. И требуется более качественного выстраивания и управления бизнес-процессами компании.

б) Нужны дополнительные ресурсы: финансовые, кадровые, временные. И к тому же «8-ку» нужно покупать, а «семерка» (почти у всех) уже есть :-) .

с) Процесс перехода сопряжен с рисками, что особенно чувствительно в кризисный период в экономике.

Однако, есть еще несколько весьма значимых (для понимания ситуации) фактора:

2) За последние 8-лет количество новых (открывающихся) бизнесов резко сократилось (т.е по сравнению с концом 90-х годов, когда открылось большинство существующих предприятий).

Как раз в конце 90-х появление 1С 7.7 удачно сопутствовало процессу открытия многих новых предприятий.

И даже, если предприятия уже существовали, то процесс перехода (с EXCEL, ACCESS и "самописных" программ) был резким и решительным.

3) За прошедшие годы компании успели вложить много ресурсов (финансовых, временных и т.д.) в настройку и адаптацию «своих семерок». А необходимость новых вложений (уже в «восьмерку») многих отпугивает.

4) И хотя «восьмерка» (особенно последняя платформа 8.2 и ее прикладные решения) имеют множество полезных и привлекательных функций (по сравнению с «семеркой»): все равно, «семерка» до сих пор может решать (особенно при работе в терминальном режиме) многие важные задачи.

К тому же, стандартные возможности «семерки» давно уже можно расширить, за счет использования различных «надстроек» и компонент. Лучшими примерами, по моей оценке, являются : 1C++ и ToySQL.

Я в своей методике обмена данными (см. 3-ю часть статьи) использую ToySQL (см: Библиотека метазапросов), и это весьма очень эффективно.
....................

И так, существуют две основных стратегии перехода с 1С 7.7 на 1C 8:
  • (1) «Решительная» стратегия. Функционал 77 полностью вытесняется и заменяется 8.
Конфигурация прикладного решения 8 дорабатывается (адаптируется) под бизнес-процессы компании.

При этом, некоторые бизнес-процессы предприятия уже оптимизируют (изменяют), с учетом имеющейся архитектуры прикладного решения на платформы 8.

А далее («в один прекрасный день» :-) ) компания перестает работать в информационной базе 7.7: к этому моменту в информационную базу 1C:8 уже должны быть перенесены (загружены) все необходимые для работы данные (из 1C:77).

Скажу прямо: по моему мнению всегда (когда это, конечно, возможно), лучше выбирать «решительную стратегию». И обязательно нужно фиксировать сроки перехода и жестко отстаивать их соблюдение. Это крайне важно!

При этом, нужно понимать, что «решительный» переход с 7.7 на 8 - это всегда проект. Часто – сложный.

А проектов без сроков не бывает. Т.е «если нет сроков – нет проекта». Это аксиома, многократно подтвержденная практикой.

И тем не менее (:-(), чаще так случается, часто выбирать «решительную» стратегию нельзя. Точнее сказать, что в этом случае проект потерпит фиаско.

И причина опять таки в том, что решительный переход – это проект, а как раз к проектам (и особенно серьезным) многие компании, увы, не готовы (о чем я как раз и писал ранее).

  • (2) Стратегия «постепенного» перехода. Т.е в процессе перехода существуют одновременно и работают информационные базы на 7.7 и на 8. Общая тенденция – постепенное вытеснение 7.7 за счет 8.

    Т.е работа в базе 7.7 прекращается после того, когда все пользователи «переведены» на 8.
Если у компании нет возможностей (ресурсов) «к решительному» переходу, то остается вариант «постепенного перехода».

Однако, необходимо ясно понимать, что осуществить хороший «постепенный переход» (в итоге) получится сложнее, чем «решительный».

Среди причин : и неопределенная растянутость по срокам, и необходимость принимать верные решения «по ходу дела», и необходимость работы + сопровождения нескольких программ + технические вопросы интеграции (обмена данными) между программами.

Далее, как раз техническим вопросам организации обмена данными между 1С 8.2 и 7.7 и будет посвящена данная статья.

Обмен данными будет рассматриваться, приемущественно, с позиции «постепенного» перехода.

2. Основные способы организации обмена данными между информационными базами "1С:Предприятия".

Основные способы организации обмена состоят в следующем:
  • Способ № 1: выгрузка, а затем - загрузка данных между базами «А» и «В».
  • Способ № 2: передача данных между базами путем подключения базы «В» к «А». Далее «B» можно использовать как источник (или приемник) данных.
Сразу замечу, что (1) способ можно использовать во всех ситуациях. Т.е это - универсальный подход и в этом его приемущества. А вот (2) подход можно использовать только, если есть возможность «подключения базы В к базе А».

Т.е если между базами «A» и «В» нельзя обеспечить (устойчивое) подключение, то без выгрузки и загрузки данных (варианта №1) ни как не обойтись.

Однако, если информационные базы, например, расположены в единой локальной сети или (тем более) на одном сервере, то появляется альтернатива использовать вариант (2).

Сложностью (при любом из способов обмена) всегда является т.н. сериализация объектов, т.е необходимость упаковать объект в структуру, состоящую из примитивных типов. А далее, эта структура:
  • либо выгружается в файл, а затем загружается из него в базе-приемнике (в нашем примере «B»), и там необходимо будет создать (собрать из структуры) соответствующий базе «А» новый объект.
  • либо объект сериализуется и структура передается (но уже без выгрузи/загрузки в файлы) в базу «В». И после этого, в базе «B» нужно создать (собрать) новый объект, соответствующий базе «А».
Сразу нужно отметить, что готовый механизм сериализации произвольного объекта заложен в платформу 1С 8. Суть его - в преобразовании объекта в XML-структуру.

Так же важно отменить, что в 1С:8 у объектов есть глобальный уникальный идентификатор (GIUD) и это тоже здорово помогает при организации обмена и синхронизации данных на платформе 1С 8.

Таким образом получается, что задача переноса объекта между информационными базами 1C:8 с одной структурой (объекта) является тривиальной и давно решенной. Это делается (например) типовыми обработками.

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

А вот для обмена данными между 1С 7.7 и 1C 8 эту сериализацию (а так же GUIDы) уже не применишь.
Т.е необходимо, каким либо образом создавать механизмы конвертации и состыковки объектов между базами источника и приемника.

Однако и здесь «1С» предусмотрела мощное средство, для быстрого создания таких механизмов и осуществления обмена данными. Это средство – конфигурация «Конвертация данных», текущая редакция - 2.

С помощью этой программы можно быстро настроить механизмы конвертации, а так же правила выгрузки и загрузки данных. И даже планы обмена (механизмы учета и регистрации изменений объектов для обмена) современная редакция "конвертации" поддерживает.

Получается, что вопрос уже решен и однозначно следует выбирать «конвертацию данных» ?

Мой ответ: если выбрали «решительную» стратегию перехода с 1С 7.7 на 1С 8, то «ДА».


Однако
, если вы выбрали «постепенную» стратегию, то «НЕ ФАКТ».

Т.е. если процесс перехода будет сложным, по этапным, растянутым по времени, то скорее всего вы «ощутите на себе» так сказать «отрицательные стороны» этой технологии (этого подхода):

  • (1) В процессе работы механизмов конвертации могут (и, к сожалению, возникают) ошибки. Чем сложней обмен, тем сложней их «отловить» и исправить.
  • (2) «Конвертация» особенная хороша, когда конфигурации источника и приемника являются типовыми или близки к типовым «1С» (или схожи между собой), тогда большинство правил конвертации уже написано за нас (или формируется конструктором в автоматическом режиме :-)).
Т.е быстрота создания правил "с лихвой" компенсирует их качество. Тем более, если обмен данными единоразовый, то какой смысл вкладываться в одноразовые программы?.

Получается , что для одноразовой выгрузки-загрузки это «прокатит». А отдельные «косяки» можно будет подправить (доделать) после завершения основного этапа переноса данных. Так всегда и поступают.

Но, если:
  • обмен данными должен проходить многократно;
  • в «каких-то случаях» данные должны повторно выгружаться и перезагружаться, в каких-то нет;
  • или нужно выгружать и загружать данные в зависимости от меняющихся условий;
  • или нужно создавать сложные алгоритмы выборки данных (что актуально для переноса данных из разросшихся семерочных баз).
то - конструктор (мастер автоматического формирования) правил конвертации вам мало поможет.

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

  • (3) И наконец, очень важно понимать, что акцент технологии «конвертации данных» сделан на выгрузку.

Т.е выгружаются (максимально) все необходимые данные + правила обмена. А в момент загрузки (в соответствии с полученными правилами) выполняется загрузка.

Это можно сравнить с ситуацией из жизни, когда человек отправляется в дальнюю дорогу.. Он не знает «будут ли» (и «понадобяться ли») ему лекарства по месту прибытия. И по этой причине, он берет все ему необходимое, т.е «в прок».

Таким образом, для сложных, многократных обменов данными (тем более если "не парится" на тему планов обмена) размеры XML – файлов могут сильно разрастаться. А это замедляет выгрузку и загрузку данных, а еще усложняет поиск «косяков» и отладку программ.

------------------
Далее, в этой статьи будет рассказано о моей методике обмена данными, которую использую я использую для задач «постепенного перехода» c 1C 7.7 на 1С 8.2.

Тип задачи, которая будет рассматриваться, – импорт данных в 1С 8.2 из 1С 7.7.

В данной методика я использую способ (2) организации обмена : т.е. без выгрузки – загрузки данных, а выполняю подключение базы 1С 7.7 к базе 1С 8.2.

Технически, для этого используется Ole-соединение (интерфейс v77.application).

К сожалению (в отличие от 1С 8 ) «семерка» не поддерживает режим com-соединения; есть только интерфейс v77.application.

Надо признать, что это – минус: ole соединение не является таким надежным и быстрым как хотелось бы :-).

И все же, механизм этот - «рабочий»; и многие его используют.
--------------------
Важным для понимания еще является такой вопрос:
  • Использовать внешнюю базу как источник или приемник данных ?
  • или (в другой формулировке): что реализовывать «импорт данных» или «экспорт данных» ?
Я считаю, что ответ прост: всегда (когда это возможно) реализовывайте импорт данных. Внешнюю базу используйте как источник данных.

Если вы работаете с 1С 7.7 (а здесь будет ole-соединение), и захотите что – либо «экспортировать» по ole, то должны понимать, что семерка не поддерживает транзакции при ole-соединении. Таким образом, вы рискуете, что экспорт данных «сорвется».

В случае же импорта - «все в ваших руках». Вам достаточно получить (по ole) объекты (в сериализованном виде + ссылки на них) и все.

Далее, все ответственные операции по записи данных вы можете осуществлять в «базе-импортере», нормально использовать транзакции, попытки-исключения и все остальное.
--------------------

Особенностью моей методики является тесное (одновременное, в едином програмном контексте) использование объектов как 1С:8 так и 1С:7.7.

Таким образом, получается достаточно «продвинутое» Ole.
----------------------
И наконец, еще одной важной особенностью технологии является использовании метазапросов. Для этих целей я подключаю к 1С 7.7 и использую внешняя библиотеку ToySQL.

Приемущества этого подхода состоят в том, что я получаю из 1С 7.7, в табличном виде, нужные мне (отобранные, сгруппированные и т.д.) данные, которые далее удобно загружать в 1С 8.

Табличный вид - простой, но при этом его и хватает (достаточно) для многих задач сериализации объектов.

Возможности языка метазапросов ТoqSQL позволяют провести предварительную обработку и упаковку (сериализацию) данных на стороне 1С 7.7.

Для выгрузки данных мне не нужно писать код на 1С 7.7 – весь код выгрузки я пишу и отлаживаю в консоли метазапросов (собственной разработки), что очень удобно.

При этом, если в процессе загрузки данных, выясняется, что нужны какие-то еще данные из "семерки", то я обращаюсь к ней по средствам ole-подключения и «забираю» эти данные.


3. Моя методика обмена данными: пример использования

Итак, опишу подробнее методику импорта данных (в базу 1С:8 из базы 1C:7.7), которую удобно использовать для решения примерно таких задач (привожу пример):


Краткая постановка задачи:

  1. Оперативный учет фирма ведет в 1С:7.7. В некой конфигурации оформляются все операции по движению товара; товары учитываются на различных складах (цеховая кладовая, пандус склада, зона брака и т.д.), далее - перемещаются между складами. По каждому из складов оформляются документы инвентаризации. Каждый склад относится к какой-либо организации (юр. лицу), но в разрезе «юр. лиц» в 1С:7.7 учет не ведется.
  2. Регламентный учет, в разрезе «юр.лиц», фирма ведет в 1С:8.2 Бухгалтерии. При этом, деления на «внутренние склады» в бухгалтерии нет, то есть все учитывается на «основном складе».
  3. Необходимо: обеспечить автоматическое заполнение фактического количества товара в документе «Инвентаризация товаров на складе» 1С Бухгалтерии 8.2.

    Заполнение табличной части документа «Инвентаризация товаров на складе» должно осуществляться по кнопке «Заполнить фактическими данными из 1С:7.7».

    При этом, по указанной (в документе инвентаризации 1С:8) организации (юр. лицу) и дате документа необходимо:
  • "собрать" все соответствующие документы инвентаризация (из 1С:7.7);
  • подсчитать суммарное количество по каждому товару
  • Загрузить полученные данные в документ «Инвентаризация» 1С:8.2.

    При этом, нужно заполнять колонку «Фактическое количество». Если есть остатки по номенклатуре, (которой нет в базе в 1С:8.2), то эту номенклатуру нужно загрузить (перенести) в 1С 8.2.

Комментарии к реализации:
  • (1) Для взаимодействия с базой 1С:7.7 со стороны базы 1С:8.2 устанавливается Olе соединение.
  • (2) Для получения и агрегации данных (группировка по складам, по указанной организации и дате) используется библиотека метазазапросов (внешняя компонента ТoySQL). Текст метазапроса и параметры (дата, юр. лицо) передаются (через Ole – соединение) из 1С: 8.2 в 1С: 7.7.

    Для передачи запроса, а так же для обратного получения результата используется отдельная экспортная функция глобального модуля.
  • (3) Результат запроса возвращается в 1С 8.2 в виде объекта «Таблица значений», и далее происходит:
    • Загрузка номенклатуры (если необходимо)
    • Загрузка данных о фактическом количестве в документ «Инвентаризация товаров»
  • (4) В конфигурацию 1С Бухгалтерии 8.2 нет необходимости вносить ни строчки кода – вся действия и обработка данных выполняется во внешней обработке (подключенной для документа «Инвентаризация» как обработчик заполнения табличной части).
Структурная схема решения:
Пояснения к реализации:

.......
....
...
...
y
...

На этом, все.

.$.
Открыть

    © 2011 Горский Михаил.