Очередная попытка взаимодействия с JavaScript из клиента 1С. Расширение "Подключаемые Скрипты"

Публикация № 1259487

Разработка - Системная интеграция - Интеграция с WEB

JavaScript WebKit

Хотелось бы поделиться своими наработками в части использования возможностей HTML + JS из клиента 1С. Показанная в статье идея будет интересна тем, кто использует карты Yandex... или ещё какие-нибудь HTML извращения в конфигурациях 1С. Тестировал подход в тонком клиенте на версии платформы 8.3.18.1289, но должно работать на любой 8.3.14+ (движок webkit).

Сразу прошу прощения за не самую лёгкую подачу информации - мне всегда сложно давалось написание текста. Просто хотелось поделиться своими идеями.

Я думаю, все со мной согласятся, что для решения почти любой бизнес-задачи возможностей экосистемы 1С Предприятие более чем достаточно. Однако, изредка, могут появиться особо требовательные к интерфейсу заказчики, которым кровь из носу надо кликать по карте и автоматически заполнять данные адреса в карточке контрагента и тд. К сожалению для реализации таких требований приходится плясать с бубном вокруг нового типа "ВнешнийОбъект". Как потом отлаживать и поддерживать решения, написанные наполовину на javascrу я вообще молчу . В результате таких плясок и родилась идея написания подсистемы, которая позволит реализовать бОльшую часть логики на 1С, где будет легко её отлаживать, расширять и поддерживать. В статье изложу основную идею, и приложу первую версию моей подсистемы. Конечно там ещё много чего надо сделать и имеется куча идей куда можно развиваться. Итак, приступим.

Для начала необходимо реализовать возможность вызова функции eval из контекста 1C, так как она в ПолеHTML изначально не работает. При этом eval доступна при вызове из javascript. Это открывает перед нами возможность перехитрить платформу и переопределить вызов функции.

Для добавления скриптов к документу ХТМЛ я использую событие формы "ПриСозданииНаСервере". Добавим к нашему ХТМЛ документу тег SCRIPT в котором переопредели вызов функции eval так, чтобы он стал доступен из 1С.

Перед подключение дополнительных скриптов к html документу надо учесть следующее ограничение:

  • Реквизит поля ХТМЛ должен содержать текст HTML документа, а не  адрес расположения страницы (чтобы мы могли программно изменить DOM модель документа и подключить дополнительные файлы скриптов). Идея с добавлением тега script с помощью вызова функций addChild у меня почему-то не сработала. Видимо WebKit не выполняет скрипты, если они были добавлены после загрузки страницы. А без возможность вызова функции eval мы не можем добавлять свои функции в контекст js динамически. Получается замкнутый круг.
 
 Переопределим вызов функции eval:

Теперь нам доступно выполнение произвольного кода javascript из 1С. Для примера вычисление суммы с помощью функции eval:

 
 Пример вычисления суммы:

Вызов javascript из 1С мы реализовали. Теперь надо реализовать вызов кода 1С из javascript. Данные из JS можно передать в 1С, если перехватывать событие элемента формы "ПриНажатии". Для этого добавим функцию вызова 1С из контекста JS.

 
 Вызов события "ПриНажатии" с передачей произвольных данных

 

Таким образом мы заложили основу. Имея возможность выполнять произвольный код JS и перехватывать события - мы можем реализовать любую логику в коде 1С. Несомненным плюсом является нормальная отладка решения в контексте 1С, без необходимости использовать отладчик WebKit (который частенько роняет платформу). Однако для реализации сложной логики придётся добавить кучу новых событий и их обработчиков, в итоге получится не самый простой и читаемый код.

Я же хотел сделать универсальный программный интерфейс в 1С, который позволит практически без использования кода на JS создавать решения с HTML интерфейсом.

Моя основная идея заключается в использовании системы событий javascript (addEventListener), в связке с использованием объектов 1С "ОписаниеОповещения". Для этого необходимо выполнить следующую последовательность действий:

  1. создать описание оповещения с присвоением ему уникального идентификатора.
  2. "Закешировать" в клиентской переменной идентификатор и обработчик оповещения (в моей подсистеме я использую глобальную клиентскую переменную, но можно использовать и переменную на форме).
  3. создать обработчик события на элементе DOM модели документа, и присвоить ему обработчик, который будет вызывать функцию sendEvent и передавать в данные события идентификатор конкретного описания оповещения.
  4. Реализовать обработчик, на стороне 1С для события документа "ПриНажатии", который по идентификатору обработчика оповещения найдёт в клиентском Кеше и вызовет обработчик 1С, передав в него данные события JS.

