gifts2017

Управление 1С извне

Опубликовал Иван Григорьев (Soloist) в раздел Программирование - Работа с интерфейсом

Передача команд 1С на выполнение через ссылки в письме.

1С имеет один очень мощный инструмент, который для меня был темным лесом. Хотя, наверно, и сейчас таковым остаётся, но уже что-то начинает проясняться. Это Web-сервисы. На сайте 1С можно поверхностно понять что это такое и зачем вообще это нужно.

Итак, web-сервисы помогают интегрировать 1С с различными программами, делая её более гибкой. Статей в интеренете достаточно можно, но в основном там описывается выгрузка из 1С, обмен между двумя 1С или 1С и каким-то мощным программным продуктом написанным на C или других языках.

Для меня же была поставлена задача возможности управление 1С через браузер. Как пример: обрабатывать завершение задачи БП в 1С по ссылке в письме (примерно такого типа http://infostart.ru/?user=000000001&bp=000000555, т.е. отсюда видно, что пользователь 000000001 хочет закрыть задачу 000000555), т.е. пользователь со своего смартфона не имеющего доступа к 1С как таковому, должен получить возможность управлять ею извне. Собственно, более сложной задачей можно поставить написание собственных web-форм, более легких и компактных, с произвольным дизайном для управления 1С.

Задача с точки зрения написания кода 1С очень легкая. Основная сложность заключалась в освоении HTML и JavaScript для управления извне. Начальные знаний по этому вопросу я подчерпнул из статьи Примеры пользования web сервисов 1С из браузера.

Настройка 1С

Для возможности использовать 1С в вебе необходимо:
1. Установить модуль расширения веб-сервера;

2. Настроить Windows: доустановить компоненты IIS и настроить проверку подлинности. Всё это можно прочитать в статье Настройка веб-клиента 1С:Предприятие 8.2 под Windows 7 x64 и IIS.

Программирование 1С

Теперь можно приступить к конфигурированию.

1. Создадим Web-сервис Input:
1.1. Input имеет операцию InputData которая принимает два параметра: User и Command, и возвращает параметр типа "boolean (http://www.w3.org/2001/XMLSchema)". Текст функции InputData:

Функция InputData(User, Command)

   
обДанные = Справочники.Данные.СоздатьЭлемент();

   
обДанные.Наименование = User + ":" + Command;

   
обДанные.Записать();

    Возврат Истина;

КонецФункции

1.2. Устанавливаем для Input URI пространства имен = "http://infostart.ru". Здесь может быть любое уникальное имя, обычно это ссылка на сайт.

1.3. Устанавливаем для Input имя файла публикации = "input.1cws". Это имя web-сервиса к которому будем устанавливать соединение.

2. Для наглядности примера создадим справочник Данные, все параметры оставим по умолчанию.

3. Публикуем нашу конфигурацию и web-сервис: Администрирование -> Публикация на веб сервере...

На этом конфигурирование заканчивается, всё остальное сделает за нас 1С.

Разработка HTML страницы

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

После установки ISS (я уже давал ссылку в начале статьи) на диске C появится каталог C:\inetpub\wwwroot, в этом каталоге располагается сайт. Для локальной машины (на которой установили ISS) он виден так http://localhost/, ну а для пользователей извне, как-то так http://infostart.ru (по правде там немного сложнее, но не суть, мы сейчас не про это). Заглавная страница сайта будет грузиться из файла index.htm каталога C:\inetpub\wwwroot

 

Исходники файлов можно скачать здесь

Код файла index.htm попытаюсь объяснить как могу, т.к. сам некоторые моменты не понимаю:

[html xmlns="http://www.w3.org/1999/xhtml"] // Неважно. Используется в XHTML для объявления пространства имен.
[head] // Предназначен для хранения других элементов, цель которых — помочь браузеру в работе с данными.

[meta http-equiv="Content-Type" content="text/html; charset=utf-8" /] // Неважно.  Мета-теги используются для указания описания.

[title]Тест веб сервиса 1С[/title] // Неважно. Определяет заголовок документа, то что видит пользователь как текст вкладки.

[script type="text/javascript" src="../js/connect1c.js"] [/script] // Важно. Подключение JavaScript библиотек. В моём случае это мой модуль соединения с 1С.
[script type="text/javascript" src="../js/parameters.js"] [/script] // Важно. А это модуль обработки параметров строки браузера.

[/head]

[body] // Предназначен для хранения содержания веб-страницы (контента), отображаемого в окне браузера.
[p id="response1C"][/p] // Важно. Метка response1C, куда вернёться ответ запроса 1С.
[/body]

[script type="text/javascript"] // Важно. Начало основного скрипта, который выдёргивает из строки браузера всё что идёт дальше знака вопроса,
а дальше парсит по определенному алгоритму. В нашем случае будут искаться ключевые слова "user=" и "command=".

    user = GetParameter("user"); // Важно. Находим значение user. Сам метод GetParameter находится в библиотеке parameters.js, о которой поговорим чуть позже.
   
command = GetParameter("command"); // Важно. Находим значение command.

   
Inquiry1C(user, command); // Важно. Запрос к 1С с найденными параметрами. Сам метод Inquiry1C находится в библиотеке connect1c.js

[/script]

[/html]

*дико извиняюсь, & lt; и & gt; не работают (точнее работают, но после пересохранения они исчезают). Заменил < на [, а > - ]

Рассмотрим библиотеку parameters.js, которая находится в папке C:\inetpub\wwwroot\js

function GetParameter(pName) { // Сам метод я нашёл на просторах интернета.

   
search = window.location.search; // window.location - это по сути URL, метод search этого объекта возвращает часть адреса после символа "?", включая символ "?".

   
begin = search.indexOf(pName) + pName.length + 1; // Вычисляем позицию начала строки значения параметра для вырезания. +1 - в нашем случае это знак "=".
Итого, для search = "?user=007" мы найдём позицию начала равной 6 (нумерация с нуля).
    end = search.indexOf('&', begin); // Находим позицию конца выражения. В нашем случае, разделение параметров осуществляется знаком "&", и если мы его не найдём,
то позицией конца будет последний символ строки search (смотри дальше код).

    if (end == -1) {
        end = search.length;
    };

    return unescape(search.substring(begin, end)); // Метод unescape возвращает строку, содержащую данные типа charString (не знаю зачем это надо,
но видимо такое приведение типа здесь необходимо). Ну а метод substring - извлекает подстроку из строки.

}

