1с методы поле html документа управляемые формы. Управляемые формы: Поле HTML Документа и веб-клиент

1с методы поле html документа управляемые формы. Управляемые формы: Поле HTML Документа и веб-клиент

Взаимодействие javascript и интерфейса 1С дает огромные возможности для реализации нестандартных функций. Раньше можно было напрямую вызывать функции JavaScript через DOM объект document Поля HTML документа. В современных браузерах эта возможность ушла. Более того, в веб-клиенте появляется тип ВнешнийОбъект, который вообще нигде не описан. На Инфостарте были предложения вызывать JavaScript через fireEvent, но это очень неудобно. Предлагаю свой вариант решения.

С чего все началось

Разбираться с HTML полем меня сподвигло большое количество задач, в которых была необходимость реализовать интерактивные карты с мониторингом, маршрутизацией и т.д. Поскольку встроенными средствами 1С сделать это невозможно, то раньше использовал ActiveX компоненту собственного изготовления. На обычных формах все работало приемлимо, не считая, что решение и рядом не стояло с открытыми фреймворками типа OpenLayers. После появления управляемых форм, была попытка встроить все тот же ActiveX в HTML документ и разместить его в поле. Решение работает, но в виду ужесточения политики безопасности Microsoft, требовало изменения настроек безопасности на каждом клиенте, что в конечном счете оказалось неприемлимым. Вот тогда мы и поставили перед собой задачу, прикрутить к управляемым формам карты на основе Web-движков (Яндекс.Карты, OpenLayers и прочие Tile ориентированные движки).

Вариант 1. Работает в толстом клиенте, работает в тонком клиенте, не работает в веб-клиенте

Суть метода заключается в получении свойства parentWindow элемента формы ПолеHTMLДокумента. Выглядит примерно так:

function HelloWorld(FormLink) { FormLink.WebMapJavascriptAction("Hello from outside!"); return "Hello world!"; } &НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) WebКартаРеквизитФормыСтрока = Обработки.УНП_WEBКарта.ПолучитьМакет("HTMLМакет").ПолучитьТекст(); КонецПроцедуры &НаКлиенте Процедура WebКартаДокументСформирован(Элемент) Сообщить(Элементы.WebКарта.Документ.parentWindow.HelloWorld(ЭтаФорма)); КонецПроцедуры &НаКлиенте Процедура WebMapJavascriptAction(Переменная) Экспорт Сообщить(Переменная); КонецПроцедуры

Все это прекрасно работает в толстом и тонком клиенте, но в веб-клиенте это работать не будет, так как в веб-клиенте у ПоляHTMLДокумента в свойстве Документ нет parentWindow.

Вариант 2. Работает в Толстом клиенте, тонком клиенте, веб-клиенте (проверено Chrome, IE, Edge)

Для реализации этого варианта необходимо немного исправить HTML макет. А именно:

document.body.HelloWorld = function(FormLink) { FormLink.WebMapJavascriptAction("Hello from outside!"); return "Hello world!"; }

И небольшие правки в коде формы

&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) ПовторноеСрабатывание = Ложь; WebКартаРеквизитФормыСтрока = Обработки.УНП_WEBКарта.ПолучитьМакет("HTMLМакет").ПолучитьТекст(); КонецПроцедуры &НаКлиенте Процедура WebКартаДокументСформирован(Элемент) Если Не ПовторноеСрабатывание Тогда // В некоторых случаях, при подключении дополнительных библиотек, //событие может сработать повторно в уже загруженном документе ОбъектBody = Неопределено; Попытка ОбъектBody = Элементы.WebКарта.Документ.parentWindow.document.body; Исключение КонецПопытки; Если Не ЗначениеЗаполнено(ОбъектBody) Тогда Попытка ОбъектBody = Элементы.WebКарта.Документ.body; Исключение КонецПопытки; КонецЕсли; Если Не ЗначениеЗаполнено(ОбъектBody) Тогда Сообщить("Что-то пошло не так"); Иначе Сообщить(ОбъектBody.HelloWorld(ЭтаФорма)); КонецЕсли; ПовторноеСрабатывание = Истина; КонецЕсли; КонецПроцедуры &НаКлиенте Процедура WebMapJavascriptAction(Переменная) Экспорт Сообщить(Переменная); КонецПроцедуры