Плюсы такого подхода очевидны - почти вся логика реализуется кодом 1С, решение легко поддаётся отладке и его намного проще расширять и дорабатывать при необходимости. Не затрагивая при этом основной блок взаимодействия 1C <-> JS.

Сам проект доступен в репозитории на github. Буду рад, если кто-то захочет помочь в развитии, так как сам не особо шарю в javascript, да и свободного времени не столь много.

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

В подсистему включён макет, добавляющий функции js. Сейчас реализовано:

  1. функция Eval, предоставляющая доступ к вызову функции eval и возвращающая объект с результатом выполнения или описанием ошибки.
  2. переопределение прототипа функций addEventListener и removeEventListener, для возможности получения списка активных подписок на события по каждому элементу DOM модели документа.
  3. добавлен объект, для управления текущими интервалами и таймаутами, с возможностью получения списка обработчиков. (setTimeout и setInterval).
  4. функции, для исследования объектов, переданных в метод (можно передавать объекты типа ВнешнийОбъект и получать структуру всех методов , свойств и итераторов объекта).
  5. функции, для вызова события элемента формы "ПриНажатии" с передачей особых управляющих событий. Сейчас реализованы события 
    • message1C(вызывает функцию 1С Сообщить в контексте текущей формы, позволяет показывать сообщения из кода js)
    • error1C(вызывает исключение с текстом, переданным из js)
    • log1C(производить запись в журнал регистрации из js)
    • callback1C(вызывает определённый обработчик оповещения в 1С по сохранённому идентификатору). Реализует основную идею моей подсистемы.
  6. функция, позволяющая вызывать у объекта с типом ВнешнийОбъект любой метод по имени с передачей произвольного количества параметров. Параметры также могут представлять из себя Внешние Объекты (например ссылки на другие функции).
  7. Функция, позволяющая прочитать текущее свойство внешнего объекта по имени. По сути вызов функции идентичен получению значения свойства из ВнешнегоОбъекта через точку, но есть подозрение, что js выполняется в отдельных потоках и не привязан к основному потоку выполнения клиента 1С. А значит текущее значение в поле внешнего объекта может отличаться от реального...Но это не точно.. возможно 1С реализовали опрос текущего значения свойства внешнего объекта каждый раз при обращении, так как по сути внешний объект является ссылкой на конкретный объект JS и вполне реально при каждом обращении к его свойствам зачитывать текущее состояние из js.

Для кеширования обработчиков оповещения используется глобальная клиентская переменная. Хранения данных в ней реализовано в разрезе конкретной формы и поля с типом ДокументHTML. Тоесть в случае использования нескольких форм у нас сохранённые данные не перемешаются.

Чтобы использовать возможности расширения в своих разработках достаточно на форме при создании на сервере вызвать метод расширения ПодключитьРасширенныеСкрипты (чтобы изменить документ HTML и 1С его перезагрузила, тем самым выполнив наши подключаемые скрипты - надо делать это с сервера).

 
 Примеры использования расширения:

Ну и на сладенькое - Реализация обмена с 1С через WebSocket в пару строк:

 
 Обмен через WebSocket:

 

Ну вот и всё, что на данный момент реализовано.

В планах на будущее:

  • Реализация справочника "Подключаемые библиотеки", который позволит сохранять внешние библиотеки JS и CSS. Типа Amcharts, Bootstrap и тд..
  • Доработка программного интерфейса, для подключения внешних библиотек в конкретным формам и полям HTML.
  • Реализация обработки для настройки способов подключения файлов, указание порядка загрузки файлов. Настройка места подключения - в header или в теле документа.
  • ну и на самую далёкую перспективу - реализация конструктора html, для создания интерфейса в самой 1С, визуальная настройка, привязка обработчиков и событий элементов DOM модели js к именам обработчиков 1С - думаю по имени модуля и имени процедуры обработчика. Как будут настраиваться дополнительные параметры при создании описания оповещения пока не придумал... (сейчас довольно призрачное представление, как всё это будет выглядеть).