Теперь рассмотрим библиотеку connect1c.js, которая также находится в папке C:\inetpub\wwwroot\js

function Inquiry1C(pUser, pCommand) { // Основной метод этой библиотеки. Запрос к 1С.

   
XMLHTTP = CreateRequestObject(); // Создание XML HTTP запроса. Сам метод я узнал из википедии.

   
XMLHTTP.open('POST', '../TestWeb/ws/Input.1cws', true, "Admin", "1"); // Создаём соединение типа POST, где второй параметр - адрес; параметр true - значит асинхронное,
то есть браузер не будет ждать ответа сервера, а продолжит работу; далее пользователь и пароль с правами на операцию InputData (этот тот метод, который мы написали в 1С),
саму операцию можно выполнять в привилегированном режиме, чтобы не мучиться с правами для пользователя Admin.

    XMLHTTP.onreadystatechange = function() {WhenAnswering1C(XMLHTTP)}; // Когда 1С отработает, автоматически сработает метод WhenAnswering (о нём чуть ниже по тексту этой библиотеки).

   
XMLHTTP.send(''
        + ' '
        + ' '
        + ''
        + pUser + ' '
        + ''
        + pCommand + ' '
        + ' '); // Отправка XML запроса, где описывается метод к исполнению в 1С, с переданными параметрами из нашей строки URL.
// Строку запроса можно раскурить минут за 5:)

}

