Меня зовут Михаил Пинягин, я руководитель компании Айтон, мы партнеры 1С уже 15 лет.
В прошлом я руководил службой информационных технологий представительства итальянской промышленной группы ALPI.
Расскажу, как я пришел в ИТ. В свое время я учился в художественной школе, рисовал, мне хотелось рисовать мультики. Казалось бы, как связаны мультики и информационные технологии? Но мультики я решил рисовать на компьютере, с помощью 3D-моделирования, а 3D-моделирование и компьютерная анимация без программирования ничто, поэтому мне пришлось погрузиться в программирование.
Поскольку я начал заниматься графикой, то естественно у меня в конце 90-х – начале 2000 гг. начали появляться заказы по разработке сайтов. Я стал специалистом по 1С-Битрикс, и наша компания некоторое время занималась разработкой сайтов.
А где сайты, там интернет-магазины, где интернет-магазины, там, естественно, учетная система. И потихоньку мы отошли от сайтов, начали заниматься просто учетными системами, и сейчас интеграция учетных систем с сайтами – это наше все.
Зачем встраивать 1С на сайт
По какой причине может понадобиться встроить 1С на сайт:
-
Это может быть нужно руководителям:
-
например, для формирования отчетов на корпоративном портале из учетной системы – причем, если стандартный веб-клиент может работать с одной базой, то в сайт можно встроить сразу несколько веб-клиентов, которые могут показывать графики или отчеты из разных учетных систем.
-
-
Это может быть нужно сотрудникам. Например, можно вывести на сайт функциональность какой-то внешней CRM-системы:
-
чтобы сотрудник мог выставить счет;
-
или проконтролировать дебиторку.
-
-
Это может понадобиться для внешних пользователей:
-
чтобы оформить самостоятельный заказ товаров через личный кабинет;
-
или посмотреть состояние расчетов, баланс лицевого счета
-
Понятно, что кейсы бывают абсолютно разные, и реализация возможна разная.
Как встроить 1С на сайт: варианты
Например, встроить 1С на сайт можно с помощью технологии oData.
-
на стороне 1С мы настраиваем доступ к данным по oData;
-
а на стороне сайта программируем какую-то логику, чтобы данные как-то получить, визуализировать, обработать, а если необходимо, еще и реагировать на нажатие, записывать их.
Какие минусы у этого подхода?
-
Во-первых, сам oData сложный достаточно и громоздкий, если не использовать какие-то обертки, которые есть на рынке. Те, кто работал с oData, знают, что ссылки там в виде идентификаторов, и чтобы достать, например, наименование контрагента, необходимо еще и обратиться к таблице контрагентов. То есть это сложная штука.
-
Кроме того, вся разработка по взаимодействию с механизмом oData ведется на стороне сайта, вне платформы 1С. Для кого-то это плюс, для кого-то это минус. Я написал, что это минус, потому что мы – разработчики на платформе 1С, и иногда некоторые разработчики не знают других языков, для них это непреодолимый барьер.
Среди плюсов:
-
oData – универсальная штука, и она не требует изменений конфигурации. В итоге мы можем просто написать на каком-то языке необходимую логику – обратиться, визуализировать, и это хорошо.
Следующий вариант, как можно встроить 1С на сайт, – использовать какой-то веб- или http-сервис.
-
Опять же на стороне 1С программируем какую-то логику запросов и реакцию на них.
-
На стороне сайта мы программируем обращение к этим сервисам, визуализируем данные.
Какие есть минусы:
-
требуется разработка как в рамках платформы 1С, так и на сайте.
Но есть и плюс:
-
полная свобода действий – мы сами определяем протокол, сами можем указать, какие данные хотим получать, какие данные хотим отправлять, и т.д.
Еще один вариант, как можно встроить 1С на сайт, – сделать периодическую выгрузку/загрузку данных. Это классика жанра.
-
На стороне 1С мы программируем или настраиваем выгрузку/загрузку данных в необходимом формате (xml, xls или картинки просто выгружаем и т.д.).
-
На стороне сайта это визуализируем.
Но опять-таки минусы:
-
требуется разработка как в рамках платформы 1С, так и на сайте;
-
это будет не онлайн-обмен.
Почему я говорю, что вариант периодической выгрузки/загрузки – это классика жанра. Потому что, например, все обмены с тем же Битриксом построены по этой технологии. Т.е. на стороне 1С у нас что-то куда-то выгружается, а сайт это загружает.
Мы в свое время делали проект, когда 1С просто выплевывал картинки в виде графиков, а на сайте руководители смотрели эти графики. Не было какого-то онлайн обмена, но такая работа велась.
Следующий вариант, как можно реализовать такое взаимодействие с сайтом, – в самом браузере открыть веб-клиент 1С. Об этом я буду дальше говорить.
Эта возможность появилась очень давно. Например, до версии 8.3.10 это можно было сделать так, как показано на слайде:
Страницу встраиваем в iframe, в котором прописываем путь к нашей базе, устанавливаем размеры этого iframe. В итоге у нас открывается страница браузера.
Дальше было много возможностей:
-
мы могли опубликовать базу таким образом, чтобы там каким-то образом проходила аутентификация;
-
можно было нарисовать на клиенте свой интерфейс 1С, где был доступ только к нужным функциям.
Но были проблемы:
-
окно загружалось полностью – сверху выводится системное меню со всеми кнопками, и их нельзя было спрятать.
В платформе версии 8.3.10 появились режимы основного окна. Например, можно было указать в строке запуска параметр MainWindowMode=Workplace, у нас прятались некоторые элементы, но заголовок окна все равно оставался.
В 8.3.10 мы с помощью навигационных ссылок могли даже открывать необходимую форму.
Например, мы указываем, что нужно открыть оборотно-сальдовую ведомость, и у нас, когда мы запускаем страницу, открывается оборотно-сальдовая ведомость.
В версии 8.3.16 появилось много интересных плюшек, о которых я расскажу. До нее были следующие проблемы:
-
Внешний сайт, куда мы встраиваем веб-клиент, ничего «не знал» о том, что делает пользователь в 1С. Т.е. запустили iframe, пользователь что-то делает в 1С, но внешний сайт никак не реагирует на это. Я сейчас имею в виду типовые возможности, а не какие-то дополнительные возможности, которые можно было в принципе реализовать при программировании.
-
1С также «не знала», что происходит на внешнем сайте. Например, у нас есть какие-то кнопки, ссылки на сайте, мы их нажимаем, но 1С не знает, что происходит на внешнем сайте.
-
Режимы основного окна отображали системную командную панель, которая не очень удобна и не нужна в принципе, если мы встроили 1С в страницу.
Что сделали разработчики 1С в 8.3.16?
-
Они создали JavaScript-интерфейс веб-клиента, который позволяет:
-
запустить веб-клиент в указанном элементе div с необходимыми параметрами;
-
выполнить переход веб-клиента по навигационной ссылке;
-
отправить сообщение веб-клиенту;
-
подписаться на события, которые происходят в веб-клиенте: когда человек нажимает какие-то кнопки, мы можем эти события отлавливать.
-
-
В новой версии появился новый режим основного окна – EmbeddedWorkplace (встроенное рабочее место).
-
Также появилось свойство ОкноВнешнегоСайта в 1С, с помощью которого мы можем:
-
проверить доступность внешнего сайта – если ОкноВнешнегоСайта доступно, значит, мы запустили клиент 1С внутри сайта;
-
подписаться на сообщения сайта для их обработки (теперь можно реализовать, что 1С реагирует, если на сайте мы нажимаем какие-то кнопки, делаем какие-то действия);
-
отправлять сообщения сайту.
-
Встраивание веб-клиента на сайт
Давайте посмотрим, как все это работает.
Первое, что мы делаем, – загружаем JavaScript-интерфейс в виде
<script src=”%АдресВебСайта%/%ИмяИБ%/scripts/webclient1ce.js”></script>
Естественно, база должна быть опубликована по соответствующему адресу на веб-сервере.
Следующий шаг – мы создаем непосредственно элемент, куда мы будем встраивать наш веб-клиент.
Например, это будет пустой div с идентификатором container.
Далее мы пишем скрипт, в котором:
-
создадим переменную, допустим, webClient – чуть ниже мы этой переменной присвоим значение, новый объект WebClient1CE().
-
Затем создадим функцию init(). В данном случае, функция init() загружает веб-клиент с определенными параметрами в div с id=“container”.
Эту функцию init мы вызываем при загрузке страницы.
Я показываю только общий принцип работы. У меня не будет живых примеров реализации какой-то конкретной практической задачи.
Я считаю, что разработчики, зная определенные математические принципы, могут сами применять их в жизни – мы сами придумываем себе способы, как их использовать. Поэтому реализация, естественно, может быть разной.
Если мы это реализуем, что будет происходить?
Мы запустили страничку, обратились к адресу, где у нас размещен скрипт, у нас отобразился сайт и внутри отобразился веб-клиент.
Как видите, при указании минимального количества параметров никакой разницы между тем, как было в версии 8.3.10, нет.
Поэтому следующее, что мы сделаем, – пропишем режим основного окна EmbeddedWorkplace и посмотрим, как теперь будет работать.
Что дает этот новый режим?
-
Сверху пропало системное меню, которое и так не нужно.
-
Внизу появляется надпись «Работает на 1С». Фирма 1С свой бренд всегда продвигает, поэтому даже если мы убрали все ненужное, то момент, что система работает на 1С, мы оставляем.
Конструктор объекта WebClient1CE и возможности по его настройке
Давайте подробнее рассмотрим, какие возможности нам дает объект WebClient1CE, и зачем все это было сделано.
У конструктора new WebClient1CE, который мы вызываем при создании веб-клиента 1С на странице сайта, есть два параметра.
-
webClientContainerID – в нем мы указываем идентификатор того div-а, куда встраивается наш веб-клиент.
-
config – объект, в котором мы указываем некоторые свойства нашего веб-клиента.
-
Первое свойство – обязательное, это путь к опубликованной базе. Вы в примере видели, что путь к опубликованной базе может содержать в себе параметры запуска, в том числе, логин и пароль. Конечно, так делать ни в коем случае нельзя, но вы можете пользоваться стандартными параметрами запуска клиента 1С.
-
Со свойствами – ширина и высота div-а – все понятно.
-
Следующее, наверное, самое интересное – это объект events, который содержит в себе подписки на события. Подписки могут быть такие: onStart, onEnd, onMessage, onFormOpen и onFormClose.
-
Посмотрим, как работает.
Подписка на событие onStart
Модернизируем наш пример, добавим объект events, подпишемся на onStart и укажем, что будет вызываться функция onStart1С, и пропишем в этой функции, что при старте 1С фон сайта должен стать красным.
Запускаем страницу, авторизуемся.
После авторизации, когда у нас завершилась процедура ПриНачалеРаботыСистемы, фон сайта стал красным.
Этот пример слишком простой – вы вряд ли будете перекрашивать цвет сайта.
Но эта подписка может пригодиться в случае, когда мы при запуске клиента не хотим, чтобы у нас при этом появлялась заставка с «1С:Предприятие 8.3» – мы можем div в это время прятать, не показывать до тех пор, пока 1С-клиент не запустился. И только после этого div будет отображаться.
Конечно, это применимо только в том случае, если у нас авторизация сделана не через логин и пароль, а каким-то другим образом.
Подписка на событие onEnd
Также можно подписаться на событие onEnd. Подписка onEnd работает аналогично onStart, то есть вызывается перед завершением работы веб-клиента, после процедуры ПриЗавершенииРаботыСистемы.
Прописываем, что при завершении работы системы будет вызываться функция onEnd1С, которая раскрасит сайт в аквамарин.
Как это будет выглядеть? Я нажимаю «Завершить работу веб-клиента».
И после выхода из 1С у меня перекрасилась страница.
Если практический пример брать, мы можем, к примеру, переадресовывать страницу куда-то, прятать это окно или рисовать какие-то кнопки.
Подписки на события onFormOpen и onFormClose
События onFormOpen и onFormClose очень похожи друг на друга, потому что параметры у них абсолютно одинаковые:
-
onFormOpen вызывается после события ПриОткрытии формы;
-
onFormClose вызывается после события ПриЗакрытии формы.
У них два параметра, к ним приходят:
-
url – навигационная ссылка;
-
formName – имя открываемой формы для английского варианта языка.
Давайте посмотрим, как это работает. У меня пример будет только на onFormOpen, потому что на onFormClose он аналогичный.
Итак, мы подписываемся на событие onFormOpen, и вызываем функцию, где в div с идентификатором messageArea пишем текст «Открыта форма:» и вставим имя формы.
Посмотрим, что получается. У нас открылся веб-клиент, открывается форма с именем «Форма» обработки «Текущие дела» и форма с именем «Форма».
Как это использовать на практике? Представьте, что открывается веб-клиент 1С, и пользователь открывает в нем какие-то отчеты, списки документов или сами документы. Зная, какие списки и формы человек открывает, мы можем перерисовывать интерфейс страницы, вставлять какие-то контекстные кнопки, выводить какие-то сообщения.
Подписка на событие onMessage
Еще одно событие, наверное, самое главное событие – это onMessage.
Здесь указывается функция обработки сообщения, отправленного веб-клиентом из 1С с помощью ОкноВнешнегоСайта.ОтправитьСообщение.
У обработчика этого события есть параметры:
-
message – это текст сообщения, строка.
-
origin – основной адрес веб-клиента, строка, которая включает в себя протокол, домен и порт.
Реализуем пример.
На стороне 1С на какой-нибудь форме вызовем процедуру ОтправитьСообщение, где в случае, если у нас доступно ОкноВнешнегоСайта, создадим СообщениеВнешнемуСайту.
На слайде конструктор, который используется для создания объекта СообщениеВнешнемуСайту. Допустим, внешнему сайту мы отправляем сообщение «Hello World!».
Что мы делаем теперь на стороне сайта? Подписываемся на событие onMessage, и в области с идентификатором messageArea я буду выводить надпись «Получено сообщение:» и текст сообщения.
Посмотрим, как это работает. Нажимаем кнопочку «Отправить сообщение», у нас веб-клиент получает сообщение и в соответствии с тем, что у нас написано в скрипте, отрабатывает свою логику.
В данном случае он пишет: «Получено сообщение: Hello World!».
Я вам показал самый простой пример. Но мы можем сделать примеры гораздо сложнее: можем разработать собственный протокол общения, текст может содержать не какое-то сообщение, которое сайт выводит, а могут какие-то данные отправляться.
Допустим, менеджер создает заказ, нажимает кнопочку «Провести и закрыть», в этот момент 1С отправляет сообщение с информацией о сумме заказа, номере, дате. А потом, например, внешняя CRM-система получает эту информацию и уже по своей логике ее отрабатывает, к примеру, записывает в сделку или в лид информацию о том, что выставлен такой-то счет или создан такой-то заказ.
Идея очень простая – на простом примере, который я показал, мы можем реализовать протокол общения между сайтом и 1С.
Метод postMessage объекта WebClient1CE
У нашего объекта WebClient1CE есть ряд методов. Первый метод, который мы рассмотрим – это postMessage, с его помощью уже внешний сайт может отправить 1С свое сообщение.
Мы можем при нажатии кнопки отправить сообщение 1С, и уже опубликованная база, с помощью процедуры, которая подключается с помощью ОкноВнешнегоСайта.ПодключитьОбработчикСообщений, подписывается на событие, получает сообщение и что-то делает.
Посмотрим, как это работает.
Для примера я создал расширение, но реализация может быть абсолютно разной.
Мы в обработчике ПриНачалеРаботыСистемы проверяем, что у нас 1С запущена внутри сайта, и, если это так, мы в ОкноВнешнегоСайта подключаем обработчик сообщений и указываем имя процедуры, которая будет выполняться.
Процедура, которая будет выполняться у меня прописана в модуле ИС_ИнтеграцияКлиент, но это не так важно. Главное – мы подключили обработчик сообщений.
Этот обработчик сообщений у нас очень простой – мы сейчас не будем придумывать логику общения между сайтом и 1С, мы просто получаем данные сообщения и просто выводим текст на клиенте методом Сообщить().
Затем мы на сайте добавили кнопку с обработчиком webClient.postMessage («Данные с сайта») – при ее нажатии у нас будет выполняться данный метод.
Как это работает? Мы открыли сайт, нажали кнопку «Отправить сообщение», и появилось сообщение «Данные с сайта», т.е. 1С его получила и выполнила ту логику, которая у нас запрограммирована.
Метод gotoURL объекта WebClient1CE
Следующий метод, который есть в объекте WebClient1CE, – это gotoURL. В качестве параметра этого метода мы указываем стандартную навигационную ссылку. Это, по сути, аналог ПерейтиПоНавигационнойСсылке на встроенном языке 1С.
Рисуем кнопочку webClient.gotoURL и прописываем навигационную ссылку. В данном случае я буду открывать отчет «Динамика поступления денег».
Мы нажимаем на сайте нашу кнопочку «Открыть отчет», у нас во встроенном клиенте открывается отчет.
Обратите внимание, мы можем на стороне 1С ограничить доступность кнопки закрытия формы – например, нажали «Открыть отчет», у нас может открыться форма, но наверху кнопок может не быть. Можно сделать управление окнами только через сайт, чтобы не закрывать окна, например, в 1С.
Итог
Если подводить итог:
-
С версии 8.3.16 у нас появилась возможность тесно интегрировать 1С и сайт.
-
Мы можем с помощью обмена сообщений сделать так, что сайт будет знать, что происходит в 1С, а 1С будет знать, что делает пользователь на сайте.
-
Естественно, нужно разрабатывать свой протокол общения. Примеры, которые я показывал, достаточно простые, но при выполнении реальных задач на проектах протокол общения может быть очень сложным.
-
Но с помощью событий запуска веб-клиента, открытия и закрытия форм вы можете теперь определять контекстную видимость элементов сайта, оформление менять и т.д. Все это достаточно легко и просто делается.
Единственный минус, который есть в таком решении – когда мы с помощью oData или веб-сервисов обращаемся к 1С и визуализируем данные, они не занимают лицензию. А в случае встраивания происходит полноценный запуск веб-клиента, и веб-клиент занимает лицензию. Поэтому если вы на страницу сайта внедрили несколько окон, которые запускают разные графики из разных баз, то учтите, что у вас могут быть заняты лицензии.
Вопросы
Что будет, если мы на одной странице отображаем отчет по деньгам для директора из одной базы, и рядом показываем отчет по продажам из другой базы. В таком случае мы попадаем на две лицензии?
Количество лицензий будет зависеть от количества запущенных веб-клиентов, т.е. будет потрачено две лицензии.
Вы прорабатывали вопрос авторизации средствами сайта? Возможно ли авторизоваться не в окне 1С?
Тут вариантов очень много – все зависит от того, чего мы хотим. Есть возможность авторизоваться через OpenID, можно базу опубликовать определенным образом, просто запускать веб-клиент с определенными параметрами… Это тема отдельного выступления.
То есть можно использовать все способы стандартной авторизации веб-клиента?
Да, сайт просто запускает веб-клиент через определенную обёртку, но авторизоваться в нем мы можем разными способами.
Когда вы передавали информацию из 1С на сайт вы в этих сообщениях передавали строки. А что-то, кроме строки, можно передать?
Только строки. Если вы обратили внимание, когда мы отправляем сообщения, у нас есть объект, который называется СообщениеВнешнемуСайту. Это целый объект, у которого есть конструктор, но внутрь мы все равно вставляем текст. И непонятно, почему сделан специальный конструктор, почему не сделать просто ОкноВнешнегоСайта.ОтправитьСообщение, а внутри текст. У меня предположение, что все-таки у разработчиков 1С были какие-то планы расширить эту возможность. Потому что практика показывает, что даже если взять систему взаимодействия, там тоже все менялось: раньше можно было передавать только строки сообщений, сейчас уже больше различных типов передавать. Поэтому надеюсь, что возможно когда-то что-то будет добавлено. Но пока только текст.
Есть ли ограничение на размер передаваемых строк? И можно ли передавать сериализованные объекты?
Передавать можно только строки, но как мы их дальше разберем – это уже вопрос взаимодействия, это уже сам разработчик будет свою логику делать. Т.е. можно передать все, что угодно. Это может быть xml, json и все, что угодно. Дальше уже разработчик обрабатывает сообщение. По поводу размера могу ошибаться, не было экспериментов. Но, по-моему, это ограничено только настройкой максимального размера передаваемого сообщения для веб-сервера.
Здесь вопрос в каком-то прикладном решении. Мы никогда не передавали большие данные – у нас и не было такой задачи, мы же не будем картинки передавать с клиента на сайт, практического смысла в этом я просто не вижу. Чтобы картинку передавать, надо как-то кодировать, декодировать. Чаще всего передается какая-то краткая информация – цифры, тексты. Допустим, клиент создал заказ, мы передаем информацию типа суммы, даты, количества товаров, их наименований или артикулы, какие-то практические вещи. И они обычно занимают очень мало места.
Если речь идет о том, как передать массив, структуру и т.д., это все заворачивается в JSON. По сути, это строка. Передаем ее сайту, а сайт ее замечательно декодирует.
А если у нас есть необходимость передать большой объем информации, то нет смысла его класть в сообщение. Правильнее было бы отправить сообщение, что для есть какая-то информация, которую можно взять по такому-то адресу. И не важно, кто эту информацию дает, – сайт 1С-ке или 1С-ка сайту. И тогда уже или сайт через http-запрос идет к 1С и берет там неограниченное количество данных, или наоборот – 1С идет на сайт и ее берет.
Еще один вопрос – как открыть в окне встроенного веб-клиента отдельный отчет?
Вариантов очень много. Можно прописать открытие определенной навигационной ссылки. Или, допустим, мы можем на стороне 1С в процедуре ПриНачалеРаботыСистемы анализировать, кто у нас зашел в систему, и в случае, если это запущено с внешнего сайта, просто открывать форму или отчет. Классика жанра, не нужно ничего придумывать.
*************
Данная статья написана по итогам доклада (видео), прочитанного на онлайн-митапе "Web-клиенты для 1С".