Скачать файлы

Наименование Файл Версия Размер
Расширение "Подключаемые Скрипты"

.cfe 36,01Kb
12
.cfe 36,01Kb 12 Скачать

Специальные предложения

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. John_d 2976 10.02.21 09:47 Сейчас в теме
за статью плюс.
я так делал взаимодействие с js:
https://infostart.ru/1c/articles/1355214/
Что думаете о моем способе?
2. savelievD 56 10.02.21 10:53 Сейчас в теме
(1) имеется в виду использовать какой-нибудь объект DOM модели документа, для передачи в него текста и последующего чтения этих данных из 1С? Как по мне, то в такой схеме инициатором события может быть только 1С, что существенно ограничивает возможности. Ну а вообще конечно - всё зависит от задачи, которую хотим решить. Если способ работает, то почему бы и нет))
9. John_d 2976 11.02.21 09:19 Сейчас в теме
(2) можете подсказать как пользоваться расширением.
Что нажимать чтобы получить результат?
Нажимаю на кнопки получаю разные ошибки
Прикрепленные файлы:
10. savelievD 56 11.02.21 09:33 Сейчас в теме
(9) расширение предоставляет в основном программный интерфейс, для разработки своих решений. У вас открыта форма тестирования. Текст, который вы вводите в поле будет выполнен не в 1С, а в javascript. попробуйте
alert("Привет мир")
11. John_d 2976 11.02.21 10:04 Сейчас в теме
(10) ошибку выдает
Прикрепленные файлы:
12. savelievD 56 11.02.21 10:07 Сейчас в теме
(11) жми сюда..
Прикрепленные файлы:
13. John_d 2976 11.02.21 10:09 Сейчас в теме
(11) а все понял нужно зеленую кнопку нажимать.
Но я бы хотел получить результат как у вас в статье. Какие действия нужно сделать чтобы получить ответ от сокета?
Прикрепленные файлы:
14. savelievD 56 11.02.21 10:21 Сейчас в теме
(13) ещё раз повторю - это форма для тестирования и делал я её на скорую руку, просто, чтобы показать как это работает.
Если хочется попробовать, то проверь/укажите свой адрес сокет сервера в процедуре "КомандаНовыйВебСокет".
далее по нажатию на кнопку КомандаНовыйВебСокет в контексте js будет создана переменная "f", которой присвоится новый объект WebSocket. далее через строку ввода команды можно посылать данные серверу - f.send("Привет мир"). при получении сообщений от сервера они выведутся в сообщение на клиенте. закрыть сокет можно командой f.close(). ну или вызвав процедуру пс_СкриптыКлиент.ЗакрытьСокет(сюда передать переменную внешний объект - ссылку на сокет)
3. VitaliyCeban 413 10.02.21 12:09 Сейчас в теме
Насчет библиотек: Делаю РМК (на основе РМК из Розницы) на HTML + Vue.js. Естественно, там куча файлов. Хранить всё это в 1С не разумно, да и отладка - сущий ад.

Пошел по другому пути: разрабатываю в Visual Studio Code, как обычный проект Vue, с хранением в репозитории Git. Отладка в Google Chrome (это дает: отладку javascript / HTML / CSS, доступ к DOM, доступ к console, замеры производительности, поключение расширений браузера конкретно для отладки Vue). Ничего этого при разработке прямо в 1С - нет.

На стороне 1С, при включенном режиме разработки (константа 1С) в поле HTML документа загружен минимальный документ-прослойка, который общается с Chrome по WebSocket-у (при запуске отладки проекта на Vue, запускается простенький WebSocket-сервер, единственная функция которого - переправлять сообщения от одного клиента другому, и к нему подключаются документ из Chrome и документ из поля html документа).