function CreateRequestObject() { // Чудо метод из википедии "Пример использования". По сути, ничего сложного.
   
if (typeof XMLHttpRequest === 'undefined') {
        XMLHttpRequest = function() {
            try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); }
                catch(e) {}
            try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); }
                catch(e) {}
            try { return new ActiveXObject("Msxml2.XMLHTTP"); }
                catch(e) {}
            try { return new ActiveXObject("Microsoft.XMLHTTP"); }
                catch(e) {}
            throw new Error("This browser does not support XMLHttpRequest.");
        };
    }
    return new XMLHttpRequest();
}

function WhenAnswering1C(pXMLHTTP) { // Метод, который срабатывает после обработки запроса 1С.

   
status = StausRequest(pXMLHTTP); // Вычисляется статус для отправки сообщения пользователю (о нём чуть ниже).
   
document.getElementById("response1C").appendChild(document.createTextNode(status)); // Вывод на экран в помеченную область response1C (о ней я писал в основном файле).
Метод getElementById возвращает ссылку на узел документа.
Метод appendChild добавляет нод в конце списка дочерных нодов элемента, т.е. встраивает в нашу область нужный нам текст.

}


function StausRequest(pXMLHTTP) // Определение статуса.
{
    status = "";
    if (pXMLHTTP.readyState == 4) { // Опять же, читая википедию можно понять, readyState - это текущее состояние объекта (0 — не инициализирован, 1 — открыт,
2 — отправка данных, 3 — получение данных и 4 — данные загружены).
        if (pXMLHTTP.status != 200) { // status - HTTP-статус в виде числа (404 — «Not Found», 200 — «OK» и т. д.)
           
status = "Запрос завершился неудачно. Ответ сервера: " + pXMLHTTP.responseText; // responseText -текст ответа на запрос.
Если состояние не 3 или 4, возвращает пустую строку.
        }
        else {
            if (RequestSuccessful(pXMLHTTP)) { // Проверка ответа от 1С (о нём чуть ниже).
               
status = "Запрос отработан.";
            }
            else {
                status = "Запрос был отклонён.";
            };

        };
    };

    return status;
}

function RequestSuccessful(pXMLHTTP) { // Проверка ответа от 1С. Здесь мы получим возвращаемое от 1С значение (в нашем случае 1С может вернуть тип булево).

   
DOM = pXMLHTTP.responseXML.getElementsByTagName("return")[0]; // responseXML - Текст ответа на запрос в виде XML, который затем может быть обработан посредством DOM.
Если состояние не 4, возвращает null.
    response = DOM.childNodes[0].data; // Достаём данные из ответа.

   
return response == "true"; // Если правда, то правда:) По правде, я не смог преобразовать сроку в булево, поэтому пришлось оставить так.

}

Проверка

Открываем браузер и вводим строку "localhost/?user=007&command=hello world!":

После чего можно открыть 1С и убедиться что создался элемент справочника:

На этом пример ознакомления управления 1С извне можно считать законченным:)

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Алексей Верещагин (alexware) 10.10.12 05:11
Отличная статья! Только начинаю присматриваться к Web-сервисам - скоро, видимо, понадобится по работе. Очень хорошо написана, чудесные комментарии. Даже непосвященному всё понятно. Спасибо!
2. Борис Моренко (BorisMor) 10.10.12 05:51
Статья хорошая, но html и java-script не читаемые.
Может просто код выделить тегом <pre> ?
3. qwerty qwerty (las77) 10.10.12 06:00
добавлю в закладки. когда нибудь пригодится.
4. Vladimir87 Vladimir87 (Vladimir87) 10.10.12 06:16
Задача с точки зрения написания кода 1С очень легкая. Основная сложность заключалась в освоении HTML и JavaScript для управления извне.


