Интеграция интерактивных карт, таких как Яндекс Карты, во встроенные формы «1С:Предприятия» — популярная задача. Однако разработчики часто сталкиваются с неприятным поведением: карта успешно загружается, на ней отображается нужный город, но при попытке перетащить ее мышью или кликнуть ничего не происходит. Карта выглядит как статичная картинка, а принудительное включение режимов совместимости приводит к лавине ошибок JavaScript.
В этой статье мы подробно разберем, почему возникает эта проблема, проанализируем внутренние механизмы работы встроенного браузера 1С и реализуем надежные способы решения, которые заставят вашу карту ожить.
Для отображения веб-страниц на платформе Windows компонент 1С ПолеHTMLДокумента исторически использует встроенный движок MSHTML (Internet Explorer). Поведение этого движка имеет одну важную особенность:
Независимо от того, какая современная версия Internet Explorer (например, IE11) установлена в вашей операционной системе, любое стороннее приложение, вызывающее MSHTML (включая 1cv8.exe), по умолчанию запускает его в режиме глубокой обратной совместимости — IE7.
Современный API Яндекс Карт версии 2.1 активно использует новые стандарты JavaScript, события мыши и возможности рендеринга, которые старый движок IE7 попросту не поддерживает. Именно поэтому:
meta http-equiv="X-UA-Compatible" content="IE=9") вызывает ошибку в системном файле Яндекс Карт combine.js, так как для полноценной работы API 2.1 возможностей IE9 тоже недостаточно.Разберем по шагам четыре практических метода устранения этой проблемы.
Чтобы заставить встроенное поле HTML в 1С использовать современный движок рендеринга IE11 вместо IE7, необходимо внести изменения в системный реестр Windows на рабочих станциях пользователей. Это укажет операционной системе, что процессы 1С должны запускать веб-компонент в режиме максимальной совместимости.
Проанализируем необходимые ветки реестра. В зависимости от разрядности операционной системы и платформы 1С, вам нужно добавить параметры в следующие разделы:
Для текущего пользователя (рекомендуется):
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION
Для всех пользователей (для 32-битной версии 1С на 64-битной Windows):
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION
Для всех пользователей (в остальных случаях):
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION
В выбранных ветках реестра необходимо создать два параметра типа DWORD (32 бита):
1cv8.exe (для толстого клиента и конфигуратора). Значение: 11001 в десятичной системе счисления (или 2AF9 в шестнадцатеричной).1cv8c.exe (для тонкого клиента). Значение: 11001 в десятичной системе счисления (или 2AF9 в шестнадцатеричной).Значение 11001 (0x2AF9) принудительно включает режим граничной совместимости IE11 (Edge mode) для исполняемых файлов платформы 1С. После перезапуска 1С карта сразу начнет полноценно реагировать на любые действия пользователя.
Если вы применили изменения в реестре, то в самом коде HTML-документа обязательно укажите самый современный режим отрисовки с помощью метатега X-UA-Compatible. Вместо жесткого ограничения на устаревший IE=9, используйте директиву IE=edge.
Давайте посмотрим, как должен выглядеть скорректированный заголовок вашего HTML-документа:
<!DOCTYPE html>
<html>
<head>
<title>Определение адреса клика на карте</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- Принудительно включаем максимальный доступный режим рендеринга движка IE -->
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU&apikey=ВАШ_API_КЛЮЧ" type="text/javascript"></script>
</head>
Использование значения IE=edge совместно с настройкой реестра полностью решит проблему отзывчивости интерфейса карты.
Даже на правильно настроенной системе устаревший движок MSHTML может изредка генерировать некритичные предупреждения JavaScript при работе со сложными картами. Чтобы эти раздражающие диалоговые окна не мешали пользователям вашей базы 1С, настроим их автоматическое подавление.
Сделать это можно двумя путями: программно в 1С или непосредственно внутри кода JavaScript.
Вариант А. Программное отключение в 1С
В свойствах элемента управления ПолеHTMLДокумента на форме снимите флаг «Показывать предупреждения об ошибках». Программно при создании формы это можно сделать следующим образом:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Отключаем всплывающие окна с ошибками скриптов для элемента ПолеКарты
Элементы.ПолеКарты.ПоказыватьПредупрежденияОбОшибках = Ложь;
КонецПроцедуры
Вариант Б. Отключение перехватом ошибок в JavaScript
Добавьте в самое начало вашего тега <script> (до инициализации API Яндекс Карт) глобальный обработчик ошибок, который будет возвращать значение true, тем самым «замалчивая» любые сбои:
<script type="text/javascript">
// Подавляем любые JS-ошибки на странице
window.onerror = function(message, url, line) {
return true;
};
</script>
Если ваша конфигурация работает на платформе «1С:Предприятие» версии 8.3.14 или новее, вам больше не нужно зависеть от устаревшего системного Internet Explorer и вносить изменения в реестр Windows. Разработчики 1С добавили полноценную поддержку современного движка Chromium (WebKit).
Чтобы переключить ваше ПолеHTMLДокумента на работу с Chromium, выполните следующие шаги:
ПолеHTMLДокумента.После этого поле HTML-документа начнет использовать современный изолированный движок рендеринга, на котором Яндекс Карты, графики и любые внешние библиотеки JS будут работать максимально быстро и без каких-либо доработок реестра.
В коде, предоставленном в вопросе, реализована функция получения адреса по клику мыши (обратное геокодирование). Но как вернуть эти данные из виртуальной карты непосредственно в реквизиты документа или справочника в 1С?
Рассмотрим универсальный механизм взаимодействия JavaScript и платформы 1С через перехват навигации. Этот метод работает стабильно как на старых обычных формах, так и на управляемых формах.
Шаг 1. Модифицируем JavaScript во встроенном HTML-документе
В функции получения адреса getAddress(coords) после успешного геокодирования сынициируем переход по фиктивной ссылке с нужными нам параметрами:
function getAddress(coords) {
myPlacemark.properties.set('iconCaption', 'поиск...');
ymaps.geocode(coords).then(function (res) {
var firstGeoObject = res.geoObjects.get(0);
var addressText = firstGeoObject.getAddressLine();
myPlacemark.properties.set({
iconCaption: [
firstGeoObject.getLocalities().length ? firstGeoObject.getLocalities() : firstGeoObject.getAdministrativeAreas(),
firstGeoObject.getThoroughfare() || firstGeoObject.getPremise()
].filter(Boolean).join(', '),
balloonContent: addressText
});
// Формируем специальную ссылку для отправки данных обратно в 1С
var lat = coords[0];
var lng = coords[1];
window.location.href = "v8action://get_address?address=" + encodeURIComponent(addressText) + "&lat=" + lat + "&lng=" + lng;
});
}
Шаг 2. Пишем обработчик события в 1С
В модуле формы 1С для элемента ПолеHTMLДокумента создаем обработчик события ПриНажатии (или ПередПереходом / OnStartNavigation в зависимости от версии формы). Проанализируем пример кода для управляемой формы:
&НаКлиенте
Процедура ПолеКартыПриНажатии(Элемент, ДанныеСобытия, СтандартнаяОбработка)
// Получаем URL, на который пытается перейти встроенный браузер
ПереходURL = ДанныеСобытия.Href;
// Проверяем, наш ли это кастомный протокол
Если Найти(ПереходURL, "v8action://get_address") > 0 Тогда
// Отменяем реальную навигацию браузера, чтобы не перезагружать карту
СтандартнаяОбработка = Ложь;
// Извлекаем параметры из адресной строки
ПараметрыСтроки = ПолучитьПараметрыИзURL(ПереходURL);
// Записываем полученные данные в реквизиты формы 1С
Объект.АдресДоставки = ПараметрыСтроки.Получить("address");
Объект.Широта = ПараметрыСтроки.Получить("lat");
Объект.Долгота = ПараметрыСтроки.Получить("lng");
ПоказатьПредупреждение(, "Адрес успешно передан в 1С: " + Объект.АдресДоставки);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Функция ПолучитьПараметрыИзURL(Знач ВходящийURL)
Результат = Новый Соответствие;
// Отсекаем схему протокола
ПозВопроса = Найти(ВходящийURL, "?");
Если ПозВопроса = 0 Тогда
Возврат Результат;
КонецЕсли;
ПараметрыТекст = Сред(ВходящийURL, ПозВопроса + 1);
МассивПараметров = СтрРазделить(ПараметрыТекст, "&");
Для Каждого ТекущийПараметр Из МассивПараметров Цикл
ПозРавно = Найти(ТекущийПараметр, "=");
Если ПозРавно > 0 Тогда
Ключ = Лев(ТекущийПараметр, ПозРавно - 1);
ЗначКодированное = Сред(ТекущийПараметр, ПозРавно + 1);
// Раскодируем URL-символы обратно в текст
Значение = ДекодироватьСтроку(ЗначКодированное, СпособКодированияСтроки.КодировкаURL);
Результат.Вставить(Ключ, Значение);
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Таким образом, мы не только оживили карту во встроенном поле 1С, настроив корректную работу движка рендеринга через реестр или WebKit, но и организовали бесшовный двусторонний обмен данными между JavaScript и платформой «1С:Предприятие».