Таким образом для толстого и тонкого клиента мы оставляем все как и было, но для универсальности используем расширенный нами объект DOM body. В веб-клиенте элемент формы ПолеHTMLДокумента.Документ содержит тип ВнешнийОбъект, что на самом деле является COM реализацией элемента body по структуре DOM.

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

Надеюсь кому-то поможет;-)

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

  • Работать с компонентами ActiveX;
  • Вызывать Javascript;
  • Создавать и использовать ссылки на различные объекты базы данных.

Этот объект называется в 1С полеHTMLдокумента.

Элемент управления ПолеHTMLДокумента имеет одно существенное ограничение в использовании – его нельзя использовать для расположенных в таблице полей.

Создание собственного браузера в 1С

Давайте попробуем с помощью этого поля создать обработку, открывающую ссылку на ресурс в интернете:

Проверим, как это работает.. Получим картинку (Рис.4)
Рис.4.

Проанализируем, что мы видим:

  • Открылось поисковое окно, со ссылкой на сайт, при этом поиск осуществляется с помощью поисковой системы, назначенной по умолчанию;
  • Обработка работает, интернет страницы открываются, переходы по ссылкам осуществляются;
  • При вызове ресурса произошла ошибка сценария.
  • С чем связана ошибка? С тем, что ПолеHTMLДокумента – это фактически типовой Internet Explorer, причем не самой последней версии, который не поддерживает большинство современных ресурсов. Так что сайты, не поддерживающие режим совместимости, будут открываться с ошибками в сценарии.

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

    Создание ссылки на объект базы данных

    Задача состоит в следующем:

    • Создать список каких-либо объектов, допустим элементы справочника «Сотрудники»;
    • Получить ссылку на каждый из них;
    • Открывать их непосредственным нажатием на соответствующую ссылку.

    Создадим нашу обработку и форму на ней.


    Подробнее рассмотрим, что мы сделали:

  • Создали текстовый документ, который содержит «тело» нашего сайта;
  • Начало и окончание документа, а так же тело нашего ХТМЛ документа мы описали с помощью соответствующих тегов;
  • Записали в него каждого сотрудника;
  • В записях сотрудников у нас содержится информация, которая нам понадобится позже, когда мы будем открывать элементы кликая на ФИО сотрудников;
  • Установили нашему полю текст, который описывает структуру.
  • Попробовав сейчас активировать любую из имеющихся гиперссылок мы столкнемся с тем, что «Такая страница не найдена»(Рис.8)
    Рис.8

    Продолжим описывать обработчик.

    Создадим процедуру, которая обрабатывает клик мышки по гиперссылке на элемент справочника (Рис.9).

    Рис.9

    Рассмотрим её подробнее:

  • Прежде всего отключим стандартную обработку щелчка по гиперссылке;
  • Получим строку, характеризующую наш элемент, для этого в ДанныеСобытия получим значение параметра Element.id;
  • Разделим полученную строку в соответствии с правилами, по которым мы её формировали (название справочника и уникальный идентификатор, разделенные между собой тире);
  • Получаем ссылку на элемент, используя функцию ВозвратСсылки;
  • Открываем элемент по полученной ссылке.
  • Протестируем выполнение созданного кода.

    Так как в настройках нашей программы запрещено использование модальных окон, выполнение выше приведенного кода завершилось ошибкой (Рис.10). В противном случае все бы отработало нормально.

    Рис.10

    Зайдем в конфигураторе в меню Текст->Рефакторинг->Нерекомендуемые синхронные вызовы->Преобразовать вызовы модуля. По прошествии некоторого времени текст нашего модуля будет выглядеть как на Рис.11

    Рис.11

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

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

    Пара слов о Javascript

    Вызовы функций JS в ранних версиях программы осуществлялись через параметр поля document.parentWindow.MyFunk(), однако в современных браузерах эта возможность была утрачена. Не срабатывают так же вызовы через eval().

    Выход состоит в использовании специальной функции fireEvent, которая является универсальным механизмом обмена данными между 1С и Javascript.

    Во время реализации одного проекта, возникла необходимость выполнять javascript(далее JS) код под управление объекта ПолеHTMLДокумента, с получением результат в 1С. Приведённые примеры, в найденных статьях, показались не очень удобными в использовании (сугубо личное мнение). Было принято решение попробовать найти другое, более простое, решение, на поиски отводилось не более 1 дня.

    ДИВ.setAttribute("onclick", "alert("Координаты");");

    Выполним скрипт

    ДИВ.click();

    ТАДА. все работает

    Процедура ВыполнитьСкрипт(ТекстСкрипт) ДИВ = Элементы.док.Документ.getElementById("TEST"); ДИВ.setAttribute("onclick", ТекстСкрипт); ДИВ.click(); КонецПроцедуры

    Дополнение от 02.08.2016

    В комметариях был предложен еще один способ вызова JS (спасибо ), если у вас есть возможность менять код HTML документа, то можно прописать функцию в нем и затем ее вызывать. передавая в нее код на JS.

    function exec(script) { eval(script); }

    и затем в 1С:

    Элементы.ПолеHTMLДокумента1.Документ.parentWindow.exec("alert("OK")");

    Возврат результата JS в 1С

    Для передачи результата скрипта в 1С из объекта ПолеHTMLДокумента будем использовать событие. Привяжем к ПолеHTMLДокумента событие ПриНажатии которое получает на вход 3 параметра:

  • Элемент у которого произошло событие(само ПолеHTMLДокумента)
  • Объект событие
  • Признак выполнения стандартного поведения
  • Чтобы вызвать событие при нажатии понадобиться выполнить следующий js код

    Var evt = document.createEventObject(); // создадим пустой объект событие evt.propertyName = "функц1"; // в реквизит propertyName предлагаю помещать название результата (что-то вроде типа, или название функции от которой получили данные) evt.data = "156"; //в реквизит data будем передавать данные результата document.body.fireEvent("onclick", evt); // выполним событие при нажатии ПолеHTMLДокумента

    Выполнив данный js код в процедуру при нажатии вторым параметром придет созданный нами объект событие. Который довольно удобно обрабатывать.

    Пример разбора ответа.

    &НаКлиенте // получаем имя и результат события Процедура ДокПриНажатии(Элемент, ДанныеСобытия, СтандартнаяОбработка) ИмяОперации = ДанныеСобытия.Event.propertyName; ДанныеОперации = ДанныеСобытия.Event.data; Если ИмяОперации = "" Тогда //не наше событие Возврат; КонецЕсли; Если ИмяОперации = "Функц1" Тогда // обработка результат ИначеЕсли ИмяОперации = "функц2" Тогда // обработка результат //...... КонецЕсли; КонецПроцедуры

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

    Дополнения от 26.03.2016

    И в этом месте тоже произошли непонятки (ошитбка восптроизводится только на плаформе 8.3.5.1570, но дабы предупредить эти ситуации в далнейшем, приведу решение) Сама причина - при повторном запуске формы с Поле HTML документа в момент вызова процедуры при нажатии по полю HTML платформенный вызов залипал и валил весь COM объект (Произошла исключительная ситуация (htmlfile): Неопределенная ошибка). Решением стало отключение стндарного выполнения события click, и отключение режима всплывания события. Как же это сделать смотрим ниже.

    // отключим всплывание события

    Evt.cancelBubble = true;

    // отключим стандартное поведение

    Evt.returnValue = false;

    В результате для передачи данных в 1с из JS мы получим функцию.

    Function return1c(name,data){ var evt = document.createEventObject(); evt.propertyName = name; evt.data = data; evt.cancelBubble = true; evt.returnValue = false; document.fireEvent("onclick",evt); };

    Вывод.

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

    Пример реализации в

    28
    При интеграции 1С с веб-сайтами всегда встает вопрос о передачи некоторых данных на веб-сервер. Будь то это передача параметров запроса для получения данных от веб-сервера в 1С или же передача данных из 1С, которые должны быть сохранены или каким-то 14
    У разработчиков на платформе 1С иногда возникает задача по взаимодействию системы 1С: Предприятие с различными почтовыми программами и протоколами. 1С Предприятие 8.0 имеет довольно удобные средства для отправки сообщений, импорта писем из почтового 9
    При обмене данными с веб-сайтами зачастую используется формат JSON. К сожалению, в 1С нет стандартных процедур для работы с данным форматом. В процессе реализации одного из проектов мной был разработан ряд процедур и функций облегчающих жизнь програ 8
    Формат JSON в 1С до версии 8.3.6 не реализован, но нижет я приведу примеры функций которые можно использовать для полноценной работы JSON в 1С предыдущий версий. JSON (JavaScript Object Notation) это текстовый формат обмена данными, широко ис 5
    В этой статье я постараюсь описать процесс парсинга сайтов средствами 1С с примером. Это статья не является инструкцией к применению, а лишь демонстрирует возможности 1С. Что мы имеем? 1. Сайт в интернете, на котором располагается список товаро

    Во время реализации одного проекта, возникла необходимость выполнять javascript(далее JS) код под управление объекта ПолеHTMLДокумента, с получением результат в 1С. Приведённые примеры, в найденных статьях, показались не очень удобными в использовании (сугубо личное мнение). Было принято решение попробовать найти другое, более простое, решение, на поиски отводилось не более 1 дня.

    ДИВ.setAttribute("onclick", "alert("Координаты");");

    Выполним скрипт

    ДИВ.click();

    ТАДА. все работает

    Процедура ВыполнитьСкрипт(ТекстСкрипт) ДИВ = Элементы.док.Документ.getElementById("TEST"); ДИВ.setAttribute("onclick", ТекстСкрипт); ДИВ.click(); КонецПроцедуры

    Дополнение от 02.08.2016

    В комметариях был предложен еще один способ вызова JS (спасибо ), если у вас есть возможность менять код HTML документа, то можно прописать функцию в нем и затем ее вызывать. передавая в нее код на JS.

    function exec(script) { eval(script); }

    и затем в 1С:

    Элементы.ПолеHTMLДокумента1.Документ.parentWindow.exec("alert("OK")");

    Возврат результата JS в 1С

    Для передачи результата скрипта в 1С из объекта ПолеHTMLДокумента будем использовать событие. Привяжем к ПолеHTMLДокумента событие ПриНажатии которое получает на вход 3 параметра:

  • Элемент у которого произошло событие(само ПолеHTMLДокумента)
  • Объект событие
  • Признак выполнения стандартного поведения
  • Чтобы вызвать событие при нажатии понадобиться выполнить следующий js код

    Var evt = document.createEventObject(); // создадим пустой объект событие evt.propertyName = "функц1"; // в реквизит propertyName предлагаю помещать название результата (что-то вроде типа, или название функции от которой получили данные) evt.data = "156"; //в реквизит data будем передавать данные результата document.body.fireEvent("onclick", evt); // выполним событие при нажатии ПолеHTMLДокумента

    Выполнив данный js код в процедуру при нажатии вторым параметром придет созданный нами объект событие. Который довольно удобно обрабатывать.

    Пример разбора ответа.

    &НаКлиенте // получаем имя и результат события Процедура ДокПриНажатии(Элемент, ДанныеСобытия, СтандартнаяОбработка) ИмяОперации = ДанныеСобытия.Event.propertyName; ДанныеОперации = ДанныеСобытия.Event.data; Если ИмяОперации = "" Тогда //не наше событие Возврат; КонецЕсли; Если ИмяОперации = "Функц1" Тогда // обработка результат ИначеЕсли ИмяОперации = "функц2" Тогда // обработка результат //...... КонецЕсли; КонецПроцедуры

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

    Дополнения от 26.03.2016

    И в этом месте тоже произошли непонятки (ошитбка восптроизводится только на плаформе 8.3.5.1570, но дабы предупредить эти ситуации в далнейшем, приведу решение) Сама причина - при повторном запуске формы с Поле HTML документа в момент вызова процедуры при нажатии по полю HTML платформенный вызов залипал и валил весь COM объект (Произошла исключительная ситуация (htmlfile): Неопределенная ошибка). Решением стало отключение стндарного выполнения события click, и отключение режима всплывания события. Как же это сделать смотрим ниже.

    // отключим всплывание события

    Evt.cancelBubble = true;

    // отключим стандартное поведение

    Evt.returnValue = false;

    В результате для передачи данных в 1с из JS мы получим функцию.

    Function return1c(name,data){ var evt = document.createEventObject(); evt.propertyName = name; evt.data = data; evt.cancelBubble = true; evt.returnValue = false; document.fireEvent("onclick",evt); };

    Вывод.

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

    Пример реализации в

    просмотров