1-C и Web-Сервис Часть 1

Опубликовано Опубликовано в рубрике 1C Программирование, MS SQL Server, Сайтостроение

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

В таком случае можно воспользоваться схемой передачи данных называемой Web-сервис. Суть ее заключается в следующем:

На удаленном сервере подымается веб-сервер (к примеру Apache), далее на языке cgi пишется приложение, которое будет отвечать за получение данных и запись полученных данных в sql сервер.

Пример веб-сервиса: insert_1c_sql.cgi

#!c:\Perl\bin\perl.exe
use CGI qw(:standard escapeHTML);
use DBI;

print "Content-type: text/plain; charset=windows-1251\n\n";
$query		= CGI->new();
$tz		= $query->param('tz');
@spisok		= split(':',$tz);
my $dbh 	= DBI->connect(dbi:ODBC:driver={SQL Server};server=NAME_SERVER_SQL;Database=Web-service;UID=XXX;PWD=YYYY) or PrintDie('Ошибка подключения к серверу: '."\n\n$DBI::errstr");
foreach $item (@spisok){
	@tovar		= split(',',$item);
	$sklad		= $tovar[0];
	$tovar 		= $tovar[1];
	$kvo 		= $tovar[2];
	$QueryText = "insert into Quantity (Warehouse, Goods, Quantity) values ('".$sklad."', '".$tovar."', '".$kvo."')";
	$sth = $dbh->prepare($QueryText);
	$sth->execute;
}

$sth->finish;
$dbh->disconnect;
$dbh = 0;
print('OK');

sub ReadFile {
  my $FN = shift;
  $rz = open(F, $FN) or Finish('Нет такого файла: <'.$FN.'>');
  $Str = join('', );
  chomp $Str;
  close(F);
  return $Str;
};

Теперь немного опишу, что делает данный веб-сервис:

Ожидает подключения извне и по протоколу POST передачи параметра tz, который должен быть передан вот в таком формате:

КодСклада,КодТовара,Количество:КодСклада,КодТовара,Количество:КодСклада,КодТовара,Количество:

Перечень кодов склада, товара и количества разделенный знаком «:»

Далее полученную строку скрипт разбирает на переменные и делает вставку записи в базу данных.

2. Пример обработки 1с, которая собственно и будет пулять наши данные

Процедура ОтправитьОстаткиВеб()
//Сдесь любым способом получаем остатки товаров по складам и заполняем ТаблицуЗначений:
ТЗ.НоваяКолонка("Склад");
ТЗ.НоваяКолонка("Товар");
ТЗ.НоваяКолонка("Количество");
WinHttp = СоздатьОбъект("WinHttp.WinHttpRequest.5.1");
WinHttp.Option(2,"utf-8");
Список = "";
Для НС = -ТЗ.КоличествоСтрок() По -1 Цикл
    ТЗ.ПолучитьСтрокуПоНомеру(-НС);
    Список = Список + ТЗ.Склад.Код + "," + ТЗ.Товар.Код + "," + ТЗ.Кво + ":";
    ТЗ.УдалитьСтроку(-НС);
    Если -НС % 1000 = 0 Тогда
       WinHttp.Open("POST","http://NAME_SERVER_SQL/cgi-bin/insert_1c_sql.cgi",1);
       WinHttp.SetRequestHeader("Accept-Language", "ru");
       WinHttp.SetRequestHeader("Accept-Charset",	"utf-8");
       WinHttp.setRequestHeader("Content-Language", "ru");
       WinHttp.setRequestHeader("Content-Charset", "utf-8");
       WinHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
       ПараметрыПОСТ = "tz=" + Список;
       WinHttp.Send(ПараметрыПОСТ);
       //тут пауза на 5-10 секунд 
       Список = "";
    КонецЕсли;
КонецЦикла;

Теперь описание: любым способом получаем остатки, затем формируем текстовую строку в формате КодСклада,КодТовара,Количество:КодСклада,КодТовара,Количество:КодСклада,КодТовара,Количество: затем открываем подключение к серверу и по протоколу POST в асинхронном режиме передаем сформированную строку параметром «tz».

Асинхронный режим позволяет существенно ускорить выполнение выгрузки, так как не дожидается подтверждения сервера о завершении процесса записи данных в базу. Таким образом мы отправляем целую кучу пакетов по 1000 записей, а сервер уже сам по мере своей загруженности повставляет их в базу.

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

Количество отправляемых данных 1000 выбрано тоже не случайным образом, в зависимости от объема передаваемых данных можно либо увеличить либо наоборот уменьшит это значение, практическим опытом понаблюдав за скоростью выполнения запросов. Как показала практика при меньшем значении падает скорость отправки, при большем программа может повести себя не стабильно, вплоть до вылета программы 1С.

Удачных опытов…

Отдельное спасибо Рубан Игорю за вдохновение к изучению работы веб-сервисов