При разработке интерфейсов в 1С:Предприятии часто возникает задача интеграции с картографическими сервисами, такими как Google Maps. Одной из самых сложных проблем является организация обратной связи: когда пользователь совершает действие на карте (кликает или рисует фигуру), необходимо передать полученные координаты обратно в базу данных 1С. Рассмотрим подробно, как реализовать этот механизм, используя поле HTML-документа.
Основная ошибка начинающих разработчиков заключается в попытке «вытянуть» данные из объекта Документ поля HTML напрямую через встроенный язык 1С в момент нажатия. Как показывает практика и обсуждения на форумах, событие ПриНажатии в 1С может срабатывать раньше, чем JavaScript внутри страницы успеет обработать координаты и обновить свойства объектов. Проанализируем более надежный подход: JavaScript должен сам «выталкивать» данные в 1С при наступлении события на карте.
Это классический и наиболее стабильный способ для тонкого и толстого клиентов 1С, работающих на движке Internet Explorer. Суть метода заключается в вызове специальной функции JavaScript, которая генерирует событие, перехватываемое платформой 1С.
Шаг 1. Настройка JavaScript на стороне HTML-страницы
В коде инициализации карты нам необходимо добавить слушатель события click для объекта карты. Разберем пример реализации функции showCoordinates:
function showCoordinates(event) {
var lat = event.latLng.lat();
var lng = event.latLng.lng();
var coordsString = lat + "|" + lng;
// Передаем строку с координатами в 1С
window.external.Notify(coordsString);
}
Шаг 2. Настройка обработчика в 1С
В форме 1С для элемента ПолеHTMLДокумента необходимо назначить обработчик события ПриНажатии (или в некоторых случаях используется событие ДокументСформирован для подписки на события). Однако при использовании Notify данные попадают в параметр ДанныеСобытия (или ТекстУведомления в зависимости от версии платформы).
Проанализируем пример кода на стороне 1С:
&НаКлиенте
Процедура ПолеHTMLУправлениеСобытиями(Элемент, Событие, ДанныеСобытия, СтандартнаяОбработка)
// В переменной ДанныеСобытия будет строка "46.635;30.402"
Если ЗначениеЗаполнено(ДанныеСобытия) Тогда
МассивКоординат = СтрРазделить(ДанныеСобытия, "|");
Широта = МассивКоординат[0];
Долгота = МассивКоординат[1];
Сообщить("Выбраны координаты: " + Широта + ", " + Долгота);
КонецЕсли;
КонецПроцедуры
Если задача стоит сложнее — например, нужно получить координаты вершин нарисованного многоугольника — нам потребуется использовать библиотеку drawing. Выясним, как извлечь данные из объектов Polygon и Rectangle.
Для многоугольника (Polygon) используется метод getPath(), который возвращает массив вершин. Посмотрим на пример реализации внутри JS:
google.maps.event.addListener(drawingManager, 'overlaycomplete', function(event) {
if (event.type == 'polygon') {
var path = event.overlay.getPath();
var coordsArray = [];
for (var i = 0; i < path.getLength(); i++) {
var point = path.getAt(i);
coordsArray.push(point.lat() + ":" + point.lng());
}
// Отправляем все вершины одной строкой, разделенной точкой с запятой
window.external.Notify("POLYGON|" + coordsArray.join(";"));
}
});
Для прямоугольника (Rectangle) ситуация иная. Прямоугольник в Google Maps определяется границами Bounds (северо-восточный и юго-западный углы). Рассмотрим, как передать эти данные:
if (event.type == 'rectangle') {
var bounds = event.overlay.getBounds();
var ne = bounds.getNorthEast();
var sw = bounds.getSouthWest();
var result = "RECT|" + ne.lat() + "," + ne.lng() + "|" + sw.lat() + "," + sw.lng();
window.external.Notify(result);
}
В некоторых случаях (например, при специфических настройках безопасности или использовании определенных версий WebKit в 1С) window.external.Notify может не срабатывать. Проанализируем альтернативный путь через свойство title документа.
Логика решения:
document.title = "COORDS:" + lat + "," + lng;.ПриНажатии, чтобы считать это свойство.Пример получения данных в 1С:
&НаКлиенте
Процедура ПроверитьКоординаты()
ДокументHTML = Элементы.ПолеКарты.Документ;
Если Найти(ДокументHTML.title, "COORDS:") > 0 Тогда
СтрокаДанных = СтрЗаменить(ДокументHTML.title, "COORDS:", "");
// Обработка данных...
ДокументHTML.title = "Карта"; // Сбрасываем заголовок
КонецЕсли;
КонецПроцедуры
В современных версиях платформы используется движок Chromium. Здесь взаимодействие может быть более гибким. Мы можем создать скрытый элемент input на форме HTML и записывать значения в него. Рассмотрим этот вариант подробнее.
В HTML добавляем скрытое поле:
<input type="hidden" id="ExchangeField" value="" />
В JavaScript при клике записываем значение:
document.getElementById('ExchangeField').value = lat + '|' + lng;
В 1С считываем значение программно:
ЭлементИнпут = Элементы.ПолеКарты.Документ.getElementById("ExchangeField");
Если ЭлементИнпут <> Неопределено Тогда
Координаты = ЭлементИнпут.value;
КонецЕсли;
При работе с координатами в 1С важно помнить о разделителях дробной части. Google Maps возвращает числа с точкой, что соответствует формату JSON или Число в языке JavaScript. При передаче их строкой в 1С, убедитесь, что при преобразовании в тип Число учитывается текущая локаль системы или используйте функцию Число() после замены точки на запятую, если это необходимо для вашей конфигурации.
Также стоит обратить внимание на API Key. В коде автора темы указано key=MyKey. Без валидного ключа Google Cloud Platform функции рисования и события кликов могут блокироваться политикой безопасности браузера, встроенного в 1С.
Подводя итог, наиболее эффективным методом является комбинация подписки на события Drawing Manager в JavaScript и передача сериализованной строки через window.external.Notify. Это позволяет избежать проблем с COM-объектами и предоставляет 1С уже готовые к обработке текстовые данные.