Когда настает момент сделать production версию, весь Vue проект собирается в один единственный файл (и html, и css, и js), и уже этот файл помещаю в макет обработки 1С. Константу "Включен режим разработки" выключаю, и в поле HTML документа открывается уже не прослойка, а этот полноценный макет, и общаюсь уже не по websocket, а непосредственно вызовом функций. Программный интерфейс у прослойки и у собранной production версии - одинаковый, РМК на стороне 1С даже не знает (кроме момента выбора - какой макет загружать - dev или prod) где открыт документ, в поле HTML или в Chrome.
unichkin; portwein; JohnyDeath; AleksandrFil; +4 Ответить
4. savelievD 56 10.02.21 12:23 Сейчас в теме
(3) Интересное решение. Раз так много логики зашито в РМК, то думаю лучше делать морду РМ в виде микросервиса, а не запаковывать всё это дело в макет 1С.
5. VitaliyCeban 413 10.02.21 12:33 Сейчас в теме
(4) Так смысл в том чтобы работать в тонком клиенте 1С, а не в браузере (хотя и это можно, пока только в режиме разработки). Работать в 1С нужно для того, чтобы можно было бесшовно открывать нативные объекты/формы 1С. Например, те же отчеты на СКД. На данном этапе, скажем, форма простой оплаты у меня уже на html, а форму комбинированной оплаты я еще не переделал, и пока открывается 1Сная форма, "бесшовно". А если перейти на связку "браузер + http-сервис" - думаю что быстродействие будет страдать, надо будет играться с пулом сеансов и временем засыпания сеанса 1С. Ну и СКД не сделать, разве что только визуализацию готового отчета в PDF.
6. savelievD 56 10.02.21 12:47 Сейчас в теме
(5)я и имел в виду работать через клиента 1с. Просто храниш в константе адрес микросервиса. И открываешь его в поле хтмл документа)
7. VitaliyCeban 413 10.02.21 12:54 Сейчас в теме
(6) Ну это уже не универсально, надо будет на клиентской машине разворачивать собственно этот микро-веб-сервер, и еще поддерживать его запущенное состояние. А в текущей реализации, в production режиме никакие приложения, помимо 1С - запускать не нужно. С макетом работает почти отлично - разве что нашел (не)один баг в платформе, из макета документ открывается в Quirks Mode (BackCompat), а если по URL - то в Standards Mode (тут зарепортил: https://partners.v8.1c.ru/forum/topic/1970293 ), но можно обойти.
8. savelievD 56 10.02.21 12:58 Сейчас в теме
(7)во всем есть свои плюсы и минусы) микросервис можно дорабатывать без обновления 1с, если не нарушать api. Да и поднимать его не на клиенте а на сервере. Но это более глобальная разработка)
15. AleksandrFil 11.02.21 22:05 Сейчас в теме
(3) Интересно было бы посмотреть как визуально выглядит ваше РМК на Vue. И еще, сборка проекта на Vue в один файл каким образом осуществляется?
17. VitaliyCeban 413 11.02.21 22:56 Сейчас в теме
16. VitaliyCeban 413 11.02.21 22:55 Сейчас в теме
Видео РМК см. в вложении. Продолжаю активно разрабатывать.
Снималось на экране с разрешением 1024х768, чтобы симулировать реальные условия рабочего места. Точнее, на FullHD мониторе, с разрешением 1024х768, странно почему разрешение видео получилось 1512x1080.

Сборка осуществляется с помощью Vue CLI, который в свою очередь использует Webpack.
Часть файла vue.config.js, ответственная за сборку в один файл: https://pastebin.com/hmfqZWDQ
Прикрепленные файлы:
SLRestoran.mp4
pm74; Neitron4ik; Dach; AleksandrFil; JohnyDeath; +5 Ответить
18. AleksandrFil 12.02.21 10:32 Сейчас в теме
(16) Очень круто! Насколько я понимаю это тиражное решение?
20. Neitron4ik 12.02.21 16:01 Сейчас в теме
19. Dach 303 12.02.21 14:46 Сейчас в теме
(16) Красиво! А статью не планируете написать?
21. portwein 15.02.21 09:44 Сейчас в теме
Интересное решение.
Но я в какой то момент понял, что если решение требует участия технологий не относящихся к 1С, то такие решение лучше всего выносить в отдельную разработку не на 1С. Так повышается удобство разработки и поддержки, главное изначально определить некий контракт и описание api микросервиса и далее четко его соблюдать. Сам сервис не обязательно писать на чем то тяжелом (Java/Spring), иногда достаточно простого сервиса на Node/Express - эта связка тоже очень неплохо держит нагрузку. А уже сам сервис общается с 1С посредством http запросов и отдает только нужную информацию.
Оставьте свое сообщение

См. также