А мне наоборот, web-программирование проще, чем 1с ). Но это так. А по статье - молодец. Ставлю плюс.
5. Иван Григорьев (Soloist) 10.10.12 08:46
(2) BorisMor, что-то так сразу не получается. Но думаю сами файлы улучшат ситуацию http://yadi.sk/d/jmg8ydss07Dey
BorisMor; +1 Ответить
6. ольга Катаева (oly86) 10.10.12 09:05
(3) las77, +1, тоже в закладки, полезная вещь, надо начинать осваивать
7. Игорь Сарафанов (ivs200999) 10.10.12 09:08
Любопытно, спасибо за статью.
8. Алексей Роза (DoctorRoza) 10.10.12 09:51
Плюс за содержание и оформление. Все бы так делали.
9. poyson (poyson) 10.10.12 10:11
Хорошая статья. подробная. спасибо.
10. Сергей (sstar90) 10.10.12 10:16
Нормалек, спасибо за статью
11. NPMar (NPMar) 10.10.12 10:25
Спасибо большое за статью! Очень хорошее и содержание и оформление. Даже "чайнику" всё понятно. Надеюсь, что пригодится в удаленной работе. Спасибо!
12. Яков Коган (Yashazz) 10.10.12 13:12
Несколько не понял, за что такие восторги человеку, который, по его же признанию, "сам многого не понимает", а часть статьи - самоочевидные вещи по публикации веб-сервисов. Автор, я б на твоём месте эту статью в рейтинге не считал.
13. absolutblohin (absolutblohin) 10.10.12 13:12
Как раз работаю над конфигурацией, в которой программисту ставятся задачи через письма. Попробую это как нибудь прикрутить. Автору спасибо.
14. Роман (Raminus) 10.10.12 13:17
Как ознакомление пойдет.
15. maksim.s (Gandalf Белый) 10.10.12 13:28
Большое спасибо! Очень интересная статья! думаю пригодиться. ))
16. Иван Григорьев (Soloist) 10.10.12 13:34
(12) Yashazz, со стороны кодинга и установки 1С - всё просто. Но для человека не знающего JavaScript дальнейшая реализация - это новый мир. Я не скрываю, что он легок для тех кто знает его. Я просто показал как я к этому шёл, и поверьте я был бы рад, если бы для меня это написали раньше, когда я задавал подобный вопрос на Мисте http://www.forum.mista.ru/topic.php?id=614454

Следующая статья будет более 1Сая.
17. LukoyanovAS (lukoyanovas) 10.10.12 14:56
(0) Что-то я не заметил, а где мы указываем под каким пользователем логинимся в 1С?
И еще, а что если полученную в результате ссылку мы нажмем 10000000 раз подряд (допустим в цикле)?
18. Иван Григорьев (Soloist) 10.10.12 15:06
1. "XMLHTTP.open('POST', '../TestWeb/ws/Input.1cws', true, "Admin", "1");" - здесь пользователь базы Admin с паролем 1;
2. В моём примере будет столько записей сколько раз перейдут по ссылке. Но не сложно отработать подобную ситуацию в 1С и предусмотреть под это событие нужную ветку.
19. Иван Григорьев (Soloist) 10.10.12 15:07
20. Алекс Ю (AlexO) 10.10.12 15:19
Я всегда знал, что 1С - навязана ИЗВНЕ.
Ничего человеческого :)
21. Андрей Гореликов (alon) 10.10.12 15:29
саму операцию можно выполнять в привилегированном режиме

А если еще в функции InputData использовать команду "Выполнить", то уже на следующий день можно увольняться. Хакеры камня на камне от базы не оставят.
iov; Kuzja_R; Трактор; +3 Ответить 1
22. Иван Григорьев (Soloist) 10.10.12 15:34
(21) alon,
..., чтобы не мучиться с правами для пользователя Admin