daСклонение: склонение ФИО, должностей, чисел, прилагательных, существительных на языке 1С + ТестЦентр Промо

Универсальные функции v8 1cv8.cf Абонемент ($m)

Функция предназначена для склонения выражений, которые часто требуется при формировании печатных форм договоров и прочих печатных форм. Функция склоняет по падежам ФИО, должности, числительные, валюты, единицы измерения, предметы. Также функция склоняет глаголы и прилагательные по числам и родам и существительные по числам. Имеется режим определения рода переданного выражения. Поддержка форматной строки для вывода результата. Функция не использует внешние библиотеки и веб-сервисы, написана на чистом языке 1С, и поэтому легко встраивается в любую конфигурацию или внешнюю обработку. Правила склонения оформлены в виде таблицы и могут быть легко изменены при необходимости.

1 стартмани

14.02.2015    108249    110    daMaster    90    

Сравнение реального дохода со средним доходом из API.HH.RU

Зарплата Управленческие v8 v8::СПР ЗУП3.x УУ Абонемент ($m)

Внешняя обработка на управляемой форме для 1С:Предприятие 8.3 по интеграции с HH.RU используя HH REST API. Ключевые функции: получение списка вакансий по должностям (Ключ для работы не нужен); расчет среднего дохода; Тестирование проводилось на платформе 1С:Предприятие 8.3 (8.3.13.1513) Зарплата и управление персоналом, редакция 3.1 (3.1.11.68) совместно с API.HH.RU.

1 стартмани

11.11.2019    4793    7    solaru    2    

Конфигурация для рекламного агентства

Управление услугами и сервисом Управление взаимоотношениями с клиентами (СRM) Производство готовой продукции (работ, услуг) Управление взаимоотношениями с клиентами (СRM) Производство готовой продукции (работ, услуг) v8 Реклама, PR и маркетинг УУ Абонемент ($m)

Данная конфигурация выполнена для решения тестового задания: Цель задания: 1) Понять, на каком из клиентов сколько мы заработали;  2) Понять, по какому виду СМИ сколько мы заработали;  3) Проследить по каждой услуге: у кого за сколько купили и кому за сколько продали, с возможностью перейти в соответствующий документ. Реализовано с помощью: 1. Справочники - контрагенты, номенклатура 2. Документы - Поступление услуг, реализация услуг 3. Отчеты - отчет по контрагентам, номенклатуре и движений.

1 стартмани

21.05.2019    6130    0    solaru    0    

Загрузка номенклатуры в УТ 10.3 из Excel файла с генерацией штрихкодов

Загрузка и выгрузка в Excel Обработка справочников Оптовая торговля Розничная торговля Учет ТМЦ Оптовая торговля Розничная торговля Учет ТМЦ v8 УТ10 Россия Абонемент ($m)

Обработка позволяет генерировать новые номенклатурные позиции на основе данных из файла Excel с последующей генерацией штрихкодов (ШК). Может быть полезна при больших поступлениях товаров на склад, где ручное создание и присваивание штрихкода  (ШК) может занимать много времени.

1 стартмани

24.03.2017    8527    7    solaru    0    

Под капотом управляемых форм

Практика программирования v8 1cv8.cf Бесплатно (free)

Управляемые формы уже давно и плотно вошли в жизнь 1С-разработчика. Однако, судя по недавним публикациям на Инфостарте, многие до сих пор мало знакомы с ними. Предлагаю разобраться с тем, что же это такое.

26.08.2013    276678    Evil Beaver    274    

[NotaBene] Универсальный отчет по таблице значений

Практика программирования v7.7 1cv7.md Россия Абонемент ($m)

1C v.7.7 Готовое решение. Не требует настройки. Не требует допрограммирования. Данная обработка решает часто встречающуюся задачу вывода в "красивом" виде таблицы значений (полученной, например, из запроса). Поддерживается произвольное группирование данных, отключение/включение группировок, в т.ч и создание "шахматок" (типа "продажи понедельно"). Обработка может использоваться как и в отладочных целях (для нормального просмотра ТЗ), так и в составе вполне рабочих отчетов. По крайней мере, я неоднократно клиентам данную обработку ставил вместо того, чтобы каждый раз писать замороченные выводы данных. И клиенты довольны, и мне - проще...

2 стартмани

07.05.2007    30261    2900    CheBurator    64