настройте тоньше и будет счастье.
24. Dimon (klel) 10.10.12 19:32
Самая что ни на несть отличная статья, даже не думал что такое можно сделать :) Огромное спасибо за статью обязательно возьму себе на вооружение =) ОГРОМНЫЙ "+"
25. Алексей (LelikOFF) 11.10.12 09:23
Интересная статья, нужно будет попробовать
26. UncleVader (UncleVader) 11.10.12 09:35
Я так понял данный метод будет работать только при условии удачного создания ActiveX-объекта, т.е. только на Win-платформе!?
27. Иван Григорьев (Soloist) 11.10.12 10:23
(26) UncleVader, если я правильно понимаю код метода CreateRequestObject(), то в блок использования ActiveX исполняемый код попадёт, если typeof XMLHttpRequest === 'undefined', а это возможно для IE версии 6 и ниже. Для всех остальных случаев будет работать строка "return new XMLHttpRequest();"
28. kiril lipatov (kilokilo) 11.10.12 14:35
Очень опасно без предварительной авторизации через web-сервисы создавать контент в БД.. разгребать потом замучаетесь - кто, что и когда.
На чтение - еще куда не шло, единственное - слишком частые запросы приведут к отказу от обслуживания (типа DDOS атаки).
А так - плюс за обмен опытом.
29. Angry (Angry) 12.10.12 14:48
(12) Yashazz, Вы не правы, человек описал на простом языке основы веб сервисов, за это он заслужил огромный +.
Но если Вы думаете, что сможете лучше, то дерзайте. Я думаю многие плюсовавшие будут благодарны и Вам если предоставите информацию, о том где есть информация о веб сервисах, доступная для программистов 1С. (именно для них этот ресурс).

А по теме: Иван молодец, я раньше пытался узнать, что это за зверь такой Веб сервис, но не смог выделить достаточно времени, потому просто забил, теперь есть возможность попробовать снова, потому: Спасибо и +.
30. Трактор Трактор (Трактор) 12.10.12 16:57
(29) Angry,
Я думаю многие плюсовавшие будут благодарны и Вам если предоставите информацию, о том где есть информация о веб сервисах, доступная для программистов 1С.

Уже 5 лет публикации http://infostart.ru/public/16001/ Она о том же что и эта.
Rustig; Soloist; +2 Ответить 2
31. Ростислав Кузьмин (Kuzja_R) 13.10.12 14:55
Заголовок "Передача команд 1С на выполнение через ссылки в письме." совершенно не соответствует содержанию. Тонкий маркетинговый ход?
32. Иван Григорьев (Soloist) 15.10.12 07:50
(30) Трактор, ваша статья мне очень помогла, для развитии этой идеи. Извиняюсь, что забыл добавить в публикацию. Исправил.
33. Иван Григорьев (Soloist) 15.10.12 07:50
34. nataon (nataon) 23.10.12 15:01
Хорошая статья, спасибо
35. Александр Притуленко (evrakylon) 08.12.12 10:54
Спасибо за статью. Осталось не ясным следующий момент. Вот строка HTTP запроса

XMLHTTP.open('POST', '../TestWeb/ws/Input.1cws', true, "Admin", "1");

Веб сервис публикуется из 1С 8.2, значит файла Input.1cws нет, а данные об alias указываются в default.vrd, например в разделе <ws>. Что означает в данном случае путь (или адрес) '../TestWeb/ws/Input.1cws'? На скрине видна папка TestWeb - что в ней?
Спасибо!
36. Анатолий Бурмистров (tolik_byr) 08.12.12 22:01
Интересно, но какие-либо мыслей по явному применению у кого-нибудь есть?
37. Иван Григорьев (Soloist) 11.12.12 10:52
(35) evrakylon, я думаю что это адрес. В папке TestWeb два файла default.vrd и web.config. В файле default.vrd прописан наш web-сервис вот так:
<ws>
<point name="Input"
alias="input.1cws"/>
</ws>
38. Александр Притуленко (evrakylon) 11.12.12 12:40
1. При вводе в браузер http://localhost/preved/ws/preved.1cws?wsdl открывается корректное описание
2. При вводе http://localhost/preved запускается web-клиент 1С
Тут корректно, мало того я подключаюсь к вебсервису из другой 1С.
Далее, в папке C:\inetpub\wwwroot\preved есть файл default.vrd
<ws>
<point name="preved"
alias="preved.1cws"/>
</ws>

Какой же путь тут должен быть XMLHTTP.open('POST', '???', true, "Admin", "1");
и где правильно расположить файлы HTM и JS?
39. Иван Григорьев (Soloist) 12.12.12 11:17
(38) evrakylon,
"Какой же путь тут должен быть XMLHTTP.open('POST', '???', true, "Admin", "1"); "
я думаю '../preved/ws/preved.1cws'. Может зависит от платформы... у меня на одной из 8.3.1 точно не выполнялось (может даже есть одна 8.2 на которой не выполняется). Сейчас стоит 8.3.2.172 и IIS 8, путь такой, какой я написал.

"и где правильно расположить файлы HTM и JS?"
в принципе где угодно, важна ведь строчка подключения этой библиотеки. Путь к файлам js я прописывал в самом начале
<script type="text/javascript" src="../js/parameters.js"> </script>
40. Иванов Иван (x2z7yy) 24.01.13 08:35
XMLHTTP.send(''
+ ' '
+ ' '
+ ''
+ pUser + ' '
+ ''
+ pCommand + ' '
+ ' ');


Не пойму, так и надо чтоли писать? Или вместо пробелов что-то должно быть?
41. Иван Григорьев (Soloist) 24.01.13 15:14
(40) x2z7yy, извиняюсь, это infostart пожрал код, возьмите его отсюда http://yadi.sk/d/jmg8ydss07Dey
42. Иванов Иван (x2z7yy) 24.01.13 15:41
(41) Soloist, спасибо, сейчас буду пробовать дальше.
43. Сергей Кудашкин (sikuda) 15.02.13 14:51
Хорошая статья, но как из прошлой жизни:
XMLHttpRequest = function() {
try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); }
catch(e) {}
try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); }
catch(e) {}
try { return new ActiveXObject("Msxml2.XMLHTTP"); }
catch(e) {}
try { return new ActiveXObject("Microsoft.XMLHTTP"); }
catch(e) {}
throw new Error("This browser does not support XMLHttpRequest.");
};
Я развил эту идею http://infostart.ru/public/167093/
44. Иван Григорьев (Soloist) 18.02.13 07:53
45. Алексей Писаренко (300hp) 11.04.13 14:27
(41) Soloist, привет! где еще можно посмотреть что там за код съел infostart?
46. Иван Григорьев (Soloist) 16.04.13 08:18
(45) 300hp, вот здесь все исходники http://yadi.sk/d/jmg8ydss07Dey. Сейчас статью обновлю
47. Михаил Болсун (m.bolsun) 17.04.13 11:15
ставлю + т.к. люблю всякие вещи, такого рода. У самого есть пара прототипов работы с вебсервисами из самой 1с, но мне не подходит изменение конфигурации, поэтому использую HTTPСоединение.
Тут однозначно необходимо решить вопросы с безопасностью и имхо, возможно стоит поменять направление запросов, т.е. к 1с никто не соединяется, а сама 1с цепляется через SSL соединение, к какому-нибудь доверенному безопасному серверу, где ее уже ждет очередь команд. Как то так.
48. Иван Григорьев (Soloist) 17.04.13 11:48
49. Юрий Лазаренко (TitanLuchs) 17.04.13 12:20
Веб-сервисы и не на это способны на самом деле ) Но минус у них есть - при большом потоке запросов имеют свойство отваливаться...
50. Мария Мария (mary61) 18.04.13 11:46
Большой +. В будущем пригодится
51. Степан S (Ed111111) 19.05.13 23:14
Не понял, для чего это нужно?
52. Иван Григорьев (Soloist) 20.05.13 07:58
(51) Ed111111, ради фана. Ну и приятно же не открывая 1С выполнить действие в базе, имея лишь исполняемую ссылку, которую тебе прислали.
53. Serg S (mdSerg) 21.05.13 13:38
(30) Трактор, только её не скачать
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа