Как декодировать (преобразовать) Unicode в 1С При разработке очередного обмена с интернет магазином через API столкнулисть что сайт возвращает ответ в виде:
Код VBS {"ok":"true ","description":"\u0421\u0442\u0430\u0442\u0443\u0441 \u0437\u0430\u043a\u0430\u0437\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d"}
из кода ясно что это JSON и используя код ПрочитатьJSON
Код 1C v 8.3 Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(стрВходящая);
ДанныеЛога = ПрочитатьJSON(Чтение);
Чтение.Закрыть();
В переменной ДанныеЛога будет структура в виде
В результате получилась функция с 2-мя вариантами возрата, в зависимости от того как нужно
Код 1C v 8.3 //Функция читает полученный JSON декадируя текст юникод
Функция ДекодироватьUniCodeВJSON(стрВходящая)
// стрВходящая содержит {"ok":"true ","description":"\u0421\u0442\u0430\u0442\u0443\u0441 \u0437\u0430\u043a\u0430\u0437\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d"}
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(стрВходящая);
ДанныеЛога = ПрочитатьJSON(Чтение);
Чтение.Закрыть();
// Вариант 1 используя перебор структуры и вывод в текстовую переменную
Текст = "";
Для каждого Элемент Из ДанныеЛога Цикл
//добавим разделитель после предыдущего значения
Текст = Текст + ?(НЕ ПустаяСтрока(Текст), Символы.ПС, "");
//добавим представление ключа и значения:
Текст = Текст + Элемент.Ключ + " = " + Элемент.Значение;
КонецЦикла;
Возврат Текст; //Вернет ok = true description = Статус заказа изменен
// Вариант 2 мспользуя ЗаписьJSON
Запись = Новый ЗаписьJSON;
Запись.УстановитьСтроку(Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет));
ЗаписатьJSON(Запись, ДанныеЛога,);
Возврат Запись.Закрыть(); // Вернет JSON {"ok":"true ","description":"Статус заказа изменен"}
КонецФункции
На просторах интернета была найдена еще одна функция:
Код 1C v 8.3 //Параметры: Строка в Юникод (обязательный) Тип: Строка. Исходная строка.
//Возвращаемое значение: Тип: Строка. Строка обработанных символов.
//Описание: Возвращает преобразованную строку из формата Unicod.
//Автор: Александр Кияница (treedo)
Функция ПереобразоватьЮникод(Строка)
ГотововаяСтрока = "" ;
МасУкр = Новый Массив(66) ;
МасУкр[0]="А"; МасУкр[1]="Б"; МасУкр[2]="В"; МасУкр[3]="Г"; МасУкр[4]="Ґ"; МасУкр[5]="Д";
МасУкр[6]="Е"; МасУкр[7]="Є"; МасУкр[8]="Ж"; МасУкр[9]="З"; МасУкр[10]="И"; МасУкр[11]="І";
МасУкр[12]="Ї"; МасУкр[13]="Й"; МасУкр[14]="К"; МасУкр[15]="Л"; МасУкр[16]="М"; МасУкр[17]="Н";
МасУкр[18]="О"; МасУкр[19]="П"; МасУкр[20]="Р"; МасУкр[21]="С"; МасУкр[22]="Т"; МасУкр[23]="У";
МасУкр[24]="Ф"; МасУкр[25]="Х"; МасУкр[26]="Ц"; МасУкр[27]="Ч"; МасУкр[28]="Ш"; МасУкр[29]="Щ";
МасУкр[30]="Ь"; МасУкр[31]="Ю"; МасУкр[32]="Я";
МасУкр[33]="а"; МасУкр[34]="б"; МасУкр[35]="в"; МасУкр[36]="г"; МасУкр[37]="ґ"; МасУкр[38]="д";
МасУкр[39]="е"; МасУкр[40]="є"; МасУкр[41]="ж"; МасУкр[42]="з"; МасУкр[43]="и"; МасУкр[44]="і";
МасУкр[45]="ї"; МасУкр[46]="й"; МасУкр[47]="к"; МасУкр[48]="л"; МасУкр[49]="м"; МасУкр[50]="н";
МасУкр[51]="о"; МасУкр[52]="п"; МасУкр[53]="р"; МасУкр[54]="с"; МасУкр[55]="т"; МасУкр[56]="у";
МасУкр[57]="ф"; МасУкр[58]="х"; МасУкр[59]="ц"; МасУкр[60]="ч"; МасУкр[61]="ш"; МасУкр[62]="щ";
МасУкр[63]="ь"; МасУкр[31]="ю"; МасУкр[65]="я";
МасКод = Новый Массив(66) ;
МасКод[0]="0410"; МасКод[1]="0411"; МасКод[2]="0412"; МасКод[3]="0413"; МасКод[4]="0490"; МасКод[5]="0414";
МасКод[6]="0415"; МасКод[7]="0404"; МасКод[8]="0416"; МасКод[9]="0417"; МасКод[10]="0418"; МасКод[11]="0406";
МасКод[12]="0407"; МасКод[13]="0419"; МасКод[14]="041A"; МасКод[15]="041B"; МасКод[16]="041C"; МасКод[17]="041D";
МасКод[18]="041E"; МасКод[19]="041F"; МасКод[20]="0420"; МасКод[21]="0421"; МасКод[22]="0422"; МасКод[23]="0423";
МасКод[24]="0424"; МасКод[25]="0425"; МасКод[26]="0426"; МасКод[27]="0427"; МасКод[28]="0428"; МасКод[29]="0429";
МасКод[30]="042C"; МасКод[31]="042E"; МасКод[32]="042F";
МасКод[33]="0430"; МасКод[34]="0431"; МасКод[35]="0432"; МасКод[36]="0413"; МасКод[37]="0491"; МасКод[38]="0434";
МасКод[39]="0435"; МасКод[40]="0454"; МасКод[41]="0436"; МасКод[42]="0437"; МасКод[43]="0438"; МасКод[44]="0456";
МасКод[45]="0457"; МасКод[46]="0439"; МасКод[47]="043A"; МасКод[48]="043B"; МасКод[49]="043C"; МасКод[50]="043D";
МасКод[51]="043E"; МасКод[52]="043F"; МасКод[53]="0440"; МасКод[54]="0441"; МасКод[55]="0442"; МасКод[56]="0443";
МасКод[57]="0444"; МасКод[58]="0445"; МасКод[59]="0446"; МасКод[60]="0447"; МасКод[61]="0448"; МасКод[62]="0449";
МасКод[63]="044C"; МасКод[31]="044E"; МасКод[65]="044F";
тмпСтрока = "" ;
Для Счетчик = 1 По СтрДлина(Строка) Цикл
Если Лев(Строка, 1) = "\" Тогда
Если Лев(Строка, 2) = "\u" Тогда
тмпСтрока = Прав(Лев(Строка, 6),4) ;
Если МасКод.Найти(тмпСтрока) = Неопределено Тогда
СтрокаЗамены = Прав(тмпСтрока, 1) ;
тмпСтрока = СтрЗаменить(тмпСтрока,СтрокаЗамены,ТРег(СтрокаЗамены));
Если МасКод.Найти(тмпСтрока) = Неопределено Тогда
Сообщить("Код символа не найден: " + тмпСтрока) ;
Иначе
ГотововаяСтрока = ГотововаяСтрока + МасУкр[МасКод.Найти(тмпСтрока)] ;
КонецЕсли;
Иначе
ГотововаяСтрока = ГотововаяСтрока + МасУкр[МасКод.Найти(тмпСтрока)] ;
КонецЕсли;
Строка = Прав(Строка, (СтрДлина(Строка)-6)) ;
Иначе
Строка = Прав(Строка, (СтрДлина(Строка)-2)) ;
КонецЕсли;
Иначе
ГотововаяСтрока = ГотововаяСтрока + Лев(Строка, 1) ;
Строка = Прав(Строка, (СтрДлина(Строка)-1)) ;
КонецЕсли;
КонецЦикла;
Возврат ГотововаяСтрока ;
КонецФункции
Категория:
WEB-сервисы, WS-ссылки, XDTO-пакеты COM-подключение к базе 7.7 из .NET, .NET Core Инсталяция:> dotnet add package sabatex.V1C77
или добавить через NUGET пакет sabatex.V1C77.
Добавить пространство имен: using sabatex.V1C77;
пример использованя: ---C#
static void Main(string[] args) { // создаём строку соединения var connection = new sabatex.V1C77.Models.Connection { DataBasePath = @"C:\demo\1SBUKRD", // путь к базе PlatformType = sabatex.V1C77.Models.EPlatform1C.V77M, // платформа 1С77 UserName = "Админов", // имя пользователя UserPass = "" // пароль или пустая строка }; // соединяемся с 1С77 // using (var _1c77 = sabatex.V1C77.COMObject1C77.CreateConnection(connection)) { // перебор всего справочника Контрагенты var contr = _1c77.GlobalContext.CreateObject("Справочник.Контрагенты"); if (contr.Method<double>("ВыбратьЭлементы") == 1) { while (contr.Method<double>("ПолучитьЭлемент")==1) { if (contr.Method<double>("ЭтоГруппа") == 1) continue; var name = contr.GetProperty<string>("Наименование"); Console.WriteLine(name); } } } } [/pre] соответствие типов данных 1С7.7 и C#
строка - string число - doubl дата - DataTime остальное - V1C77COMObject возможно использовать bool для замены double(0- false;1 - true ) тогда выражение сократится к if (contr.Method("ВыбратьЭлементы"))
Категория:
OLE, ActiveX Как получить координаты выделенной области на Яндекс Карте? На одном проекте потребовалось получать координаты выделенной области на яндекс карте, после долгих изучений получилось следующее:
Вид Формы: На карте выделяете объект, нажимаете кнопку Получить координаты выделенной области и заполняется таблица координат
Код инициализации карты и обработчик кнопки получения координат:
Код 1C v 8.х Процедура ИнициализироватьКарту()
ПутьКФайлу = КаталогВременныхФайлов()+"yamaps.html";
Ф = новый Файл(ПутьКФайлу);
Если Ф.Существует() Тогда
УдалитьФайлы(ПутьКФайлу);
КонецЕсли;
Т = новый ТекстовыйДокумент;
ТД = ЭтотОбъект.ПолучитьМакет("МакетЯндекс");
Т.УстановитьТекст(ТД.ПолучитьТекст());
Т.Записать(ПутьКФайлу);
ЭлементыФормы.Эксплорер.Перейти(ПутьКФайлу);
КонецПроцедуры
Процедура ВыполнитьСкрипт(Команда) Экспорт
ЭлементыФормы.Эксплорер.document.getElementById("WebClientOperation").value = Команда;
ЭлементыФормы.Эксплорер.document.getElementById("WebClient").click();
КонецПроцедуры
Процедура ПриОткрытии()
ИнициализироватьКарту();
КонецПроцедуры
Процедура ПолучитьКоординатыНажатие(Элемент)
ВыполнитьСкрипт("GetGEO();");
ТекКоординаты=ЭлементыФормы.Эксплорер.document.getElementById("geometry").innerText;
ТекКоординаты=СтрЗаменить(ТекКоординаты,"Координаты: [","");
МассивСтроки = ОбщегоНазначения.РазложитьСтрокуВМассивПодстрок(ТекКоординаты, "], [ ");
Точки.Очистить();
Для Каждого стр из МассивСтроки Цикл
Текстр=СтрЗаменить(стр,"[","");
Текстр=СтрЗаменить(Текстр,"]","");
Текстр=СокрЛП(Текстр);
нСтрок=Точки.Добавить();
симвЗапятой=Найти(Текстр,",");
нСтрок.Широта=Лев(Текстр,симвЗапятой-1);
нСтрок.Долгота=Сред(Текстр,симвЗапятой+2,СтрДлина(Текстр));
КонецЦикла;
//Сообщить(ТекКоординаты);
КонецПроцедуры
Макет
Код VBS <!DOCTYPE html">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0px; padding: 0px }
#map { height: 100% }
</style>
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>
<script src="http://yandex.st/jquery/1.6.4/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
var index = 1;
var MyMap, route;
var clusterer;
var PointArray = [];
var noclick = false;
ymaps.ready(init);
function init(){
myMap = new ymaps.Map ("map", {
center: [55.75, 37.62],
zoom: 10
}),
polygon = new ymaps.GeoObject({
geometry: {
type: "Polygon",
coordinates: []
}
});
myMap.behaviors.enable('scrollZoom');
myMap.behaviors.disable('dblClickZoom');
myMap.events.add('click', function (e) {
if (!noclick) {
// addMarker(e.get('coords'));
}else{
noclick = false;
}
});
myMap.events.add('drag end', function (e) {
noclick = true ;
document.getElementById('CoordX').value = "0";
document.getElementById('CoordY').value = "0";
});
// создадим кластеризатор и запретим приближать карту при клике на кластеры
//clusterer = new ymaps.Clusterer({clusterDisableClickZoom: true , synchAdd: true });
//myMap.geoObjects.add(clusterer);
myMap.geoObjects.add(polygon);
polygon.editor.startDrawing();
$('input').attr('disabled', false);
// Обработка нажатия на любую кнопку.
$('input').click(
function () {
// Отключаем кнопки, чтобы на карту нельзя было
// добавить более одного редактируемого объекта (чтобы в них не запутаться).
$('input').attr('disabled', true );
GetGEO();
});
}
function addMarker(coordPosition){
myPlacemark = new ymaps.Placemark(coordPosition, {
// Свойства
// Текст метки
iconContent: 'Точка'+index
}, {
// Опции
// Иконка метки будет растягиваться под ее контент
preset: 'islands#blueStretchyIcon'
});
myMap.geoObjects.add(myPlacemark);
document.getElementById('CoordX').value = coordPosition[0].toPrecision(15);
document.getElementById('CoordY').value = coordPosition[1].toPrecision(15);
index++;
}
function calcRoute(options){
ymaps.route(options, {
// Опции маршрутизатора
mapStateAutoApply: true , // автоматически позиционировать карту
avoidTrafficJams: false // Учитывать пробки
}).then(
function (router) {
route = router;
myMap.geoObjects.add(route);
//заполняем и сохраняем инфо про маршрут
document.getElementById('RouteInfo').value = "Длина маршрута - " + route.getHumanLength() + ". Время - " + route.getHumanJamsTime();
//генерация события для перехвата в 1С
var evt = document.createEventObject();
document.body.fireEvent('ondatasetcomplete', evt);
},
function (error) {
alert("Возникла ошибка: " + error.message);
});
}
function calcLine(options){
var poly = new ymaps.Polyline(options, {
hintContent: "Маршрут",
balloonContent: "Маршрут экспедитора",
balloonContentHeader: "",
balloonContentBody: "",
balloonContentFooter: ""
}, {
cursor: "pointer",
draggable: false,
hasBalloon: true ,
hasHint: true ,
interactiveZIndex: false,
opacity: 1,
openBalloonOnClick: true ,
openEmptyBalloon: false,
openEmptyHint: false,
openHintOnHover: true ,
strokeColor: '#E33926',
strokeOpacity: 0.8,
strokeStyle: '',
strokeWidth: 5,
syncOverlayInit: false,
visible: true
});
myMap.geoObjects.add(poly);
myMap.setBounds(poly.geometry.getBounds());
}
function Reset(){
// Удаляем все геообъекты на карте
myMap.geoObjects.removeAll();
PointArray = [];
index = 1;
}
function ChangeCityMSK(){
myMap.panTo([55.75, 37.62], {
flying: 1
});
}
function ChangeCitySPB(){
myMap.panTo([59.938531, 30.313497], {
flying: 1
});
}
function ChangeCityKRAS(){
myMap.panTo([45.04, 38.97], {
flying: 1
});
}
function ChangePlace(k,d){
myMap.panTo([k, d], {
flying: 1
});
}
function FindAdres(Adres){
Reset();
var myGeocoder = ymaps.geocode(Adres);
myGeocoder.then(
function (res){
var firstGeoObject = res.geoObjects.get(0);
if(firstGeoObject != null){
myMap.panTo(
// Координаты нового центра карты
firstGeoObject.geometry.getCoordinates(), {
/* Опции перемещения:
разрешить уменьшать и затем увеличивать зум
карты при перемещении между точками
*/
flying: true
}
);
myPlacemark = new ymaps.Placemark(firstGeoObject.geometry.getCoordinates(), {
// Свойства
// Текст метки
iconContent: Adres
}, {
// Опции
// Иконка метки будет растягиваться под ее контент
preset: 'islands#blueStretchyIcon'
});
myMap.geoObjects.add(myPlacemark);
}else{
alert("Ничего не найдено");}
}
);
}
function ReverseSearchAdres(CoordX, CoordY, Adres){
Reset();
var CoordPosition = [CoordX, CoordY];
myMap.panTo(
// Координаты нового центра карты
CoordPosition, {
/* Опции перемещения:
разрешить уменьшать и затем увеличивать зум
карты при перемещении между точками
*/
flying: true
}
);
myPlacemark = new ymaps.Placemark(CoordPosition, {
// Свойства
// Текст метки
iconContent: Adres
}, {
// Опции
// Иконка метки будет растягиваться под ее контент
preset: 'islands#blueStretchyIcon'
});
myMap.geoObjects.add(myPlacemark);
}
function addToPointArrayM(CoordX, CoordY, TextC, Text){
var CoordPosition = [CoordX, CoordY];
myPlacemark = new ymaps.Placemark(CoordPosition, {
// Свойства
// Текст метки
iconContent: Text
}, {
// Опции
// Иконка метки будет растягиваться под ее контент
preset: TextC
});
myMap.geoObjects.add(myPlacemark);
}
function addToPointArrayPointOne(CoordX, CoordY, ID, Text){
var point = new ymaps.GeoObject({
geometry: {type: "Point", coordinates: [CoordX, CoordY>,
properties: {
clusterCaption: ID,
iconContent: ID,
hintContent: ID,
balloonContent: Text,
balloonContentBody: Text
}
});
myMap.geoObjects.add(point);
}
function addToPointArray(CoordX, CoordY, ID, Text){
var point = new ymaps.GeoObject({
geometry: {type: "Point", coordinates: [CoordX, CoordY>,
properties: {
clusterCaption: ID,
iconContent: ID,
hintContent: ID,
balloonContent: Text,
balloonContentBody: Text
}
});
PointArray.push(point);
}
function drawCluster(){
clusterer.add(PointArray);
myMap.geoObjects.add(clusterer);
}
function createPolygon(ArrayPoint, Name, color) {
// Создаем многоугольник
myPolygon = new ymaps.Polygon([
// Координаты вершин внешней границы многоугольника.
ArrayPoint
], {
//Свойства
hintContent: Name
}, {
// Опции.
// Цвет заливки (зеленый)
fillColor: color,
// Цвет границ (синий)
strokeColor: '#0000FF',
// Прозрачность (полупрозрачная заливка)
opacity: 0.6,
// Ширина линии
strokeWidth: 5,
// Стиль линии
strokeStyle: 'shortdash'
});
myMap.geoObjects.add(myPolygon);
}
function WebClientClick() {
//очистка перед кликом координат, иначе после клика в упр. формах идет считывание координат
document.getElementById('CoordX').value = "0";
document.getElementById('CoordY').value = "0";
var WebClientOperation = document.getElementById("WebClientOperation").value;
//alert(WebClientOperation);
switch (WebClientOperation) {
case "0": // ничего не делаем
var a = 1;
default: // запускаем функцию
eval(WebClientOperation);
}
document.getElementById('WebClientOperation').value = "0";
}
function GetGEO(){
polygon.editor.stopEditing();
printGeometry(polygon.geometry.getCoordinates());
}
// Выводит массив координат геообъекта в <div id="geometry">
function printGeometry (coords) {
$('#geometry').html('Координаты: ' + stringify(coords));
function stringify (coords) {
var res = '';
if ($.isArray(coords)) {
res = '[ ';
for (var i = 0, l = coords.length; i < l; i++) {
if (i > 0) {
res += ', ';
}
res += stringify(coords[i]);
}
res += ' ]';
} else if (typeof coords == 'number') {
res = coords.toPrecision(6);
} else if (coords.toString) {
res = coords.toString();
}
return res;
}
}
</script>
</head>
<body>
<div id="geometry"/></div>
<div id="map" style="width:100%; height:100%"></div>
<input type="hidden" id="CoordX" name="CoordX" value="0"></input>
<input type="hidden" id="CoordY" name="CoordY" value="0"></input>
<input type="hidden" id="RouteInfo" name="RouteInfo" value=""></input>
<input type="hidden" id="WebClientOperation" name="WebClientOperation" value="0"></input>
<input type="hidden" id="WebClient" name="WebClient" onclick="WebClientClick();"></input>
<!-- <input type="button" value="Завершить редактирование" id="stopEditPolyline"/> -->
</body>
</html>
Категория:
Географическая схема Google maps : вывод точек на карту и режим панорамы В отличие от яндекс карт в GMaps можно использовать панорамы - за что им большой плюс! Надеюсь в яндексе прочитают этот пост и тоже когда-нибудь это сделают!
Для клиента нужно было сделать вывод объектов на карту
С возможностью просмотра панорамы:
Основной HTML код карты хранится в макете:
Код VBS <!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=8">
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0px; padding: 0px }
#map { height: 100% }
</style>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?v=3.9&sensor=false"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript" src="http://www.sitedev.by/lab/markerclusterer/markerclusterer.js"></script>
<script type="text/javascript">
var latlng;
var markers = [];
var myMap;
var index = 1;
var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
var infoWindow = new google.maps.InfoWindow;
var clusterer, mcOptions;
var trafficLayer = new google.maps.TrafficLayer();
var trafficOn = false;
var noclick = false;
var PointArray = [];
var polygons = [];
function initialize() {
directionsDisplay = new google.maps.DirectionsRenderer();
latlng = new google.maps.LatLng(55.75, 37.62);
var myOptions = {
zoom: 12,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
disableDoubleClickZoom: true ,
panControl: true ,
zoomControl: true ,
mapTypeControl: true ,
scaleControl: true ,
streetViewControl: true ,
overviewMapControl: true
};
myMap = new google.maps.Map(document.getElementById("map"),
myOptions);
google.maps.event.addListener(myMap, 'dragend', function() {
noclick = true ;
document.getElementById('CoordX').value = "0";
document.getElementById('CoordY').value = "0";
});
google.maps.event.addListener(myMap, 'click', function(event) {
infoWindow.close();
if (!noclick) {
addMarker(event.latLng);
}else{
noclick = false;
}
});
mcOptions = {gridSize: 3, maxZoom: 15};
clusterer = new MarkerClusterer(myMap, markers, mcOptions);
//отображение кнопки управления трафиком - все спер с примера, только подцепил свою функцию
var trafficControlDiv = document.createElement('div');
trafficControlDiv.style.padding = '5px';
// Set CSS for the control border
var controlUI = document.createElement('div');
controlUI.style.backgroundColor = 'white';
controlUI.style.borderStyle = 'solid';
controlUI.style.borderWidth = '2px';
controlUI.style.cursor = 'pointer';
controlUI.style.textAlign = 'center';
controlUI.title = 'нажмите для вкл/выкл трафика';
trafficControlDiv.appendChild(controlUI);
// Set CSS for the control interior
var controlText = document.createElement('div');
controlText.style.fontFamily = 'Arial,sans-serif';
controlText.style.fontSize = '12px';
controlText.style.paddingLeft = '4px';
controlText.style.paddingRight = '4px';
controlText.innerHTML = '<b>Трафик</b>';
controlUI.appendChild(controlText);
google.maps.event.addDomListener(controlUI, 'click', function (){
if (!trafficOn){
trafficOn = true ;
trafficLayer.setMap(myMap);
}else{
trafficOn = false;
trafficLayer.setMap(null);
}
});
trafficControlDiv.index = 1;
myMap.controls[google.maps.ControlPosition.TOP_RIGHT].push(trafficControlDiv);
};
//добавляем маркер и отправляем в массив
function addMarker(location) {
marker = new google.maps.Marker({
position: location,
map: myMap,
title: 'Точка'+index
});
infoWindow.setContent(marker.title);
infoWindow.open(myMap, marker);
google.maps.event.addListener(marker, 'click', function(){
var mark = this;
var latLng = mark.getPosition();
infoWindow.setContent(mark.title);
infoWindow.open(myMap, mark);});
markers.push(marker);
index++;
document.getElementById('CoordX').value = location.lat();
document.getElementById('CoordY').value = location.lng();
}
function calcRoute(options) {
//вытягиваем из массива переданных параметров значения
//и преобразуем их в формат LatLng
var option1 = options[0];//начальная точка
var option2 = options[1];//промежуточные точки
var option3 = options[2];//конечная точка
var start = new google.maps.LatLng(option1[0], option1[1]); //первый
var end = new google.maps.LatLng(option3[0], option3[1]); //последний
//получаем транзитные точки
var waypts = [];
if(option2.length > 0) {
for(var i = 0, l = option2.length; i < l; i++) {
temp = option2[i];
Qcoord = new google.maps.LatLng(temp[0], temp[1])
waypts.push({
location:Qcoord,
stopover:true
});
}
}
//return;
var request = {
origin: start,
destination: end,
waypoints: waypts,
optimizeWaypoints: true ,
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setMap(myMap);
directionsDisplay.setDirections(response);
var total = 0;
var myroute = response.routes[0];
for (i = 0; i < myroute.legs.length; i++) {
total += myroute.legs[i].distance.value;
}
total = total / 1000;
document.getElementById('RouteInfo').value = "Длина маршрута - " + total + "км.";
//генерация события для перехвата в 1С
var evt = document.createEventObject();
document.body.fireEvent('ondatasetcomplete', evt);
}else{
alert(status);
}
});
}
function Reset(){
directionsDisplay.setMap(null);
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
markers = [];
index = 1;
//обнуляем кластер маркеров
clusterer.clearMarkers();
for (var i = 0; i < polygons.length; i++) {
polygons[i].setMap(null);
}
polygons = [];
PointArray = [];
}
function FindAdres(Adres){
Reset();
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': Adres}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
latlng = results[0].geometry.location;
myMap.panTo(latlng);
marker = new google.maps.Marker({
map: myMap,
position: latlng,
animation: google.maps.Animation.BOUNCE,
title:Adres
});
markers.push(marker);
infoWindow.setContent(marker.title);
infoWindow.open(myMap, marker);
} else {
alert("Ничего не найдено: " + status);
}
});
}
function ReverseSearchAdres(CoordX, CoordY, Adres){
Reset();
latlng = new google.maps.LatLng(CoordX, CoordY);
myMap.panTo(latlng);
var marker = new google.maps.Marker({
map: myMap,
position: latlng,
animation: google.maps.Animation.BOUNCE,
title:Adres
});
markers.push(marker);
infoWindow.setContent(marker.title);
infoWindow.open(myMap, marker);
}
function addToPointArray(CoordX, CoordY, ID, IconT, Text){
var latLng = new google.maps.LatLng(CoordX, CoordY);
var point = new google.maps.Marker({'position': latLng, title: Text, icon: IconT});
PointArray.push(point);
}
function drawCluster(){
clusterer.addMarkers(PointArray);
//myMap.geoObjects.add(clusterer);
}
function createPolygon(ArrayPoint, Name, color) {
//создаем массив координат вершин многоугольника
var paths = [];
for(var i = 0, l = ArrayPoint.length; i < l; i++) {
var temp = ArrayPoint[i];
Qcoord = new google.maps.LatLng(temp[0], temp[1])
paths.push(Qcoord);
};
// Создаем многоугольник
myPolygon = new google.maps.Polygon({
paths: paths,
strokeColor: color,
strokeOpacity: 0.6,
strokeWeight: 5,
fillColor: "#0000FF"
});
myPolygon.setMap(myMap);
polygons.push(myPolygon);
}
function WebClientClick() {
//очистка перед кликом координат, иначе после клика в упр. формах идет считывание координат
document.getElementById('CoordX').value = "0";
document.getElementById('CoordY').value = "0";
var WebClientOperation = document.getElementById("WebClientOperation").value;
//alert(WebClientOperation);
switch (WebClientOperation) {
case "0": // ничего не делаем
var a = 1;
default: // запускаем функцию
eval(WebClientOperation);
}
document.getElementById('WebClientOperation').value = "0";
}
</script>
</head>
<body onload="initialize()">
<div id="map" style="width:100%; height:100%"></div>
<input type="hidden" id="CoordX" name="CoordX" value="0"></input>
<input type="hidden" id="CoordY" name="CoordY" value="0"></input>
<input type="hidden" id="RouteInfo" name="RouteInfo" value=""></input>
<input type="hidden" id="WebClientOperation" name="WebClientOperation" value="0"></input>
<input type="hidden" id="WebClient" name="WebClient" onclick="WebClientClick();"></input>
</body>
</html>
Код вывода карты:
Код 1C v 8.х Процедура ИнициализироватьКарту()
ПутьКФайлу = КаталогВременныхФайлов()+"Карта.html";
Ф = новый Файл(ПутьКФайлу);
Если Ф.Существует() Тогда
УдалитьФайлы(ПутьКФайлу);
КонецЕсли;
Т = новый ТекстовыйДокумент;
ТД = ЭтотОбъект.ПолучитьМакет("МакетГугл");
Т.УстановитьТекст(ТД.ПолучитьТекст());
Т.Записать(ПутьКФайлу);
ЭлементыФормы.Эксплорер.Перейти(ПутьКФайлу);
КонецПроцедуры
Процедура ОчиститьКарту()
ЭлементыФормы.Эксплорер.Документ.parentWindow.eval("Reset()");
КонецПроцедуры
//к сожалению, другого спососба получить "внутрь 1С" информацию о действии пользователя на карте я не сумел
//действие пользователя на карте изменяет поле HTML-документа, но не вызывает никакого события в 1с-ке
// поэтому через обработчикОжидания делаю непрерывный опрос карты
Процедура ПриОткрытии()
ИнициализироватьКарту();
КонецПроцедуры
// вывод точек на карту
Процедура ОсновныеДействияФормыОсновныеДействияФормыВыполнить(Кнопка)
ОчиститьКарту();
СписокВидов = Новый СписокЗначений;
Для Каждого стр из ВыборВывода Цикл
если стр.пометка тогда СписокВидов.Добавить(стр.наименование); КонецЕсли;
КонецЦикла;
табАдресов.Очистить();
табАдресов = получитьтабАдресов(СписокВидов);
табУникальныхАдресов = табАдресов.скопировать();
табУникальныхАдресов.свернуть("Уник");
тзДанных = табАдресов.скопировать();
табАдресов.очистить();
Для Каждого стр из табУникальныхАдресов Цикл
Отбор = Новый Структура();
Отбор.Вставить("Уник",стр.Уник);
Строки = тзДанных.НайтиСтроки(Отбор);
НовСтр = табАдресов.добавить();
НовСтр.уник = стр.уник;
Если Строки.Количество() > 0 Тогда
для Каждого тздстр из Строки Цикл
НовСтр.Адрес = тздстр.Адрес;
НовСтр.КД = тздстр.КД;
НовСтр.КШ = тздстр.КШ;
НовСтр.ВидОбъекта = тздстр.ВидОбъекта;
НовСтр.Наименование=Строка(НовСтр.Наименование)+Строка(тздстр.Наименование)+"; ";
КонецЦикла;
КонецЕсли;
КонецЦикла;
ЭлементыФормы.табАдресов.СоздатьКолонки();
ВыборМасштаба = "50%";
ВыборРегиона = "Москва";
ЭлементыФормы.Надпись24.Заголовок = "Точек: "+Строка(табАдресов.количество());
Кол = табАдресов.Количество();
Индекс = 0;
Для Каждого ТекСтрока Из табАдресов Цикл Индекс = Индекс + 1; Если НЕ ЗначениеЗаполнено(ТекСтрока.КД) тогда Продолжить; КонецЕсли;
Широта = формат(ТекСтрока.КШ, "ЧРД=.");
Долгота = формат(ТекСтрока.КД, "ЧРД=.");
СодержимоеТочки = СокрЛП(ТекСтрока.ВидОбъекта)+": "+ СокрЛП(ТекСтрока.адрес); //опять же можно вставить свое название
Попытка
ЭлементыФормы.Эксплорер.Документ.parentWindow.eval("addToPointArray(" + Широта + "," + Долгота + ", '" + Строка(Индекс) + "', '" + СокрЛП(ТекСтрока.ВидОбъекта.ПутьКИконке)+ "', """ + СодержимоеТочки + """);");
Исключение
Сообщить("addToPointArray(" + Широта + "," + Долгота + ", '" + Строка(Индекс) + "', '" + СокрЛП(ТекСтрока.ВидОбъекта.ПутьКИконке)+ "', """ + СодержимоеТочки + """);",СтатусСообщения.Внимание);
КонецПопытки;
Состояние("Вывожу на карту " + Индекс + " из " + кол);
КонецЦикла;
ЭлементыФормы.Эксплорер.Документ.parentWindow.eval("drawCluster();");
КонецПроцедуры
Вырванная из конфигурации обработка GMaps.rar
Можно ее использовать как макет для создания обработки под свои требования.
Пример автоматизации в котором это использовалось.
Категория:
Географическая схема Яндекс карта : вывод точек на карту Пример о том,как вывести яндекс карту на форму и далее работать с ней:
Основной HTML код карты хранится в макете:
Код VBS <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Примеры. Геокодирование.</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="http://api-maps.yandex.ru/1.1/index.xml?key=ANpUFEkFAAAAf7jmJwMAHGZHrcLKDsbEqEVjEUtCmufxQMwAAAAAAAAAAAAvVrubVT4btztbduoIgTLAeFILaQ==" type="text/javascript"></script>
<script type="text/javascript">
var router;
var myPoints = new Array();
var myRouts = new Array();
var strOpen = "OPEN";
var strKontr = "Kontragent";
var t = new YMaps.Template('<b>$[name]</b><div id="descrID" >$[description]</div>');
YMaps.Templates.add("my#template", t);
var KopdinatShirota = 0;
var KopdinatDolgota = 0;
var UID_Zakaza = "";
/*vstavkaStiley;
var map, geoResult;
YMaps.jQuery(function () {
map = new YMaps.Map(YMaps.jQuery("#YMapsID")[0]);
map.setCenter(new YMaps.GeoPoint(37.62, 55.75), 12);
});
function showAddress (value, contrag, Styles, UID) {
var geocoder = new YMaps.Geocoder(value, {results: 1, boundedBy: map.getBounds()});
YMaps.Events.observe(geocoder, geocoder.Events.Load, function () {
if (this.length()) {
geoResult = this.get(0);
var point = new YMaps.GeoPoint(geoResult._point.__lng, geoResult._point.__lat);
var placemark = new YMaps.Placemark(point, {style: Styles});
placemark.name = UID;
placemark.description = contrag;
myPoints.push(placemark);
map.addOverlay(placemark);
return placemark;
}else {
}
});
YMaps.Events.observe(geocoder, geocoder.Events.Fault, function (geocoder, error) {
alert("Произошла ошибка: " + error);
return null;
})
}
function showAddressCoord (shirota, dolgota, contrag, Styles, UID) {
var point = new YMaps.GeoPoint(dolgota, shirota);
var placemark = new YMaps.Placemark(point, {style: Styles});
placemark.name = UID;
placemark.description = contrag;
myPoints.push(placemark);
map.addOverlay(placemark);
return placemark;
}
function removeAllOverlays (map) {
map.removeAllOverlays();
}
function AddRoute(wayPoint1, wayPoint2) {
if (myRouts.length>0) {lastRouter = myRouts[myRouts.length-1]; map.removeOverlay(lastRouter)};
var myRouter = new YMaps.Router([wayPoint1, wayPoint2], [], {viewAutoApply: true });
map.addOverlay(myRouter);
YMaps.Events.observe(myRouter, myRouter.Events.Success, function (myRouter) {
myRouter.getWayPoint(0).setIconContent('Начало маршрута');
myRouter.getWayPoint(1).setIconContent('Конец маршрута');
dlMar = myRouter.getDistance()/1000;
document.title = 'Дистанция: '+ dlMar.toFixed(2);
});
myRouts.push(myRouter);
return true ;
}
function mapRazmer(map, SentrSh, SentrDlg, razmer) {
map.setCenter(new YMaps.GeoPoint(SentrSh, SentrDlg), razmer);
}
function changeStyle(numTochki, imStyle){
var restoreDefault = true ;
tochka = myPoints[numTochki];
tochka.setOptions({style: imStyle}, restoreDefault);
point = tochka.getCoordPoint();
map.setCenter(new YMaps.GeoPoint(point.__lng, point.__lat), 12);
map.redraw();
return tochka.description;
}
</script>
</head>
<body //~~onload~~>
<div id="YMapsID" style="width:100%;height:100%"></div>
</form>
</body>
</html>
Код вывода карты:
Код 1C v 8.х //берем HTML-текст из макета и доделываем его
//создаем столько стилей, сколько есть различных картинок в папке "icons_"
//Загружаем в поле HTML-документа
//и позиционируем центр карты на Москву
Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)
Макет = ПолучитьМакет("Макет");
КодХТМЛ = Макет.ПолучитьТекст();
СтрокаСтиляНачальная = "var BurG = new YMaps.Style();
|BurG.iconStyle = new YMaps.IconStyle();
|BurG.iconStyle.offset = new YMaps.Point(-12, -12);
|BurG.iconStyle.href = ""http://www.burgerking.ru/favicon.ico"";
|BurG.iconStyle.size = new YMaps.Point(20, 20);
|BurG.hideIcon = false;
|BurG.balloonContentStyle = new YMaps.BalloonContentStyle(""my#template"");";
СтрокаСтиляИтоговая = "";
//
//имяКаталогаКартинок = "D:\!1C\MAPS\icons_";
//КаталогКартинок = Новый Файл(имяКаталогаКартинок);
//Если КаталогКартинок.ЭтоКаталог() тогда
// списокИменКартинок = новый таблицаЗначений;
// списокИменКартинок.Колонки.Добавить("ИмяСтиля");
// списокИменКартинок.Колонки.Добавить("ИмяФайлаКартинки");
// МассивНайденных = НайтиФайлы(имяКаталогаКартинок, "*.gif");
// Для Каждого Файл из МассивНайденных Цикл
//
// времСтрокаСтиля = СтрокаСтиляНачальная;
// времСтрокаСтиля = стрЗаменить(времСтрокаСтиля, "BurG", сокрЛП(Файл.ИмяБезРасширения));
// времСтрокаСтиля = стрЗаменить(времСтрокаСтиля, "C:/icons_/kv2_5_x.gif", "C:/icons_/" + сокрЛП(Файл.Имя));
//
// СтрокаСтиляИтоговая = СтрокаСтиляИтоговая + времСтрокаСтиля + символы.ПС;
//
// КонецЦикла;
//конецЕсли;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВидыОбъектов.Ссылка,
| ВидыОбъектов.ПутьКИконке,
| ВидыОбъектов.Код
|ИЗ
| Справочник.ВидыОбъектов КАК ВидыОбъектов
|ГДЕ
| ВидыОбъектов.ПометкаУдаления = ЛОЖЬ";
Результат = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = Результат.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
времСтрокаСтиля = СтрокаСтиляНачальная;
времСтрокаСтиля = стрЗаменить(времСтрокаСтиля, "BurG", "s"+Строка(ВыборкаДетальныеЗаписи.код));
времСтрокаСтиля = стрЗаменить(времСтрокаСтиля, "http://www.burgerking.ru/favicon.ico", сокрЛП(ВыборкаДетальныеЗаписи.ПутьКИконке));
СтрокаСтиляИтоговая = СтрокаСтиляИтоговая + времСтрокаСтиля + символы.ПС;
КонецЦикла;
СтрокаСтиляИтоговая = СтрокаСтиляИтоговая + СтрокаСтиляНачальная + символы.ПС;
КодХТМЛ = стрЗаменить(КодХТМЛ, "/*vstavkaStiley;", СтрокаСтиляИтоговая);
путьККаталогуКартинок = СтрЗаменить(КаталогПрограммы(), "\", "/");
КодХТМЛ = СтрЗаменить(КодХТМЛ,"C:/",путьККаталогуКартинок);
ЭлементыФормы.Карта.УстановитьТекст(КодХТМЛ);
табАдресов = получитьтабАдресов();
табУникальныхАдресов = табАдресов.скопировать();
табУникальныхАдресов.свернуть("Уник");
тзДанных = табАдресов.скопировать();
табАдресов.очистить();
Для Каждого стр из табУникальныхАдресов Цикл
Отбор = Новый Структура();
Отбор.Вставить("Уник",стр.Уник);
Строки = тзДанных.НайтиСтроки(Отбор);
НовСтр = табАдресов.добавить();
НовСтр.уник = стр.уник;
Если Строки.Количество() > 0 Тогда
для Каждого тздстр из Строки Цикл
НовСтр.Адрес = тздстр.Адрес;
НовСтр.КД = тздстр.КД;
НовСтр.КШ = тздстр.КШ;
НовСтр.ВидОбъекта = тздстр.ВидОбъекта;
НовСтр.Наименование=Строка(НовСтр.Наименование)+Строка(тздстр.Наименование)+"; ";
КонецЦикла;
КонецЕсли;
КонецЦикла;
ЭлементыФормы.табАдресов.СоздатьКолонки();
ВыборМасштаба = "50%";
ВыборРегиона = "Москва";
ЭлементыФормы.Надпись24.Заголовок = "Точек: "+Строка(табАдресов.количество());
КонецПроцедуры
// Вывод точек на карту
Процедура ОсновныеДействияФормыОсновныеДействияФормыВыполнить(Кнопка)
//имя стиля совпадает с именем картинки без расширения
Всего=Строка(табАдресов.Количество()); н=0;
Для каждого строкаАдреса Из табАдресов Цикл
н=н+1; Состояние("Вывод "+Строка(н)+" из "+Всего);
////ЭТО ПРИМЕР ВЫВОДА ТОГО ИЛИ ИНОГО МАРКЕРА В ЗАВИСИМОСТИ ОТ НЕКОЕГО ПАРАМЕТРА
//Если строкаАдреса.ДокументПродажи.суммаДокумента <1000 тогда
// имяСтиля = "BurG";
//ИначеЕсли строкаАдреса.ДокументПродажи.суммаДокумента <10000 тогда
// имяСтиля = "tr2_3_x";
//ИначеЕсли строкаАдреса.ДокументПродажи.суммаДокумента <20000 тогда
// имяСтиля = "kv3_4_x";
//ИначеЕсли строкаАдреса.ДокументПродажи.суммаДокумента <50000 тогда
// имяСтиля = "tr4_1_x";
//ИначеЕсли строкаАдреса.ДокументПродажи.суммаДокумента <100000 тогда
// имяСтиля = "kv5_2_x";
//Иначе
// имяСтиля = "cr6_3_x";
//конецЕсли;
УИД_Дока = Строка(н);
имяСтиля = "s"+Строка(строкаАдреса.ВидОбъекта.код);
Попытка
Если ЗначениеЗаполнено(строкаАдреса.КД) Тогда
ВызовФункции = "showAddressCoord(" + сокрЛП(строкаАдреса.КШ) + ", " + сокрЛП(строкаАдреса.КД) + ", '"+ сокрЛП(строкаАдреса.адрес) + "', " + имяСтиля + ", '" + сокрЛП(строкаАдреса.ВидОбъекта.наименование) + "')";
Иначе
ВызовФункции = "showAddress('" + сокрЛП(строкаАдреса.адрес) + "', '" + сокрЛП(строкаАдреса.адрес) + "', " + имяСтиля + ", '" + сокрЛП(строкаАдреса.ВидОбъекта.наименование) + "')";
КонецЕсли;
ЭлементыФормы.Карта.Document.parentWindow.eval(ВызовФункции);
исключение
Сообщить("Точка с адресом " + сокрЛП(строкаАдреса.адрес) + " не может быть отбражена на карте!" );
конецПопытки
КонецЦикла;
ТочкиНеСозданы = Ложь;
ЭлементыФормы.Карта.ПолучитьТекст();
КонецПроцедуры
//Изменение масштаба
Процедура Кнопка1Нажатие(Элемент)
если ЭлементыФормы.ВыборРегиона.значение = "Москва" Тогда
СтрокаКоординат = "37.64, 55.76, ";
ИначеЕсли ЭлементыФормы.ВыборРегиона.значение = "Тверь" Тогда
СтрокаКоординат = "35.90, 56.83, ";
ИначеЕсли ЭлементыФормы.ВыборРегиона.значение = "Балашиха" Тогда
СтрокаКоординат = "37.97, 55.82, ";
Иначе
СтрокаКоординат = "37.64, 55.76, ";
конецесли;
Если ВыборМасштаба = "" тогда
возврат;
конецесли;
числоМасштаба = Число(Лев(ВыборМасштаба, стрдлина(ВыборМасштаба)-1));
числоМасштаба = числоМасштаба + 5;
ВыборМасштаба = строка(числоМасштаба) + "%";
ТекущийМасштаб = Строка(Цел((числоМасштаба/125)*(20)+4));
если стрДлина(ТекущийМасштаб) =1 тогда
ТекущийМасштаб = "0" + ТекущийМасштаб;
конецесли;
ЭлементыФормы.Карта.Document.parentWindow.eval("mapRazmer(map," + СтрокаКоординат + ТекущийМасштаб + ")");
КонецПроцедуры
Пример обратного геокодирования - получение координат по адресу:
Код 1C v 8.х Процедура ПолучитьКоординаты() Экспорт
Яндекс = Новый HTTPСоединение("geocode-maps.yandex.ru",,,,,Истина);
ВременныйФайл = КаталогВременныхФайлов() + "Yandex_geocode_" + СокрЛП(Новый УникальныйИдентификатор);
Попытка
Яндекс.Получить("/1.x/?geocode=" + Адрес + "&results=1", ВременныйФайл);
Исключение
Сообщить("Ошибка при попытке геокодировать по яндексу адрес: " + Адрес);
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ВременныйФайл);
ПостроительDOM = Новый ПостроительDOM;
ДокументДОМ = ПостроительDOM.Прочитать(ЧтениеXML);
СписокText = ДокументДОМ.ПолучитьЭлементыПоИмени("text");
СписокPos = ДокументДОМ.ПолучитьЭлементыПоИмени("pos");
Если (СписокText.Количество() = 0) ИЛИ (СписокPos.Количество() = 0) Тогда
Возврат;
КонецЕсли;
Для ъ = 0 по СписокText.Количество()-1 Цикл
Координаты = СписокPos[Ъ].ТекстовоеСодержимое;
Разделитель = Найти(Координаты," ");
Широта = Число(Сред(Координаты, Разделитель + 1));
Долгота = Число(Лев(Координаты, Разделитель - 1));
Если Широта = 0 ИЛИ Долгота = 0 Тогда
Продолжить;
КонецЕсли;
КД = Долгота;
КШ = Широта;
КонецЦикла;
КонецПроцедуры
Обработка вырванная из конфигурации: YandexMap.rar
Можно ее использовать как макет для создания обработки под свои требования.
Пример автоматизации в котором это использовалось.
Категория:
Географическая схема Синтаксический анализ JSON - выражения средствами 1С 7.7 Код 1C v 7.x
Перем Л_Лев_Фиг_Скобка, Л_Прав_Фиг_Скобка, Л_Лев_Кв_Скобка, Л_Прав_Кв_Скобка, Л_Кавычка, Л_Экран, Л_Двоеточие, Л_Запятая, Л_Число, Л_Строка, Л_Константа, Л_Финиш;
Перем Цифры1_9, Цифры0_9, ПервыеСимволыКонстант, ОдносимвольныеЛексемы;
Перем НомЛексемы, ТекЛексема;
Перем JSON_Error;
Перем В_Массив, В_Объект, В_Значение;
//*****
Перем НомерСимвола;
Перем ФлагОшибки;
Перем СписокСтроковыхКонстант;
Перем СтекЛексем;
Перем АнализируемаяСтрока;
//*****
Перем ТекКаталог, ТекФайл;
//*****
Функция ПолучитьОбъект_ТЗ() Далее
Функция ПолучитьМассив_ТЗ() Далее
//*****
Функция ТекущиеСимволы(Сколько)
Возврат Сред(АнализируемаяСтрока, НомерСимвола, Сколько);
КонецФункции
//*****
Функция ПрошлыйСимвол(Сдвиг)
Возврат Сред(АнализируемаяСтрока, НомерСимвола - Сдвиг, 1);
КонецФункции
//*****
Процедура ДобавитьЛексему(Лексема, Значение, Сдвиг)
СтекЛексем.НоваяСтрока();
СтекЛексем.Лексема = Лексема;
СтекЛексем.Значение = Значение;
НомерСимвола = НомерСимвола + Сдвиг;
КонецПроцедуры
//*****
Процедура ОбвестиОбласть(Обл)
Обл.РамкаСнизу(1);
Обл.РамкаСверху(1);
Обл.РамкаСлева(1);
Обл.РамкаСправа(1);
КонецПроцедуры
//*****
Процедура НапечататьТЗ(Таб, ТЗ, НомС, НомК)
Перем Тип, Обл1, НС, КС, Ключ, Зн, Обл2;
Тип = ТЗ.ПолучитьЗначение(1, 1);
НомС = НомС + 1;
Обл1 = Таб.Область(НомС, НомК);
ОбвестиОбласть(Обл1);
Если Тип = В_Значение Тогда
ТипЗн = ТЗ.ПолучитьЗначение(2, 1);
Обл1.Текст = ТЗ.ПолучитьЗначение(2, 2);
Обл1.ГоризонтальноеПоложение(1);
Если ТипЗн = Л_Число Тогда
Обл1.ГоризонтальноеПоложение(2);
ИначеЕсли ТипЗн = Л_Константа Тогда
Обл1.Полужирный(1);
ИначеЕсли ТипЗн = Л_Строка Тогда
Обл1.Контроль(4);
КонецЕсли;
Возврат;
ИначеЕсли (Тип = В_Объект) Или (Тип = В_Массив) Тогда
Обл1.Текст = Тип;
Обл1.Полужирный(1);
Обл1.ЦветФона(12648447);
Обл1.РамкаСнизу(5);
КС = ТЗ.КоличествоСтрок();
Для НС = 2 По КС Цикл
НомС = НомС + 1;
Обл2 = Таб.Область(НомС, НомК);
Обл2.Текст = ТЗ.ПолучитьЗначение(НС, 1);
Если Тип = В_Массив Тогда
Обл2.ГоризонтальноеПоложение(2);
КонецЕсли;
ОбвестиОбласть(Обл2);
НомС = НомС - 1;
НапечататьТЗ(Таб, ТЗ.ПолучитьЗначение(НС, 2), НомС, НомК + 1);
КонецЦикла;
Иначе
Сообщить("Фигня " + Тип, "!");
КонецЕсли;
КонецПроцедуры
//*****
Процедура ВыравнятьТЗ(Таб, ОграничениеШирины)
Перем НомерКол, НомерСтр, МаксШирина, Обл, ТекШирина, ТекДлина;
Для НомерКол = 1 По Таб.ШиринаТаблицы() Цикл
МаксШирина = 0;
Для НомерСтр = 1 По Таб.ВысотаТаблицы() Цикл
Обл = Таб.Область(НомерСтр, НомерКол);
ТекШирина = Обл.ШиринаСтолбца();
ТекДлина = СтрДлина(СокрЛП(Обл.Текст));
МаксШирина = Макс(МаксШирина, ТекШирина, ТекДлина);
КонецЦикла;
Таб.Область(, НомерКол).ШиринаСтолбца(Мин(МаксШирина, ОграничениеШирины));
КонецЦикла;
КонецПроцедуры
//*****
Процедура Напечатать_ТЗ(ТЗ)
Перем Таб, НС, НК, МаксШирина, ТекДлина, Обл;
Таб = СоздатьОбъект("Таблица");
МаксНК = 1;
НС = 0;
НК = 1;
НапечататьТЗ(Таб, ТЗ, НС, НК);
ВыравнятьТЗ(Таб, 30);
Таб.Область(1, 1, Таб.ВысотаТаблицы(), Таб.ШиринаТаблицы()).ВертикальноеПоложение(2);
Таб.Опции(0, 0);
Таб.Показать("JSON");
КонецПроцедуры
//*****
Функция Ошибка()
ФлагОшибки = 1;
Возврат 0;
КонецФункции
//*****
Функция ЧитатьКонстанту(ПервСимвол)
Перем КонстантаСтр, ДлинаКонстанты;
КонстантаСтр = СписокСтроковыхКонстант.Получить(ПервСимвол);
ДлинаКонстанты = СтрДлина(КонстантаСтр);
Если ТекущиеСимволы(ДлинаКонстанты) = КонстантаСтр Тогда
ДобавитьЛексему(Л_Константа, КонстантаСтр, ДлинаКонстанты);
Возврат 1;
Иначе
Возврат Ошибка();
КонецЕсли;
КонецФункции
//*****
Процедура ДописатьСимвол(Стр)
Стр = Стр + ТекущиеСимволы(1);
НомерСимвола = НомерСимвола + 1;
КонецПроцедуры
//*****
Функция ЧитатьЧисло()
Перем ЧислоСтр;
ЧислоСтр = "";
Если ТекущиеСимволы(1) = "-" Тогда
ДописатьСимвол(ЧислоСтр);
КонецЕсли;
Если Найти(Цифры1_9, ТекущиеСимволы(1)) > 0 Тогда // не с нуля
ДописатьСимвол(ЧислоСтр);
Пока Найти(Цифры0_9, ТекущиеСимволы(1)) > 0 Цикл // любые цыфры
ДописатьСимвол(ЧислоСтр);
КонецЦикла;
ИначеЕсли ТекущиеСимволы(1) = "0" Тогда //с нуля - ничего дальше
ДописатьСимвол(ЧислоСтр);
Иначе
Возврат Ошибка();
КонецЕсли;
Если ТекущиеСимволы(1) = "." Тогда // десятичная точка
ДописатьСимвол(ЧислоСтр);
Пока Найти(Цифры0_9, ТекущиеСимволы(1)) > 0 Цикл // любые цыфры
ДописатьСимвол(ЧислоСтр);
КонецЦикла;
КонецЕсли;
Если ВРег(ТекущиеСимволы(1)) = "E" Тогда // значок e больное или маленькое
ДописатьСимвол(ЧислоСтр);
Если Найти("+-", ТекущиеСимволы(1)) > 0 Тогда // унарный знак для порядка
ДописатьСимвол(ЧислоСтр);
КонецЕсли;
Пока Найти(Цифры0_9, ТекущиеСимволы(1)) > 0 Цикл // любые цыфры
ДописатьСимвол(ЧислоСтр);
КонецЦикла;
КонецЕсли;
ДобавитьЛексему(Л_Число, ЧислоСтр, 0);
Возврат 1;
КонецФункции
//*****
Функция ЧитатьСтроку()
Перем СтрокаСтр;
СтрокаСтр = "";
НомерСимвола = НомерСимвола + 1;
Пока (ТекущиеСимволы(1) <> Л_Кавычка) Или ((ТекущиеСимволы(1) = Л_Кавычка) И (ПрошлыйСимвол(1) = Л_Экран) И (ПрошлыйСимвол(2) <> Л_Экран)) Цикл
ДописатьСимвол(СтрокаСтр);
КонецЦикла;
ДобавитьЛексему(Л_Строка, СтрокаСтр, 1);
Возврат 1;
КонецФункции
//*****
Функция ПрочитатьФайл(ИмяФайла)
Перем Т, НомерСтрокиФайла, СтрокаРез;
Т = СоздатьОбъект("Текст");
Т.Открыть(ИмяФайла);
СтрокаРез = "";
Для НомерСтрокиФайла = 1 По Т.КоличествоСтрок() Цикл
СтрокаРез = СтрокаРез + Т.ПолучитьСтроку(НомерСтрокиФайла);
КонецЦикла;
Возврат СтрокаРез;
КонецФункции
//*****
Функция СледующаяЛексема()
НомЛексемы = НомЛексемы + 1;
СтекЛексем.ПолучитьСтрокуПоНомеру(НомЛексемы);
ТекЛексема = СтекЛексем.Лексема;
Возврат 1;
КонецФункции
//*****
Функция ОшибкаЛексемы()
Перем РезСтр, НомСтр, ТЛ, ТС;
Сообщить("Ошибочная лексема № " + НомЛексемы + " : <" + ТекЛексема + ">", "!");
РезСтр = "";
Для НомСтр = НомЛексемы + 1 По СтекЛексем.КоличествоСтрок() Цикл
СтекЛексем.ПолучитьСтрокуПоНомеру(НомСтр);
ТЛ = СтекЛексем.Лексема;
Если ТЛ = Л_Строка Тогда
ТС = "<" + ТЛ + "(" + СтекЛексем.Значение + ")>";
ИначеЕсли ТЛ = Л_Константа Тогда
ТС = "<" + ТЛ + "(" + СтекЛексем.Значение + ")>";
Иначе
ТС = "<" + ТЛ + ">";
КонецЕсли;
РезСтр = РезСтр + ТС + ",";
КонецЦикла;
Сообщить(Лев(РезСтр, 400), "!");
Возврат 0;
КонецФункции
//*****
Процедура ДобавитьПару(ТЗ, Ключ, Значение)
ТЗ.НоваяСтрока();
ТЗ.Ключ = Ключ;
ТЗ.Значение = Значение;
КонецПроцедуры
//*****
Функция НоваяТЗ(Тип)
Перем _ТЗ;
_ТЗ = СоздатьОбъект("ТаблицаЗначений");
_ТЗ.НоваяКолонка("Ключ");
_ТЗ.НоваяКолонка("Значение");
ДобавитьПару(_ТЗ, Тип, "");
Возврат _ТЗ;
КонецФункции
//*****
Функция ПолучитьПроизвольноеЗначение_ТЗ()
Перем ТЗ;
Если (ТекЛексема = Л_Строка) Или (ТекЛексема = Л_Число) Или (ТекЛексема = Л_Константа) Тогда
ТЗ = НоваяТЗ(В_Значение);
ДобавитьПару(ТЗ, ТекЛексема, СтекЛексем.Значение);
СледующаяЛексема();
Возврат ТЗ;
ИначеЕсли ТекЛексема = Л_Лев_Фиг_Скобка Тогда
Возврат ПолучитьОбъект_ТЗ();
ИначеЕсли ТекЛексема = Л_Лев_Кв_Скобка Тогда
Возврат ПолучитьМассив_ТЗ();
КонецЕсли;
Возврат ОшибкаЛексемы();
КонецФункции
//*****
Функция ДобавитьКлючЗначение(ТЗ)
Перем НовКлюч, НовЗначение;
Если ТекЛексема <> Л_Строка Тогда
Возврат 0;
КонецЕсли;
НовКлюч = СтекЛексем.Значение;
СледующаяЛексема();
Если ТекЛексема <> Л_Двоеточие Тогда
Возврат ОшибкаЛексемы();
КонецЕсли;
СледующаяЛексема();
НовЗначение = ПолучитьПроизвольноеЗначение_ТЗ();
Если НовЗначение = 0 Тогда
Возврат 0;
КонецЕсли;
ДобавитьПару(ТЗ, НовКлюч, НовЗначение);
Возврат 1;
КонецФункции
//*****
Функция ПолучитьОбъект_ТЗ()
Перем ТЗ;
ТЗ = НоваяТЗ(В_Объект);
СледующаяЛексема();
Если ТекЛексема = Л_Прав_Фиг_Скобка Тогда // пустой объект
СледующаяЛексема();
Возврат ТЗ;
КонецЕсли;
Если ДобавитьКлючЗначение(ТЗ) = 0 Тогда // первая пара ключ-значение
Возврат 0;
КонецЕсли;
Пока ТекЛексема = Л_Запятая Цикл // пока запятые
СледующаяЛексема();
Если ДобавитьКлючЗначение(ТЗ) = 0 Тогда // пара ключ-значение
Возврат 0;
КонецЕсли;
КонецЦикла;
Если ТекЛексема = Л_Прав_Фиг_Скобка Тогда
СледующаяЛексема();
Возврат ТЗ;
КонецЕсли;
Возврат 0;
КонецФункции
//*****
Функция ПолучитьМассив_ТЗ()
Перем ТЗ, _Ключ, _Значение;
ТЗ = НоваяТЗ(В_Массив);
СледующаяЛексема();
Если ТекЛексема = Л_Прав_Кв_Скобка Тогда
СледующаяЛексема();
Возврат ТЗ;
КонецЕсли;
_Значение = ПолучитьПроизвольноеЗначение_ТЗ();
Если _Значение = 0 Тогда
Возврат 0;
КонецЕсли;
_Ключ = 0; // JS - индексы массиворв с нуля
ДобавитьПару(ТЗ, _Ключ, _Значение);
Пока ТекЛексема = Л_Запятая Цикл
СледующаяЛексема();
_Значение = ПолучитьПроизвольноеЗначение_ТЗ();
Если _Значение = 0 Тогда
Возврат 0;
КонецЕсли;
_Ключ = _Ключ + 1;
ДобавитьПару(ТЗ, _Ключ, _Значение);
КонецЦикла;
Если ТекЛексема = Л_Прав_Кв_Скобка Тогда
СледующаяЛексема();
Возврат ТЗ;
КонецЕсли;
Возврат 0;
КонецФункции
//*****
Функция ПрочитатьОбъект_ТЗ()
Перем Рез;
НомЛексемы = 0;
СледующаяЛексема();
Если ТекЛексема = Л_Лев_Фиг_Скобка Тогда
Рез = ПолучитьОбъект_ТЗ();
ИначеЕсли ТекЛексема = Л_Лев_Кв_Скобка Тогда
Рез = ПолучитьМассив_ТЗ();
Иначе
Рез = ПолучитьПроизвольноеЗначение_ТЗ();
КонецЕсли;
Если (Рез = 0) Или (ТекЛексема <> Л_Финиш) Тогда
ОшибкаЛексемы();
Возврат 0;
КонецЕсли;
Возврат Рез;
КонецФункции
//*****
Функция СгенерироватьТЗ(НачАнализируемаяСтрока)
Перем НачальныйСимвол, Рез;
АнализируемаяСтрока = НачАнализируемаяСтрока;
СтекЛексем = СоздатьОбъект("ТаблицаЗначений");
СтекЛексем.НоваяКолонка("Лексема" , "Строка");
СтекЛексем.НоваяКолонка("Значение", "Строка");
ФлагОшибки = 0;
НомерСимвола = 1;
Пока НомерСимвола <= СтрДлина(АнализируемаяСтрока) Цикл
НачальныйСимвол = ТекущиеСимволы(1);
Если Найти(" " + Симв(9), НачальныйСимвол) > 0 Тогда // пробелы и разделители строк пропускаем
НомерСимвола = НомерСимвола + 1;
ИначеЕсли НачальныйСимвол = Л_Кавычка Тогда // кавычка - читаем строку
ЧитатьСтроку();
ИначеЕсли Найти(ОдносимвольныеЛексемы, НачальныйСимвол) > 0 Тогда
ДобавитьЛексему(НачальныйСимвол, "", 1);
ИначеЕсли Найти(ПервыеСимволыКонстант, НачальныйСимвол) > 0 Тогда // первая буква из начала константы - константа null, true , false
Если ЧитатьКонстанту(НачальныйСимвол) = 0 Тогда
Прервать;
КонецЕсли;
ИначеЕсли Найти("-" + Цифры0_9, НачальныйСимвол) > 0 Тогда // число
Если ЧитатьЧисло() = 0 Тогда
Прервать;
КонецЕсли;
Иначе // иных вариантов нет
Сообщить("========= " + НомерСимвола, "!");
Сообщить(НачальныйСимвол, "!");
Сообщить("<" + НачальныйСимвол + "> " + КодСимв(НачальныйСимвол), "!");
Сообщить(ТекущиеСимволы(100), "!");
Возврат 0;
КонецЕсли;
КонецЦикла;
Если ФлагОшибки <> 0 Тогда
Сообщить("Ошибка парсинга JSON - выражения", "!");
Возврат 0;
ИначеЕсли СтекЛексем.КоличествоСтрок() = 0 Тогда
Сообщить("Пустой стек", "!");
Возврат 0;
КонецЕсли;
ДобавитьЛексему(Л_Финиш, "", 0);
Возврат ПрочитатьОбъект_ТЗ();
КонецФункции
//*****
Функция JSON_Error(Стр = "")
Если Стр <> "" Тогда
Сообщить("JSON-ОШИБКА: " + Стр, "!");
КонецЕсли;
Возврат JSON_Error;
КонецФункции
//*****
Функция JSON_Type(Парам)
Если ТипЗначенияСтр(Парам) <> "ТаблицаЗначений" Тогда
Возврат JSON_Error();
ИначеЕсли Парам.КоличествоКолонок() <> 2 Тогда
Возврат JSON_Error();
ИначеЕсли Парам.КоличествоСтрок() < 2 Тогда
Возврат JSON_Error();
КонецЕсли;
Возврат Парам.ПолучитьЗначение(1, 1);
КонецФункции
//*****
Функция JSON_GetValue(Парам, Keys)
Перем Тип, До, После, ПозЗакр, Л1, П2, Инд, ИндСтр, НС, КвоСтрок;
Тип = JSON_Type(Парам);
ПозЗакр = Найти(Keys, "]");
Если ПозЗакр = 0 Тогда
ПозЗакр = СтрДлина(Keys) + 1;
КонецЕсли;
До = Лев(Keys, ПозЗакр);
После = Сред(Keys, ПозЗакр + 1);
Л1 = Лев(До, 1);
П2 = Найти(До, "]");
Если Тип = JSON_Error Тогда
Возврат JSON_Error("Параметра");
КонецЕсли;
КвоСтрок = Парам.КоличествоСтрок();
Если До = "" Тогда // сам объект
Если (Тип = В_Массив) Или (Тип = В_Объект) Тогда
Возврат JSON_Error();
ИначеЕсли Тип = В_Значение Тогда
Возврат Парам.ПолучитьЗначение(2, 2);
Иначе
Возврат JSON_Error("№ 1");
КонецЕсли;
ИначеЕсли До = ".length" Тогда // размер массива или объекта. Для значения - ошибка
Если (Тип = В_Массив) Или (Тип = В_Объект) Тогда
Возврат Парам.КоличествоСтрок() - 1;
Иначе
Возврат JSON_Error("Длина скаляра");
КонецЕсли;
ИначеЕсли Л1 = "[" Тогда // размер массива или объекта. Для значения - ошибка
Если П2 = 0 Тогда
Возврат JSON_Error("Индексация: <" + До + ">");
КонецЕсли;
Инд = Сред(До, 2, П2 - 2);
Если (Найти("'""", Лев(Инд, 1)) > 0) И (Найти("'""", Прав(Инд, 1)) > 0) Тогда // строковый только объект
ИндСтр = Сред(Инд, 2, СтрДлина(Инд) - 2);
Если Тип <> В_Объект Тогда
Возврат JSON_Error("Строковый индекс <" + ИндСтр + "> только для Объекта");
КонецЕсли;
НС = 0;
Если Парам.НайтиЗначение(ИндСтр, НС, 1) = 1 Тогда
Возврат JSON_GetValue(Парам.ПолучитьЗначение(НС, 2), После);
КонецЕсли;
Возврат JSON_Error("Нет индекса <" + ИндСтр + ">");
КонецЕсли;
ИндЧис = 0 + Инд;
Если "" + ИндЧис <> Инд Тогда // защита от <5D>
Возврат JSON_Error("Ошибка 1 числового индекса <" + Инд + ">");
ИначеЕсли Цел(ИндЧис) <> ИндЧис Тогда // защита от неЦелого индекса
Возврат JSON_Error("Ошибка 2 числового индекса <" + Инд + "> (нецелый)");
ИначеЕсли ИндЧис < 0 Тогда
Возврат JSON_Error("Ошибка 3 числового индекса <" + Инд + "> (отрицательный)");
ИначеЕсли ИндЧис > (КвоСтрок - 2) Тогда
Возврат JSON_Error("Ошибка 4 числового индекса <" + Инд + "> (" + ИндЧис + ">" + (КвоСтрок - 2) + ")");
КонецЕсли;
Возврат JSON_GetValue(Парам.ПолучитьЗначение(ИндЧис + 1, 2), После);
Иначе
Возврат JSON_Error("Ошибка 5 <" + До + ">");
КонецЕсли;
КонецФункции
//*****
Процедура ПриОткрытии()
Перем Рез1, ТипУзла1, Зн1, Значение;
ОчиститьОкноСообщений();
СтатусВозврата(0);
Рез1 = СгенерироватьТЗ(ПрочитатьФайл(ТекКаталог + "j1.json"));
Напечатать_ТЗ(Рез1);
ТипУзла1 = JSON_Type(Рез1);
Сообщить("Тип узла: " + ТипУзла1);
Зн1 = JSON_GetValue(Рез1, ".length"); Сообщить("1) Размер: " + Зн1);
Зн3 = JSON_GetValue(Рез1, "['1']"); Сообщить("3) ['1']: <" + Зн3 + ">");
Зн4 = JSON_GetValue(Рез1, "[1]"); Сообщить("4) [1]: <" + Зн4 + ">");
Зн5 = JSON_GetValue(Рез1, "['Массив'][6]"); Сообщить("5) [*]: <" + Зн5 + ">");
Зн6 = JSON_GetValue(Рез1, "['Соответствие']['ДопустимоеИмяСвойства']"); Сообщить("6) [*]: <" + Зн6 + ">");
КонецПроцедуры
//*****
Процедура ДобавитьСтроковуюКонстанту(КонстантаСтр)
Перем ПервыйСимвол;
ПервыйСимвол = Лев(КонстантаСтр, 1);
ПервыеСимволыКонстант = ПервыеСимволыКонстант + ПервыйСимвол;
СписокСтроковыхКонстант.Установить(ПервыйСимвол, КонстантаСтр);
КонецПроцедуры
//*****
РасположениеФайла(ТекКаталог, ТекФайл);
//*****
Л_Лев_Фиг_Скобка = "{";
Л_Прав_Фиг_Скобка = "}";
Л_Лев_Кв_Скобка = "[";
Л_Прав_Кв_Скобка = "]";
Л_Двоеточие = ":";
Л_Запятая = ",";
Л_Экран = "\";
Л_Кавычка = """";
Л_Финиш = "";
Л_Число = "number";
Л_Строка = "string";
Л_Константа = "const";
ОдносимвольныеЛексемы = Л_Лев_Фиг_Скобка + Л_Прав_Фиг_Скобка + Л_Лев_Кв_Скобка + Л_Прав_Кв_Скобка + Л_Двоеточие + Л_Запятая;
//*****
Цифры1_9 = "123456789";
Цифры0_9 = "0" + Цифры1_9;
//*****
В_Массив = "###array";
В_Объект = "###object";
В_Значение = "###value";
//*****
СписокСтроковыхКонстант = СоздатьОбъект("СписокЗначений");
ПервыеСимволыКонстант = "";
ДобавитьСтроковуюКонстанту("null");
ДобавитьСтроковуюКонстанту("false");
ДобавитьСтроковуюКонстанту("true ");
JSON_Error = "ERROR";
В качестве примера взят файл j1.json :
{
"999": 88,
"Null": null,
"Сэкраном": "\"",
"Ложь": false,
"ОдинСимв": "1",
"1": "11111",
"Пустышка": "",
"Истина": true ,
"Число (плавающая точка)": 1.001e-2,
"Число (плавающая)": -1.001e-2,
"Число (фиксированная точка)": -1000.001,
"Дата": "2011-01-01T12:00:00Z",
"Строка (двойная кавычка)": "Двойная кавычка",
"Строка (одинарная кавычка)": "Одинарная кавычка",
"Маскируемые символы": " \\ \/ \b \t \n \f \r \" ",
"Заковыристая строка": "\\n\\",
"Проблемные символы": "Спец. символы: \u0000, \u0001, \u0002, ... , \u001e, \u001f; Юникод символы: \u0421\u0430\u0448\u0430\u0020\u003a\u0029",
"Кириллические символы": "’АБВГҐДЂЃЕ?ЁЄЖЗЅИ?ІЇЙЈКЛЉМНЊОПРСТЋЌУЎФХЦЧЏШЩЪЫЬЭЮЯ",
"Идентификатор": "a763cfbb-f94f-4c67-8e13-0e96a3a7f353",
"Пустой массив": [],
"Пустой объект": {},
"Массив": [
null,
false,
true ,
1.001e-2,
-1000.001,
"2011-01-01T12:00:00Z",
"Двойная кавычка",
"Одинарная кавычка",
"a763cfbb-f94f-4c67-8e13-0e96a3a7f353",
[
"Первый элемент",
"Второй элемент"
],
{
"Имя": "Александр",
"Отчество": "Владимирович",
"Фамилия": "Переверзев"
},
{
"ДопустимоеИмяСвойства": true ,
"Недопустимое Имя Свойства": false
}
],
"Структура":
{
"Имя": "Александр",
"Отчество": "Владимирович",
"Фамилия": "Переверзев"
},
"Соответствие":
{
"ДопустимоеИмяСвойства": true ,
"Недопустимое Имя Свойства": false
},
"Ссылка":
{
"Ссылка": "00000000-0000-0000-0000-000000000000",
"Представление": "Неизвестная ссылка"
},
"COMSafeArray": [
0,
1,
2,
3,
4,
5
]
}
Категория:
HTML, JS, VML Обмен данными с сайтом используя формат JSON в 1С Формат JSON в 1С до версии 8.3.6 не реализован, но нижет я приведу примеры функций которые можно использовать для полноценной работы JSON в 1С предыдущий версий.
JSON (JavaScript Object Notation) это текстовый формат обмена данными, широко используемый в веб-приложениях. По сравнению с XML он является более лаконичным и занимает меньше места. Кроме этого все браузеры имеют встроенные средства для работы с JSON.
Необходимость работы с этим форматом на уровне платформы обусловлена не только тем, что это «модный современный» формат, который прикладные решения 1С:Предприятия сами по себе могут использовать для интеграции со сторонними приложениями. Другая причина заключается ещё и в том, что JSON активно используется в HTTP интерфейсах. А в 1С:Предприятии как раз есть такие механизмы, в которых хочется использовать этот формат. Это REST интерфейс приложения, автоматически генерируемый платформой, и HTTP-сервисы, которые вы можете создавать самостоятельно.
В платформе с версии 8.3.6: Потоковое чтение и запись JSON:
Объекты потоковой работы - это общие объекты ЧтениеJSON и ЗаписьJSON. Они последовательно читают JSON из файла или строки, или последовательно записывают JSON в файл или строку. Таким образом, чтение и запись JSON происходят без формирования всего документа в памяти.
В качестве иллюстрации потокового чтения JSON можно привести следующий пример:
Код 1C v 8.3 // Пример чтения JSON.
ЧтениеJSON = Новый ЧтениеJSON;
// Либо открыть файл, из которого будет выполняться чтение, // либо установить строку, из которой будет выполняться чтение.
ЧтениеJSON.ОткрытьФайл("ИмяФайла");
//ЧтениеJSON.УстановитьСтроку("СтрокаJSON");
Пока ЧтениеJSON.Прочитать() Цикл
TипJSON = ЧтениеJSON.ТипТекущегоЗначения;
Если TипJSON = ТипЗначенияJSON.Число ИЛИ TипJSON = ТипЗначенияJSON.Строка ИЛИ TипJSON = ТипЗначенияJSON.Булево ИЛИ TипJSON = ТипЗначенияJSON.Null Тогда
// Обработать значение
Значение = ЧтениеJSON.ТекущееЗначение;
ИначеЕсли ТипJSON = ТипЗначенияJSON.Комментарий Тогда
// Обработать комментарий
Комментарий = ЧтениеJSON.ТекущееЗначение;
ИначеЕсли TипJSON = ТипЗначенияJSON.ИмяСвойства Тогда
// Обработать имя свойства
ИмяСвойства = ЧтениеJSON.ТекущееЗначение;
ИначеЕсли TипJSON = ТипЗначенияJSON.НачалоМассива ИЛИ TипJSON = ТипЗначенияJSON.КонецМассива ИЛИ TипJSON = ТипЗначенияJSON.НачалоОбъекта ИЛИ TипJSON = ТипЗначенияJSON.КонецОбъекта ИЛИ TипJSON = ТипЗначенияJSON.Ничего Тогда
// Обработать начало/коней массива/объекта или отсутствие данных, // ТекущееЗначение читать не нужно.
КонеиЕсли;
КокецЦикла;
ЧтениеJSON.Закрыть();
// При записи JSON вы самостоятельно формируете его структуру. Чтобы «подстраховать» вас от ошибок, объект ЗаписьJSON автоматически проверяет правильность записываемой структуры.
// Для увеличения скорости работы эту проверку можно отключить. В примере ниже это строка:
ЗаписьJSON.ПроверятьСтруктуру = Ложь;
// Также при записи вы можете управлять некоторыми параметрами формируемого текста, например использованием двойных кавычек, переносом строк, символами отступа и экранированием символов.
// В примере ниже для форматирования текста используется символ табуляции:
ПараметрыЗаписиJSON = Новый ПараметрыЗаписиJSON( , Символы.Таб) ;
ЗаписьJSON.ОткрытьФайл("ИмяФайла", , , ПараметрыЗаписиJSON);
// Потоковая запись JSON может выглядеть следующим образом. Записывается массив из четырёх элементов. Три из них примитивного типа, а четвёртый элемент - это объект с двумя свойствами:
// Пример записи JSON. ЗаписьJSON = Новый ЗаписьJSON;
// Для увеличения скорости работы можно отключить автоматическую проверку // правильности структуры записываемого документа JSON. ЗаписьиЗСЖ.ПроверятьСтруктуру = Ложь;
// Для красоты результирующего текста можно увеличить "лесенку".
// Стандартный отступ - 1 пробел.
ПараметрыЗаписиJSON = Новый ПараметрыЗаписиJSON( , Символы.Таб);
// Либо открыть файл, в который будет выполнена запись,
// либо указать, что запись будет выполнена в строку, которую вернет метод Закрыть().
ЗаписьJSON.ОткрытьФайл("ИмяФайла", , , ПараметрыЗаписиJSON);
//ЗаписьJSON.УстановитьСтроку(ПараметрыЗаписиJSON);
// Записать массив.
ЗаписьJSON.ЗаписатьНачалоОбъекта();
ЗаписьJSON.ЗаписатьИмяСвойства("СвойствоТипаМассив");
ЗаписьJSON.ЗаписатьНачалоМассива();
// Первый элемент массива - Строка. ЗаписьJSON.ЗаписатьЗначение("Значение строка");
// Второй элемент массива - Число. ЗаписьJSON.ЗаписатьЗначение(12.345, Истина);
// Третий элемент массива - Булево. ЗаписьJSON-ЗаписатьЗначение(Истина);
// Четвертый элемент массива - объект с двумя свойствами. ЗаписьJSON.ЗаписатьНачалоОбъекта();
// Первое свойство объекта - Строка
ЗаписьJSON.ЗаписатьИмяСвойства("СвойствоТипаСтрока");
ЗаписьJSON.ЗаписатьЗначение("Значение строка");
// Второе свойство объекта - Неопределено
ЗаписьJSON.ЗаписатьИмяСвойства("СвойствоТипаНеопределено");
ЗаписьJSON.ЗаписатьЗначение(Неопределено);
ЗаписьJSON.ЗаписатьКонецОбъекта();
Запись JSON. ЗаписатьКонецМассива () ;
ЗаписьJSON.ЗаписатьКонецОбъекта();
ЗаписьJSON.Закрыть();
//CTpoKaJSON = ЗаписьJSON.Закрыть();
Результат такой записи:
Код 1C v 8.х
{
"СвойствоТипаМассив": [
"Значение строка",
1.2345E1,
true ,
{
"СвойствоТипаСтрока": "Значение строка",
"СвойствоТипаНеопределено": null
}
]
}
Сериализация примитивных типов и коллекций в JSON
Вторая группа средств работы с JSON хороша тем, что избавляет вас от рутинной работы по чтению/записи каждого отдельного значения или свойства. При чтении документы JSON отображаются в фиксированный набор типов платформы: Строка, Число, Булево, Неопределено, Массив, ФиксированныйМассив, Структура, ФиксированнаяСтруктура, Соответствие, Дата. Соответственно, в обратную сторону, композиция объектов этих типов позволяет сформировать в памяти и быстро записать в файл структуру JSON. Таким образом, чтение и запись небольшого объема JSON заранее известной структуры можно производить немногими строчками кода.
Основное назначение этих средств мы видим в обмене информацией с внешними системами, чтении конфигурационных файлов в формате JSON.
Сериализацию вы можете выполнять с помощью методов глобального контекста ПрочитатьJSON() и ЗаписатьJSON(). Они работают в связке с объектами ЧтениеJSON и ЗаписьJSON.
В качестве примера десериализации JSON можно рассмотреть чтение массива из двух объектов:
Код 1C v 8.3 // В качестве примера десериализации JSON можно рассмотреть чтение массива из двух объектов:
[
{
"имя": "Anton",
"фамилия": "Иванов",
"возраст": 25
},
{
"имя": "Ирина",
"фамилия": "Иванова",
"возраст": 20
}
]
// Код 1С:Предприятия, выполняющий десериализацию, может выглядеть следующим образом:
// Пример чтения JSON.
ЧтениеJSON = Новый ЧтениеJSON();
ЧтениеJSON.ОткрытьФайл("ИмяФайла");
Сотрудники = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
Для каждого Сотрудник из Сотрудники Цикл
// Обработать данные сотрудника.
ИмяСотрудника = Сотрудник.имя; ФамилияСотрудника = Сотрудник.фамилия; ВозрастСотрудника = Сотрудник.возраст;
КонецЦикла;
// А пример сериализации (записи) в JSON может выглядеть так:
// Пример записи JSON
Структура = Новый Структура;
Вставить("Фамилия","Иванов");
Зставить("Имя", "Иван");
Вставить("Отчество", "Иванович");
Зставить("Возраст", 40) ;
Зставить("Женат", Истина);
Телефоны = Новый Массив;
Телефоны.Добавить("8-999-999-99-90") ;
Телефоны.Добавить("8-999-999-99-91") ;
Структура.Вставить("Телефоны", Телефены);
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.ОткрытьФайл("ИмяФайла", , , Новый ПapaмeтpыЗaпиcиJS0N( , Символы.Таб) ) ;
ЗаписатьJSON(ЗаписьJSON, Структура);
ЗаписьJSON.Закрыть();
// Результат записи:
{
"Фамилия": "Иванов",
"Имя": "Иван",
"Отчество": "Иванович",
"Возраст": 40,
"Женат": true ,
"Телефоны": [
"8-999-999-99-90",
"8-999-999-99-91"
]
}
Подробнее вы можете посмотреть здесь
В платформе с версии 8.3.7: Полностью автоматизировали работу с JSON и реализовали в платформе третью группу средств. Они позволяют сериализовать в JSON прикладные типы 1С:Предприятия: ссылки, объекты, наборы записей и вообще любые типы, для которых поддерживается XDTO сериализация. Конечно же, мы обеспечили и обратную операцию - десериализацию. Зачем это нужно!?
Прежде всего, и в основном, XDTO сериализацию в JSON мы рекомендуем использовать при обмене данными между двумя прикладными решениями 1С:Предприятия. По сравнению с XML формат JSON более компактный, сериализация/десериализация в/из JSON выполняется быстрее. Кроме этого мы предприняли дополнительные меры для того, чтобы сократить объём передаваемых данных.
Кроме обмена между приложениями 1С:Предприятия этот механизм можно использовать и для обмена с внешними системами, готовыми принимать типы данных 1С:Предприятия. Например, XDTO сериализацию в JSON можно использовать для организации собственного HTTP интерфейса прикладного решения. Сервис на платформе 1С:Предприятия будет формировать ответ в памяти в виде строки JSON. А затем передавать её при помощи объекта HTTPСервисОтвет. Реализованный нами механизм сериализации полностью соответствует стандарту JSON. Поэтому внешняя система не должна испытывать каких-либо трудностей с десериализацией.
Использование XDTO сериализации в JSON для других задач видится нам маловероятным. Потому что если внешняя система не готова работать с прикладными типами 1С:Предприятия, то зачем их ей передавать? А если предполагается обмениваться только примитивными типами и коллекциями, то для этой задачи хорошо подходят методы ПрочитатьJSON() и ЗаписатьJSON(). Подробнее здесь
ДО платформы версии 8.3.6, т.е. 8.3.5 и ниже: На HelpF уже есть статья где описан пример: Работа с форматом JSON в 1С но не приведены функции, вот они:
Код 1C v 8.х Функция ПреобразоватьвСистему(Число10,система) Экспорт
Если система > 36 или система < 2 тогда
Сообщить("Выбранная система исчисления не поддерживается");
Возврат -1;
КонецЕсли;
СтрокаЗначений = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
СтрокаСистема = "";
Пока Число10 > 0 цикл
РезДеления = Число10/система;
ЧислоСистема = цел(РезДеления);
остатокОтДеления = Число10 - система*(ЧислоСистема);
СтрокаСистема = сред(СтрокаЗначений,остатокОтДеления+1,1)+ СтрокаСистема;
Число10 = ?(ЧислоСистема=0,0,РезДеления);
КонецЦикла;
Нечётное = стрДлина(СтрокаСистема) - цел(стрДлина(СтрокаСистема)/2)*2;
Если Нечётное тогда
СтрокаСистема = "0"+СтрокаСистема;
КонецЕсли;
Возврат СтрокаСистема;
КонецФункции
Функция URLEncode(стр) Экспорт
Длина=СтрДлина(Стр);
Итог="";
Для Н=1 По Длина Цикл
Знак=Сред(Стр,Н,1);
Код=КодСимвола(Знак);
если ((Знак>="a")и(Знак<="z")) или
((Знак>="A")и(Знак<="Z")) или
((Знак>="0")и(Знак<="9")) тогда
Итог=Итог+Знак;
Иначе
Если (Код>=КодСимвола("А"))И(Код<=КодСимвола("п")) Тогда
Итог=Итог+"%"+ПреобразоватьвСистему(208,16)+"%"+ПреобразоватьвСистему(144+Код-КодСимвола("А"),16);
ИначеЕсли (Код>=КодСимвола("р"))И(Код<=КодСимвола("я")) Тогда
Итог=Итог+"%"+ПреобразоватьвСистему(209,16)+"%"+ПреобразоватьвСистему(128+Код-КодСимвола("р"),16);
ИначеЕсли (Знак="ё") Тогда
Итог=Итог+"%"+ПреобразоватьвСистему(209,16)+"%"+ПреобразоватьвСистему(145,16);
ИначеЕсли (Знак="Ё") Тогда
Итог=Итог+"%"+ПреобразоватьвСистему(208,16)+"%"+ПреобразоватьвСистему(129,16);
Иначе
Итог=Итог+"%"+ПреобразоватьвСистему(Код,16);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат Итог;
КонецФункции
Функция СформироватьСтрокуJSONИзМассива(Объект)
СтрокаJSON = "[";
Для каждого Элемент Из Объект Цикл
Если ТипЗнч(Элемент) = Тип("Строка") Тогда
СтрокаJSON = СтрокаJSON + """" + Элемент + """";
ИначеЕсли ТипЗнч(Элемент) = Тип("Число") Тогда
СтрокаJSON = СтрокаJSON + СтрЗаменить(Строка(Элемент), Символы.НПП, "");
ИначеЕсли ТипЗнч(Элемент) = Тип("Булево") Тогда
СтрокаJSON = СтрокаJSON + Формат(Элемент, "БЛ=false; БИ=true ");
ИначеЕсли ТипЗнч(Элемент) = Тип("Дата") Тогда
СтрокаJSON = СтрокаJSON + Формат(Элемент - Дата(1970,1,1,1,0,0), "ЧГ=0");
ИначеЕсли ТипЗнч(Элемент) = Тип("Массив") Тогда
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON(Элемент);
ИначеЕсли ТипЗнч(Элемент) = Тип("Структура") Тогда
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON(Элемент);
ИначеЕсли ТипЗнч(Элемент) = Тип("ТаблицаЗначений") Тогда
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON(Элемент);
Иначе
СтрокаJSON = СтрокаJSON + """" + URLEncode(Строка(Элемент)) + """";
КонецЕсли;
СтрокаJSON = СтрокаJSON + ",";
КонецЦикла;
Если Прав(СтрокаJSON, 1) = "," Тогда
СтрокаJSON = Лев(СтрокаJSON, СтрДлина(СтрокаJSON)-1);
КонецЕсли;
Возврат СтрокаJSON + "]";
КонецФункции
Функция СформироватьСтрокуJSONИзСтруктуры(Объект)
СтрокаJSON = "{";
Для каждого Элемент Из Объект Цикл
Если Элемент.Значение = "" Тогда
Продолжить;
КонецЕсли;
СтрокаJSON = СтрокаJSON + """" + Элемент.Ключ + """" + ":";
Если ТипЗнч(Элемент.Значение) = Тип("Строка") Тогда
СтрокаJSON = СтрокаJSON + """" + Элемент.Значение + """";
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("Число") Тогда
СтрокаJSON = СтрокаJSON + СтрЗаменить(Строка(Элемент.Значение), Символы.НПП, "");
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("Булево") Тогда
СтрокаJSON = СтрокаJSON + Формат(Элемент.Значение, "БЛ=false; БИ=true ");
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("Дата") Тогда
СтрокаJSON = СтрокаJSON + Формат(Элемент.Значение - Дата(1970,1,1,1,0,0), "ЧГ=0");
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("Массив") Тогда
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON(Элемент.Значение);
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("Структура") Тогда
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON(Элемент.Значение);
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("ТаблицаЗначений") Тогда
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON(Элемент.Значение);
Иначе
СтрокаJSON = СтрокаJSON + """" + URLEncode(Строка(Элемент.Значение)) + """";
КонецЕсли;
СтрокаJSON = СтрокаJSON + ",";
КонецЦикла;
Если Прав(СтрокаJSON, 1) = "," Тогда
СтрокаJSON = Лев(СтрокаJSON, СтрДлина(СтрокаJSON)-1);
КонецЕсли;
Возврат СтрокаJSON + "}";
КонецФункции
Функция СформироватьСтрокуJSON(Объект) Экспорт
СтрокаJSON = "";
Если ТипЗнч(Объект) = Тип("Массив") Тогда
СтрокаJSON = СформироватьСтрокуJSONИзМассива(Объект);
ИначеЕсли ТипЗнч(Объект) = Тип("Структура") Тогда
СтрокаJSON = СформироватьСтрокуJSONИзСтруктуры(Объект);
ИначеЕсли ТипЗнч(Объект) = Тип("ТаблицаЗначений") Тогда
СоставСтруктуры = "";
Для каждого Колонка Из Объект.Колонки Цикл
СоставСтруктуры = СоставСтруктуры + ?(ЗначениеЗаполнено(СоставСтруктуры), ",", "") + Колонка.Имя;
КонецЦикла;
МассивСтрок = Новый Массив;
Для каждого Строка Из Объект Цикл
СтруктураКолонок = Новый Структура(СоставСтруктуры);
ЗаполнитьЗначенияСвойств(СтруктураКолонок, Строка);
МассивСтрок.Добавить(СтруктураКолонок);
КонецЦикла;
СтрокаJSON = СформироватьСтрокуJSONИзМассива(МассивСтрок);
КонецЕсли;
Возврат СтрокаJSON;
КонецФункции
Процедура ЗаполнитьДанныеИзОтветаJSON(Результат, ТекстJSON, ТипДанных)
ТекстJSON = СокрЛП(Сред(ТекстJSON, 2));
НомерЗначения = 0;
Пока ТекстJSON <> "" Цикл
ПервыйСимвол = Лев(ТекстJSON, 1);
Если ПервыйСимвол = "{" Тогда
Значение = Новый Структура;
ЗаполнитьДанныеИзОтветаJSON(Значение, ТекстJSON, "Структура");
Если ТипДанных = "Структура" Тогда
Результат.Вставить("Значение" + ?(НомерЗначения = 0, "", НомерЗначения), Значение);
НомерЗначения = НомерЗначения + 1;
ИначеЕсли ТипДанных = "Массив" Тогда
Результат.Добавить(Значение);
КонецЕсли;
ИначеЕсли ПервыйСимвол = "[" Тогда
Значение = Новый Массив;
ЗаполнитьДанныеИзОтветаJSON(Значение, ТекстJSON, "Массив");
Если ТипДанных = "Структура" Тогда
Результат.Вставить("Значение" + ?(НомерЗначения = 0, "", НомерЗначения), Значение);
НомерЗначения = НомерЗначения + 1;
Иначе
Результат.Добавить(Значение);
КонецЕсли;
ИначеЕсли ПервыйСимвол = "}" И ТипДанных = "Структура" Тогда
ТекстJSON = СокрЛП(Сред(ТекстJSON, 2));
Если Лев(ТекстJSON, 1) = "," Тогда
ТекстJSON = СокрЛП(Сред(ТекстJSON, 2));
КонецЕсли;
Возврат;
ИначеЕсли ПервыйСимвол = "]" И ТипДанных = "Массив" Тогда
ТекстJSON = СокрЛП(Сред(ТекстJSON, 2));
Если Лев(ТекстJSON, 1) = "," Тогда
ТекстJSON = СокрЛП(Сред(ТекстJSON, 2));
КонецЕсли;
Возврат;
Иначе
Если ТипДанных = "Структура" Тогда
Поз = Найти(ТекстJSON, ":");
Если Поз = 0 Тогда
Прервать;
КонецЕсли;
ИмяЗначения = СокрЛП(Лев(ТекстJSON, Поз-1));
ТекстJSON = СокрЛП(Сред(ТекстJSON, Поз+1));
Если Лев(ТекстJSON, 1) = "{" Тогда
Значение = Новый Структура;
ЗаполнитьДанныеИзОтветаJSON(Значение, ТекстJSON, "Структура");
ИначеЕсли Лев(ТекстJSON, 1) = "[" Тогда
Значение = Новый Массив;
ЗаполнитьДанныеИзОтветаJSON(Значение, ТекстJSON, "Массив");
Иначе
Поз = 0;
Для Сч = 1 По СтрДлина(ТекстJSON) Цикл
Символ = Сред(ТекстJSON, Сч, 1);
Если Символ = "," ИЛИ Символ = "]" ИЛИ Символ = "}" Тогда
Поз = Сч;
Прервать;
КонецЕсли;
КонецЦикла;
Если Поз = 0 Тогда
Значение = ТекстJSON;
ТекстJSON = "";
Иначе
Значение = Лев(ТекстJSON, Поз-1);
ТекстJSON = СокрЛП(Сред(ТекстJSON, Поз + ?(Сред(ТекстJSON, Поз, 1) = ",", 1, 0)));
КонецЕсли;
Значение = СокрЛП(Значение);
КонецЕсли;
Результат.Вставить(ИмяЗначения, Значение);
ИначеЕсли ТипДанных = "Массив" Тогда
Поз = 0;
Для Сч = 1 По СтрДлина(ТекстJSON) Цикл
Символ = Сред(ТекстJSON, Сч, 1);
Если Символ = "," ИЛИ Символ = "]" ИЛИ Символ = "}" Тогда
Поз = Сч;
Прервать;
КонецЕсли;
КонецЦикла;
Если Поз = 0 Тогда
Значение = ТекстJSON;
ТекстJSON = "";
Иначе
Значение = Лев(ТекстJSON, Поз-1);
ТекстJSON = СокрЛП(Сред(ТекстJSON, Поз + ?(Сред(ТекстJSON, Поз, 1) = ",", 1, 0)));
КонецЕсли;
Значение = СокрЛП(Значение);
Результат.Добавить(Значение);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция ЗаполнитьСтруктуруИзОтветаJSON(Знач ТекстJSON) Экспорт
Результат = Новый Структура;
ТекстJSON = СтрЗаменить(ТекстJSON, "\""", """");
ТекстJSON = СтрЗаменить(ТекстJSON, """", "");
Если Лев(ТекстJSON, 1) = "{" Тогда
ЗаполнитьДанныеИзОтветаJSON(Результат, ТекстJSON, "Структура");
ИначеЕсли Лев(ТекстJSON, 1) = "[" Тогда
МассивДанных = Новый Массив;
ЗаполнитьДанныеИзОтветаJSON(МассивДанных, ТекстJSON, "Массив");
Результат.Вставить("Значение", МассивДанных);
КонецЕсли;
Возврат Результат;
КонецФункции
Примеры их использования:
Код 1C v 8.х ////////////////////////////////////////////////////////
// преобразование простой структуры
Данные = Новый Структура("server,user,hash",
10234, 3745, "8263ad83ce");
СтрокаJSON = СформироватьСтрокуJSONИзСтруктуры(Данные);
// результатом будет строка
// {"server":"10234","user":"3745","hash":"8263ad83ce"}
////////////////////////////////////////////////////////
// преобразования массива
Данные = Новый Массив;
Данные.Добавить("Nissan");
Данные.Добавить("Ford");
Данные.Добавить("Audi");
СтрокаJSON = СформироватьСтрокуJSONИзСтруктуры(Данные);
// результатом будет строка
// ["Nissan","Ford","Audi"]
////////////////////////////////////////////////////////
// преобразование сложной структуры
Данные = Новый Структура;
Данные.Добавить("server", 10234);
Данные.Добавить("users", Новый Массив);
Данные.Добавить("hash", "8263ad83ce");
Данные.users.Добавить(3745);
Данные.users.Добавить(7462);
Данные.users.Добавить(2374);
СтрокаJSON = СформироватьСтрокуJSONИзСтруктуры(Данные);
// результатом будет строка
// {"server":"10234","users":["3745","7462","2374"],"hash":"8263ad83ce"}
////////////////////////////////////////////////////////
// еще один пример массива
Данные = Новый Структура;
Данные.Вставить("server", 10234);
Данные.Вставить("users", Новый Массив);
Данные.users.Добавить(Новый Структура("id,name", 3745, "Jack"));
Данные.users.Добавить(Новый Структура("id,name", 7246, "Nick"));
СтрокаJSON = СформироватьСтрокуJSONИзСтруктуры(Данные);
// результатом будет строка
// {"server":"10234","users":[{"id":"3745","name":"Jack"},{"id":"7462","name":"Nick"}>
////////////////////////////////////////////////////////
// преобразование таблицы значений
ТаблПользователей = Новый ТаблицаЗначений;
ТаблПользователей.Колонки.Добавить("id");
ТаблПользователей.Колонки.Добавить("name");
НоваяСтрока = ТаблПользователей.Добавить();
НоваяСтрока.id = 3276;
НоваяСтрока.name = "Jack";
НоваяСтрока = ТаблПользователей.Добавить();
НоваяСтрока.id = 3276;
НоваяСтрока.name = "Nick";
СтрокаJSON = СформироватьСтрокуJSONИзСтруктуры(Данные);
// результатом будет строка
// [{"id":"3745","name":"Jack"},{"id":"7462","name":"Nick"}]
Пишите комменты
Категория:
Работа с Интернет, Почтой (Mail), FTP КД: Передача параметров из выгрузки в загрузку (в т.ч. и на ранние стадии) при обмене из 7.7 в 8.х Кратко суть проблемы можно озвучить цитатой из документации: "Передача параметра из источника в приемник доступна только при обмене между информационными базами на платформе 1С:Предприятие 8".
Ниже излагается способ передачи глобальных параметров при таком обмене без правки выгруженного из КД 2 модуля выгрузки и без правки самой КД 2.
Итак, в обработчике ПередВыгрузкойДанных пишем код:
Код 1C v 8.2 УП УзелПарам=СоздатьУзел("ЗначениеПараметра");
УстановитьАтрибут(УзелПарам,"Имя","НашПараметр1");
УстановитьАтрибут(УзелПарам,"Тип","Строка");
ЗаписатьЭлемент(УзелПарам,"Значение","Значение нашего параметра 1");
ДобавитьПодчиненный(rootNode,УзелПарам);
УзелПарам=СоздатьУзел("ЗначениеПараметра");
УстановитьАтрибут(УзелПарам,"Имя","НашПараметр2");
УстановитьАтрибут(УзелПарам,"Тип","Булево");
ЗаписатьЭлемент(УзелПарам,"Значение","true ");
ДобавитьПодчиненный(rootNode,УзелПарам);
после этого данные параметры будут абсолютно штатно загружены в стандартной обработке "Универсальный обмен данными в формате XML (2.1.5)".
Ещё хотелось бы заметить, что содержимое обработчика ПослеЗагрузкиПараметров при таком обмене также не выгружается в файл обмена. Исправить данную оплошность можно так же, записав в обработчике ПередВыгрузкойДанных
Код 1C v 8.2 УП АлгПослеЗагрузкиПараметров=
"СтрокаКода1;"+РазделительСтрок+
"СтрокаКода2;"+РазделительСтрок+
"СтрокаКода3;";
ЗаписатьЭлемент(rootNode,"АлгоритмПослеЗагрузкиПараметров",АлгПослеЗагрузкиПараметров);
Нюанс : чтобы иметь параметры на ранних стадиях загрузки, например, в обработчиках ПередЗагрузкойДанных или ПередОбработкой в ПОД (правилах очистки данных), нужно помещать выгружаемые параметры в корень узла с выгружаемыми данными:
Код 1C v 8.2 УП ИмяПараметра="НашПараметр1";
ТипПараметра="Строка";
ЗначениеПараметра="Значение нашего параметра 1";
// Устанавливаем значение параметра в обработчике ПередЗагрузкойДанных
УзелПравил=rootNode.getElementsByTagName("ПравилаОбмена").item(0);
УзелПередЗагрузкой=УзелПравил.getElementsByTagName("ПередЗагрузкойДанных").item(0);
КоллУзлов=УзелПередЗагрузкой.childNodes;
Для НомУзла=0 По КоллУзлов.length-1 Цикл
ТекУзел=КоллУзлов.item(НомУзла);
Если (ТекУзел.nodeType=3) Тогда
// текст элемента
ТекУзел.nodeValue=РазделительСтрок+"Параметры."+ИмяПараметра+"="+?(ТипПараметра="Строка","""","")+
ЗначениеПараметра+?(ТипПараметра="Строка","""","")+";"+РазделительСтрок+РазделительСтрок+
ТекУзел.nodeValue;
Прервать;
КонецЕсли;
КонецЦикла;
Автор: andrewks - Источник
Категория:
Конвертация данных, Обмен, Перенос Отправка почты через CDO (работает c SSL) &НаСервереБезКонтекста
Функция ПолучитьДанныеЯщикаСистемнойЗаписи()
СистемнаяУчетнаяЗаписьЭлектроннойПочты = Справочники.УчетныеЗаписиЭлектроннойПочты.СистемнаяУчетнаяЗаписьЭлектроннойПочты;
СтруктураНастроек = Новый Структура;
СтруктураНастроек.Вставить("СерверSMTP", СокрЛП(СистемнаяУчетнаяЗаписьЭлектроннойПочты.СерверИсходящейПочтыSMTP));
СтруктураНастроек.Вставить("ПользовательSMTP",СокрЛП(СистемнаяУчетнаяЗаписьЭлектроннойПочты.ПользовательSMTP));
СтруктураНастроек.Вставить("ПарольSMTP", СокрЛП(СистемнаяУчетнаяЗаписьЭлектроннойПочты.ПарольSMTP));
СтруктураНастроек.Вставить("ПортSMTP", СистемнаяУчетнаяЗаписьЭлектроннойПочты.ПортSMTP);
СтруктураНастроек.Вставить("Отправитель", СокрЛП(СистемнаяУчетнаяЗаписьЭлектроннойПочты.АдресЭлектроннойПочты));
СтруктураНастроек.Вставить("ИспользоватьSSL", СистемнаяУчетнаяЗаписьЭлектроннойПочты.ИспользоватьSSL);
Возврат СтруктураНастроек;
КонецФункции
//обработка, пример который приведен содержит ТЧ "НаОтправку" с реквизитами "Контрагент" - ссылка на справочник и "Файл" - строка, путь к файлу
//ПолучитьМассивКлиентов() - функция возвращает перечень всех клиентов из данной ТЧ
//
//АдресПолучателя(ЭлементМассива) - функция возвращает e-mail клиента
&НаКлиенте
Процедура ОтправкаПисем()
//тут был прочий код, не относящийся к отправке, он удален
МассивКлиенты = ПолучитьМассивКлиентов();
Для Каждого ЭлементМассива Из МассивКлиенты Цикл
//***************************************
Если АдресПолучателя(ЭлементМассива) = "" Тогда
Сообщить("У контрагента "+ЭлементМассива+" не указан email, письмо отправлено не будет!");
Продолжить;
КонецЕсли;
Кому = АдресПолучателя(ЭлементМассива);
Тема = "Документы";
Текст = "Документы";
СтруктураНастроек = ПолучитьДанныеЯщикаСистемнойЗаписи();
CDO_СерверSMTP = СтруктураНастроек.СерверSMTP;
CDO_ПользовательSMTP = СтруктураНастроек.ПользовательSMTP;
CDO_ПарольSMTP = СтруктураНастроек.ПарольSMTP;
CDO_ПортSMTP = СтруктураНастроек.ПортSMTP;
Отправитель = СтруктураНастроек.Отправитель;
ИспользоватьSSL = СтруктураНастроек.ИспользоватьSSL;
Письмо = Новый COMОбъект("CDO.Message");
Письмо.to = Кому;
Письмо.from = Отправитель;
Письмо.Sender = Отправитель;
//Письмо.cc=Копия;
//Письмо.bcc=СкрКопия;
Отбор = Новый Структура();
Отбор.Вставить("Контрагент",ЭлементМассива);
НайденныеСтроки = Объект.НаОтправку.НайтиСтроки(Отбор);
Для КАЖДОГО СтрДокументы ИЗ НайденныеСтроки ЦИКЛ
Письмо.AddAttachment(СокрЛП(СтрДокументы.Файл));
КонецЦикла;
Письмо.Subject = Тема;
Письмо.TextBody = Текст;
Письмо.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing").Value = 2;
Письмо.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver").Value = CDO_СерверSMTP;
Письмо.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate").Value = 1;// 0 - Do not authenticate; 1 - basic (clear-text) authentication; 2 - NTLM
Письмо.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusername").Value = CDO_ПользовательSMTP;
Письмо.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendpassword").Value = CDO_ПарольSMTP;
Письмо.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport").Value = CDO_ПортSMTP;
Если ИспользоватьSSL Тогда
Письмо.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpusessl").Value = True ;
КонецЕсли;
//Письмо.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpusessl").Value = ИспользоватьSSL;
Письмо.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout").Value = 60;
Попытка
Письмо.Configuration.Fields.Update();
Исключение
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
Попытка
Письмо.Send();
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
Сообщить("Все...");
КонецПроцедуры
Категория:
Работа с Интернет, Почтой (Mail), FTP Как в 1С проложить маршрут используя GoogleMaps API V3 Клиенты частенько просят настроить отображение маршрутов перемещения по разным адресам в 1С, например для курьеров и т.д.
В примере описан способ отражения карт GoogleMaps в 1С:
Код 1C v 8.2 УП Для Каждого Стр Из НаВходе Цикл
нСтр = ПроверкаСовпадений.Добавить();
нСтр.Адрес = Стр.Адрес;
нСтр.Контрагент = Стр.Контрагент;
//Если адрес начальный или конечный - пропускаем
Если Стр.НомерСтроки = 1 или Стр.НомерСтроки = НаВходе.Количество() Тогда
Продолжить;
КонецЕсли;
опАдреса = опАдреса + "
|waypts.push({location:'" + нСтр.Адрес + "',stopover:true });";
КонецЦикла;
//Подставляем параметры в макет "Карта"
опМаршрут = ПолучитьМакет("Карта").ПолучитьТекст();
опМаршрут = СтрЗаменить(опМаршрут,"[=-опАдреса-=]",опАдреса);
опМаршрут = СтрЗаменить(опМаршрут,"[=-опНач-=]",опНач);
опМаршрут = СтрЗаменить(опМаршрут,"[=-опКон-=]",опКон);
ЭлементыФормы.Карта.УстановитьТекст(опМаршрут);
Скрипт отображения из макета Карта (выделила как VBS, но по факту это HTML ):
Код VBS <HTML><HEAD>
<META content="text/html; charset=utf-8" http-equiv=Content-Type></META>
<META name=viewport content="initial-scale=1.0, user-scalable=no"></META>
<STYLE type=text/css>HTML {
HEIGHT: 100%
}
BODY {
HEIGHT: 100%; PADDING-BOTTOM: 0px; PADDING-TOP: 0px; PADDING-LEFT: 0px; MARGIN: 0px; PADDING-RIGHT: 0px
}
#map_canvas {
HEIGHT: 100%
}
</STYLE>
<SCRIPT type=text/javascript src="http://maps.google.com/maps/api/js?sensor=false">
</SCRIPT>
<SCRIPT type=text/javascript>
var directionDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
function initialize() {
directionsDisplay = new google.maps.DirectionsRenderer();
var chicago = new google.maps.LatLng(55.81234, 37.664425);
var myOptions = {
zoom: 6,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: chicago
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
directionsDisplay.setMap(map);
calcRoute();
var trafficLayer = new google.maps.TrafficLayer();
trafficLayer.setMap(map);
}
function calcRoute() {
var start = "[=-опНач-=]";
var end = "[=-опКон-=]";
var waypts = [];
var checkboxArray = document.getElementById("waypoints");
[=-опАдреса-=]
var request = {
origin: start,
destination: end,
waypoints: waypts,
optimizeWaypoints: true ,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
var route = response.routes[0];
var summaryPanel = document.getElementById("directions_panel");
summaryPanel.innerHTML = "";
// For each route, display summary information.
for (var i = 0; i < route.legs.length; i++) {
var routeSegment = i+1;
summaryPanel.innerHTML += 'опЗаполнитьМаршрут("' + String.fromCharCode(routeSegment+65) + '","' + String.fromCharCode(route.legs.length+65) + '","' + route.legs[i].start_address + '","' + route.legs[i].end_address + '","' + route.legs[i].distance.text + '");';
}
}
});
}
</SCRIPT>
<META name=GENERATOR content="MSHTML 11.00.9600.17239"></META><BASE href="v8config://c924c032-2565-45e2-b49f-9a30494bc69f/mdobject/ida329e781-b8d1-431e-9e2f-8321c1a691fc/8eb4fad1-1fa6-403e-970f-2c12dbb43e23"></BASE></HEAD>
<BODY onload=initialize()>
<DIV id=map_canvas style="HEIGHT: 100%; WIDTH: 100%"></DIV>
<DIV id=directions_panel style="MARGIN: 20px; DISPLAY: none; BACKGROUND-COLOR: #ffee77"></DIV></BODY></HTML>
Файл отображающий пример работы GoogleMaps API V3 - Прокладываем маршрут в 1С
Скрин это обработки
Категория:
HTML, JS, VML Управляем 1С со стороны используя web-сервис Передача команд 1С на выполнение через ссылки в письме.
web-сервисы помогают интегрировать 1С с различными программами, делая её более гибкой. Статей в интеренете достаточно можно, но в основном там описывается выгрузка из 1С, обмен между двумя 1С или 1С и каким-то мощным программным продуктом написанным на C или других языках.
Для меня же была поставлена задача возможности управление 1С через браузер. Как пример: обрабатывать завершение задачи БП в 1С по ссылке в письме (примерно такого типа http://site.ru/?user=000000001&bp=000000555, т.е. отсюда видно, что пользователь 000000001 хочет закрыть задачу 000000555), т.е. пользователь со своего смартфона не имеющего доступа к 1С как таковому, должен получить возможность управлять ею извне. Собственно, более сложной задачей можно поставить написание собственных web-форм, более легких и компактных, с произвольным дизайном для управления 1С.
Задача с точки зрения написания кода 1С очень легкая. Основная сложность заключалась в освоении HTML и JavaScript для управления извне. Начальные знаний по этому вопросу я подчерпнул из статьи Примеры пользования web сервисов 1С из браузера.
Настройка 1С
Для возможности использовать 1С в вебе необходимо:
1. Установить модуль расширения веб-сервера;
2. Настроить Windows: доустановить компоненты IIS и настроить проверку подлинности. Всё это можно прочитать в статье
Настройка веб-клиента 1С:Предприятие 8.2 под Windows 7 x64 и IIS.
Программирование 1С
Теперь можно приступить к конфигурированию.
1. Создадим Web-сервис Input:
1.1. Input имеет операцию InputData которая принимает два параметра: User и Command, и возвращает параметр типа "boolean (http://www.w3.org/2001/XMLSchema)". Текст функции InputData:
Код 1C v 8.х Функция InputData(User, Command)
обДанные = Справочники.Данные.СоздатьЭлемент();
обДанные.Наименование = User + ":" + Command;
обДанные.Записать();
Возврат Истина;
КонецФункции
1.2. Устанавливаем для Input URI пространства имен = "http://infostart.ru". Здесь может быть любое уникальное имя, обычно это ссылка на сайт.
1.3. Устанавливаем для Input имя файла публикации = "input.1cws". Это имя web-сервиса к которому будем устанавливать соединение.
2. Для наглядности примера создадим справочник Данные, все параметры оставим по умолчанию.
3. Публикуем нашу конфигурацию и web-сервис: Администрирование -> Публикация на веб сервере...
На этом конфигурирование заканчивается, всё остальное сделает за нас 1С.
Разработка HTML страницы
Эта часть далась для меня тяжело, т.к. я ещё только делаю первые шаги в этой теме. Буду рад замачаниям и советам. А так, я постараюсь объяснить всё на пальцах тем, кто как и я знаком по большей части с 1С.
После установки ISS (я уже давал ссылку в начале статьи) на диске C появится каталог C:\inetpub\wwwroot, в этом каталоге располагается сайт. Для локальной машины (на которой установили ISS) он виден так http://localhost/, ну а для пользователей извне, как-то так http://infostart.ru (по правде там немного сложнее, но не суть, мы сейчас не про это). Заглавная страница сайта будет грузиться из файла index.htm каталога C:\inetpub\wwwroot
Исходники файлов можно скачать здесь:
Скачивать файлы может только зарегистрированный пользователь!
Код файла index.htm попытаюсь объяснить как могу, т.к. сам некоторые моменты не понимаю:
Код [html xmlns="http://www.w3.org/1999/xhtml"] // Неважно. Используется в XHTML для объявления пространства имен.
[head] // Предназначен для хранения других элементов, цель которых — помочь браузеру в работе с данными.
[meta http-equiv="Content-Type" content="text/html; charset=utf-8" /] // Неважно. Мета-теги используются для указания описания.
[title]Тест веб сервиса 1С[/title] // Неважно. Определяет заголовок документа, то что видит пользователь как текст вкладки.
[script type="text/javascript" src="../js/connect1c.js"] [/script] // Важно. Подключение JavaScript библиотек. В моём случае это мой модуль соединения с 1С.
[script type="text/javascript" src="../js/parameters.js"] [/script] // Важно. А это модуль обработки параметров строки браузера.
[/head]
[body] // Предназначен для хранения содержания веб-страницы (контента), отображаемого в окне браузера.
[p id="response1C"][/p] // Важно. Метка response1C, куда вернёться ответ запроса 1С.
[/body]
[script type="text/javascript"] // Важно. Начало основного скрипта, который выдёргивает из строки браузера всё что идёт дальше знака вопроса,
а дальше парсит по определенному алгоритму. В нашем случае будут искаться ключевые слова "user=" и "command=".
user = GetParameter("user"); // Важно. Находим значение user. Сам метод GetParameter находится в библиотеке parameters.js, о которой поговорим чуть позже.
command = GetParameter("command"); // Важно. Находим значение command.
Inquiry1C(user, command); // Важно. Запрос к 1С с найденными параметрами. Сам метод Inquiry1C находится в библиотеке connect1c.js
[/script]
[/html]
Заменил < на [, а > - ], замените перед использованием обратно.
Рассмотрим библиотеку parameters.js, которая находится в папке C:\inetpub\wwwroot\js
f
Код unction GetParameter(pName) { // Сам метод я нашёл на просторах интернета.
search = window.location.search; // window.location - это по сути URL, метод search этого объекта возвращает часть адреса после символа "?", включая символ "?".
begin = search.indexOf(pName) + pName.length + 1; // Вычисляем позицию начала строки значения параметра для вырезания. +1 - в нашем случае это знак "=".
Итого, для search = "?user=007" мы найдём позицию начала равной 6 (нумерация с нуля).
end = search.indexOf('&', begin); // Находим позицию конца выражения. В нашем случае, разделение параметров осуществляется знаком "&", и если мы его не найдём,
то позицией конца будет последний символ строки search (смотри дальше код).
if (end == -1) {
end = search.length;
};
return unescape(search.substring(begin, end)); // Метод unescape возвращает строку, содержащую данные типа charString (не знаю зачем это надо,
но видимо такое приведение типа здесь необходимо). Ну а метод substring - извлекает подстроку из строки.
}
Теперь рассмотрим библиотеку connect1c.js, которая также находится в папке C:\inetpub\wwwroot\js
function Inquiry1C(pUser, pCommand) { // Основной метод этой библиотеки. Запрос к 1С.
XMLHTTP = CreateRequestObject(); // Создание XML HTTP запроса. Сам метод я узнал из википедии.
XMLHTTP.open('POST', '../TestWeb/ws/Input.1cws',
true , "Admin", "1"); // Создаём соединение типа POST, где второй параметр - адрес; параметр
true - значит асинхронное,
то есть браузер не будет ждать ответа сервера, а продолжит работу; далее пользователь и пароль с правами на операцию InputData (этот тот метод, который мы написали в 1С),
саму операцию можно выполнять в привилегированном режиме, чтобы не мучиться с правами для пользователя Admin.
XMLHTTP.onreadystatechange = function() {WhenAnswering1C(XMLHTTP)}; // Когда 1С отработает, автоматически сработает метод WhenAnswering (о нём чуть ниже по тексту этой библиотеки).
XMLHTTP.send(''
+ ' '
+ ' '
+ ''
+ pUser + ' '
+ ''
+ pCommand + ' '
+ ' '); // Отправка XML запроса, где описывается метод к исполнению в 1С, с переданными параметрами из нашей строки URL.
// Строку запроса можно раскурить минут за 5
}
function CreateRequestObject() { // Чудо метод из википедии "Пример использования". По сути, ничего сложного.
if (typeof XMLHttpRequest === 'undefined') {
XMLHttpRequest = function() {
try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); }
catch(e) {}
try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); }
catch(e) {}
try { return new ActiveXObject("Msxml2.XMLHTTP"); }
catch(e) {}
try { return new ActiveXObject("Microsoft.XMLHTTP"); }
catch(e) {}
throw new Error("This browser does not support XMLHttpRequest.");
};
}
return new XMLHttpRequest();
}
function WhenAnswering1C(pXMLHTTP) { // Метод, который срабатывает после обработки запроса 1С.
status = StausRequest(pXMLHTTP); // Вычисляется статус для отправки сообщения пользователю (о нём чуть ниже).
document.getElementById("response1C").appendChild(document.createTextNode(status)); // Вывод на экран в помеченную область response1C (о ней я писал в основном файле).
Метод getElementById возвращает ссылку на узел документа.
Метод appendChild добавляет нод в конце списка дочерных нодов элемента, т.е. встраивает в нашу область нужный нам текст.
}
function StausRequest(pXMLHTTP) // Определение статуса.
{
status = "";
if (pXMLHTTP.readyState == 4) { // Опять же, читая википедию можно понять, readyState - это текущее состояние объекта (0 — не инициализирован, 1 — открыт,
2 — отправка данных, 3 — получение данных и 4 — данные загружены).
if (pXMLHTTP.status != 200) { // status - HTTP-статус в виде числа (404 — «Not Found», 200 — «OK» и т. д.)
status = "Запрос завершился неудачно. Ответ сервера: " + pXMLHTTP.responseText; // responseText -текст ответа на запрос.
Если состояние не 3 или 4, возвращает пустую строку.
}
else {
if (RequestSuccessful(pXMLHTTP)) { // Проверка ответа от 1С (о нём чуть ниже).
status = "Запрос отработан.";
}
else {
status = "Запрос был отклонён.";
};
};
};
return status;
}
function RequestSuccessful(pXMLHTTP) { // Проверка ответа от 1С. Здесь мы получим возвращаемое от 1С значение (в нашем случае 1С может вернуть тип булево).
DOM = pXMLHTTP.responseXML.getElementsByTagName("return")[0]; // responseXML - Текст ответа на запрос в виде XML, который затем может быть обработан посредством DOM.
Если состояние не 4, возвращает null.
response = DOM.childNodes[0].data; // Достаём данные из ответа.
return response == "
true "; // Если правда, то правда
По правде, я не смог преобразовать сроку в булево, поэтому пришлось оставить так.
}
Проверка
Открываем браузер и вводим строку "localhost/?user=007&command=hello world!":
После чего можно открыть 1С и убедиться что создался элемент справочника:
На этом пример ознакомления управления 1С извне можно считать законченным
Автор:
Soloist Категория:
WEB-сервисы, WS-ссылки, XDTO-пакеты Обмен 1С c клиентом используя web сервисы 1С Все чаще и чаще встречаются обмены, используя технологию Web-Сервисов. Это удобно, т.к для хостовой базы данных достаточно установить расширение Web-Сервиса и обработчик данных, а для клинтского решения подключиться к Web-Сервису. Технология является мультиплатформенной и на данный момент ее использование весьма актуально.
Примерами таких веб-сервисов можно назвать:
http://www.cbr.ru/scripts/Root.asp?Prtid=DWS веб-сервис Центробанка, для получения ежедневных данных.
http://api.yandex.ru/speller/doc/dg/concepts/api-overview.xml веб-сервис Яндекса проверки правописания.
https://www.flightstats.com/developers/bin/view/Web+Services/WSDL ряд веб сервисов авиастатистики, для мониторинга полетов, сведений о погоде, и.т.п.
WSDL (Web Services Description Language) — язык описания веб-сервисов и доступа к ним, основанный на языке XML. (спецификация http://www.w3.org/TR/wsdl).
SOAP (Simple Object Access Protocol — простой протокол доступа к объектам) — протокол обмена структурированными сообщениями в распределенной вычислительной среде. SOAP используется для обмена произвольными сообщениями в формате XML и удалённого вызова процедур (RPC). (спецификация http://www.w3.org/TR/soap/).
XDTO (XML Data Transfer Objects) — механизм объектного моделирования данных, описываемых с помощью схемы XML (подробнее http://v8.1c.ru/overview/xdto.htm).
Большинство примитивных типов сериализованных объектов разработана компание W3 и их описание находится в пространстве имен «http://www.w3.org/2001/XMLSchema».
 
и так:
Задание 1: Установка платформы 1С: Предприятие, установка компоненты IIS сервера, связь Web-Расширения 1С с сервером IIS.
При установке платформы 1С: Предприятие необходимо установить Web-Расширение.
Рис. 1. Выбранные компоненты в момент установки 1С
В меню «Панель управленияВсе элементы панели управленияПрограммы и компоненты» Необходимо выполнить установку дополнительных компонентов Windows «Включение или отключение компонентов Windows» где указать все компоненты IIS (за исключением FTP, для текущей работы он не требуется). После установки рекомендуется перезапустить операционную систему.
Рис. 2. Выбранные компоненты в момент установки IIS
В меню «Панель управленияВсе элементы панели управленияАдминистрирование» запустить консоль «Диспетчер служб IIS», где открыть элемент «Пулы приложений» открыть пул «DefaultAppPool» в контекстном меню выбрать «Дополнительные параметры…» где элемент «Разрешены 32-рязрядные приложения» надо установить «
True ». Это необходимо для работы Web-Расширения 1С, т.к. оно является 32-битным прилодением.
В той же консоли «Диспетчер служб IIS», выбрать элемент «Default Web Site», выбрать действие «Проверка подлинности» где необходимо включить варианты: «Анонимная проверка подлинности», «Обычная проверка подлинности», «Проверка подлинности Windows».
Теперь возможна публикация Web-Сервисов 1С на сервере IIS. Но для того, чтобы было возможно выполнить эту публикацию, необходимо запустить Конфигуратор 1С: Предприятия от имени пользователя «Администратор».
Задание 2: Создание простой конфигурации 1С.
Считаем, что в базе данных есть информация информации обо всех заказах, содержащая количество и тип номенклатуры, который был заказан, в одном заказе может быть список, содержащий номенклатуру и количество, заказ так же имеет свой номер и дату его создания. Информацию обо всех заказах надо передать через Web-Сервис.
Для описания этого необходимо создать объекты базы данных:
Рис. 3. Структура данных в созданной конфигурации 1С
Справочник «Номенклатура», без дополнительных реквизитов. В реквизитах «по умолчанию» содержится информацию о наименовании и коде номенклатуры.
Документ «Заказ покупателя», который будет содержать табличную часть «Товары», каждая строка которой будет иметь информацию о номенклатуры (элемент типа «СправочникСсылка.Номенклатура») и количестве (элемент «Количество» типа «Число» беззнаковое с 15 знаками до запятой и 3 после).
Далее можно запустить 1С в режиме предприятия и создать несколько документов, заполненных созданными нами же номенклатурами и соответствующим количеством.
Задание 3: Создание и публикация Веб-Сервиса 1С.
В группировке «Общие» конфигурации создать новый элемент типа «XDTO-пакеты», первоначально для передачи номенклатуры. Его можно назвать, например «NomenclatureXDTO». URL пространство имен, в соответствии со спецификацией WSDL необходимо назначить в виде URL адреса спецификации данного пакета, например
«company.com/1C/Nomenclature». В этом пакете необходимо создать тип объекта, например «Nomenclature», в котором есть реквизиты «Code» и «Name», с соответствующим типом «string (http://www.w3.org/2001/XMLSchema)».
Теперь надо создать второй XDTO пакет, который будет содержать информацию о заказах покупателей, его можно назвать «ClientOrderXDTO» в пространсте имен «company.com/1C/ClientOrder». В первую очередь необходимо подключить директиву импорта «company.com/1C/Nomenclature», для того, чтобы можно было использовать созданный нами пакет сериализации номенклатуры. Это необходимо для передачи номенклатуры, содержащейся в табличной части документа «Заказы покупателей».
Теперь надо создать тип объекта «ClientOrderRow», содержащий одну строку табличной части. Этот тип будет состоять из совокупности реквизитов «Nomenclature» и «Count», соответственно для номенклатуры необходимо указать тип объекта «Nomenclature (http://company.com/1C/Nomenclature)», а для количества, «double (http://www.w3.org/2001/XMLSchema)».
Тип объекта, содержащий сам заказ можно назвать «ClientOrder» должен содержать номер заказа, дату создания и массив элементов из табличной части заказа. «Number» типа строка, «Date» типа «dateTime (http://www.w3.org/2001/XMLSchema)» и «Products» типа «ClientOrderRow (http://company.com/1C/ClientOrder)», при этом необходимо указать, что минимальное количество «0», а максимальное количество «-1», это говорит о том, что этот объект будет массивом.
Но, поскольку необходимо возвращить список заказов, то необходимо создать тип объекта, содержащий этот массив, потому надо создать еще один элемент, называемый «ArrayOfClientOrders», у которого будет всего один реквизит, называемый «ClientOrder» типа «ClientOrder (http://company.com/1C/ClientOrder)».
Рис 4. Структуры XDTO пакетов в 1С
На этом создание описания передаваемых значений можно считать оконченным. Необходимо описать сам веб сервис и его методы.
В группировке «Общие» конфигурации надо создать объект, Web-Сервиса. Его можно назвать «Service». Во вкладке «Прочее» надо указать пространство имен, которому принадлежит веб-сервис, например «company.com/1C», а так же список XDTO пакетов, содержащий только что созданные пакеты «company.com/1C/Nomenclature, company.com/1C/ClientOrder». Во вкладке «Операции» создать метод «GetClientOrders», который будет возвращать значения «ArrayOfClientOrders (http://company.com/1C/ClientOrder )», при этом установить возможность возвращать пустые значения и нажать на поле с лупой, называемое «Имя метода», тем самым в модуле веб-сервиса будет создана функция, который будет вызвана при обращении к данному методу веб-сервиса.
Для того, чтобы корректно описать функцию, получающую из базы данных и возвращающую список заказов покупателей, необходимо знать внутренний язык 1С, потому код этой функции находится в приложении 1. В пояснении нуждается то, что «ФабрикаXDTO», это некоторый менеджер, который выполняет сериализацию объектов, и этот сериализованный объект необходимо возвратить. При этом происходит выборка всех заказов, содержащихся в базе данных, сериализация полей номера, даты, и строк табличной части, при этом номенклатура, нуждается в дополнительной сериализации, и уже упакованный объект вставляется в общую структуру. Собирается массив упакованных объектов, сериализуется в пакет массива. И отправляется клиенту, как результат вызванной функции.
Для публикации веб-сервиса в меню конфигуратора 1С выбрать «АдминистрированиеПубликация на веб-сервере…», после чего указать название публикации веб-сервиса, например «Company», имя сервиса, например «Service» и адрес «service.1cws», а так же указать путь для публикации, например «C:\inetpub\www\root\Company».
После этого WSDL структура Web-Сервиса будет доступна по адресу
«localhost/Company/ws/service.1cws?wsdl»
Задание 4: Создание клиента на C# платформы .NET 4.0.
В Visual Studio создать новое консольное приложение C#.
Далее вызвать контекстное меню над элементом проекта «Reference», и выполнить действие «Add service reference…», в открывшемся меню нажать на кнопку «Advanced…», откроется окно, где необходимо нажать на кнопку «Add Web Reference…».
Откроется меню, в которое необходимо вставить ссылку на WSDL описание веб-сервиса.
Рис. 5. Подключение веб-сервиса к проекту на C#
Для созданного в 1С веб-сервиса эта ссылка будет иметь вид «localhost/Company/ws/service.1cws?wsdl», после корректного получения описания веб-сервиса надо указать название пространства имен .NET, из под которого будет доступно обращение к веб-сервису, например «CompanyService», затем нажать на кнопку «Add Reference…», Visual Studio автоматически сгенерирует классы по этому описанию. В проекте достаточно будет вызывать методы сгенерированного класса, при этом сериализация и вызов будут выполнять платформой .NET.
Далее необходимо написать программу, которая будет обращаться к веб сервису, и выводить пользователю полученные данные. Для этого необходимо знать язык C#, код программы представлен в приложении 2. Из этого кода надо пояснить, то, что создание объекта «Service», есть не что иное, как создание менеджера обращения к сервису. От этого имени будут вызывать методы веб-сервиса.
«_1CWebServiceClientConsole» — это общее пространство имени проекта, оно выбирается при создании. Пространство имени веб-сервиса, полученное из WSDL структуры полностью включено в пространство имени проекта, что позволяет вызывать удаленные методы «как свои».
Построение такой архитектуры является прозрачной для программистов, но при этом необходимо понимать в какие моменты и что проходит сериализацию для последующей передачи. Подобная архитектура клиент-серверных приложений на данный момент самая популярная.
Приложение 1: код функции GetClientOrders на языке 1С
Код 1C v 8.2 УП Функция GetClientOrders()
МассивЗаказовПокупателейТип = ФабрикаXDTO.Тип("http://company.com/1C/ClientOrder", "ArrayOfClientOrders");
ЗаказПокупателяТип = ФабрикаXDTO.Тип("http://company.com/1C/ClientOrder", "ClientOrder");
ЗаказПокупателяСтрокаТип = ФабрикаXDTO.Тип("http://company.com/1C/ClientOrder", "ClientOrderRow");
НоменклатураТип = ФабрикаXDTO.Тип("http://company.com/1C/Nomenclature", "Nomenclature");
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ЗаказПокупателя.Ссылка,
| ЗаказПокупателя.Номер,
| ЗаказПокупателя.Дата
|ИЗ
| Документ.ЗаказПокупателя КАК ЗаказПокупателя";
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Если Выборка.Количество() = 0 Тогда
Возврат Null;
КонецЕсли;
МассивЗаказовПокупателей = ФабрикаXDTO.Создать(МассивЗаказовПокупателейТип);
Пока Выборка.Следующий() Цикл
ЗаказПокупателя = ФабрикаXDTO.Создать(ЗаказПокупателяТип);
ЗаказПокупателя.Number = Выборка.Номер;
ЗаказПокупателя.Date = Выборка.Дата;
Для каждого Строка Из Выборка.Ссылка.Товары Цикл
ЗаказПокупателяСтрока = ФабрикаXDTO.Создать(ЗаказПокупателяСтрокаТип);
Номенклатура = ФабрикаXDTO.Создать(НоменклатураТип);
Номенклатура.Code = Строка.Номенклатура.Код;
Номенклатура.Name = Строка.Номенклатура.Наименование;
ЗаказПокупателяСтрока.Nomenclature = Номенклатура;
ЗаказПокупателяСтрока.Count = Строка.Количество;
ЗаказПокупателя.Products.Добавить(ЗаказПокупателяСтрока);
КонецЦикла;
МассивЗаказовПокупателей.ClientOrder.Добавить(ЗаказПокупателя);
КонецЦикла;
Возврат МассивЗаказовПокупателей;
КонецФункции
Приложение 2: код программы на C# осуществляющий обращение к веб-сервису
Код using System;
using _1CWebServiceClientConsole.CompanyService;
namespace _1CWebServiceClientConsole
{
class Program
{
static void Main(string[] args)
{
using (Service service = new Service())
{
var arrayOfClientOrders = service.GetClientOrders();
if (arrayOfClientOrders == null)
Console.WriteLine("Не найдена");
foreach (var clientOrder in arrayOfClientOrders)
{
Console.WriteLine("Заказ покупателя №" + clientOrder.Number + " от " + clientOrder.Date);
Console.WriteLine("*****************************************************");
foreach (var clientOrderRow in clientOrder.Products)
{
Console.WriteLine(clientOrderRow.Nomenclature.Name + " " + clientOrderRow.Count);
}
Console.WriteLine("*****************************************************n");
}
}
Console.ReadKey();
}
}
}
Автор:
ZEEGIN Категория:
WEB-сервисы, WS-ссылки, XDTO-пакеты Настройка веб-клиента 1С:Предприятие 8.2 под Windows 7 x64 и IIS Возникла необходимость отладить небольшую конфигурацию 1С:Предприятие 8.2 под веб-клиентом. Веб сервером был выбран IIS, являющийся самым родным для ОС Windows. Опыт использования этого сервера в Windows XP подсказывал, что с ним будет меньше проблем чем с Apache, но на недавно установленной Windows 7 x64 все оказалось не так просто. Мелкие проблемы начались с момента попытки публикации веб приложения, а после их устранения коснулись уже веб сервера, настройкой которого платформа 1С:Предприятие 8.2 не занимается.
Героически победив все свалившиеся напасти, решил скомпоновать и выложить на всеобщее обозрение свои шаги в достижении цели.
Шаг 1. Доустановка компонентов IIS.
Для работы веб-клиента 1С:Предприятия необходимы службы IIS, которые небыли установлены по умолчанию при установке Windows 7 x64.
Для их установки следует перейти "Пуск - Панель управления - Программы и компоненты - Включение или отключение компонентов Windows". В появившемся дереве, в ветке "Службы IIS – Компоненты разработки приложений" отметить все компоненты, как показано на рисунке. Затем нажать кнопку "Ок".
Шаг 2. Разрешение 32-разрядных приложений в пуле приложений.
Веб-клиент 1С:Предприятия 8.2 является 32-разрядным приложением. Поэтому для 64-разрядной ОС необходимо разрешить работу оных в пуле приложений сервера IIS. Для этого необходимо перейти "Пуск - Панель управления – Администрирование – Диспетчер служб IIS". В диспетчере служб выбрать "Пулы приложений – DefaultAppPool – Дополнительные параметры". В списке дополнительных параметров переменной "Разрешены 32-разрядные приложения" установить значение "
True ".
Шаг 3. Установка удостоверения пула приложений в качестве удостоверения анонимного пользователя.
По умолчанию в качестве анонимного пользователя установлен пользователь IUSR, которого нет в системе. Дабы не создавать оного можно просто включить удостоверение пула приложений в качестве удостоверения анонимного пользователя. Для этого необходимо перейти "Пуск - Панель управления – Администрирование – Диспетчер служб IIS". В диспетчере служб перейти в "Проверка подлинности – Анонимная проверка подлинности". В открывшемся диалоге отметить "Удостоверение пула приложений". Закрыть диалог, нажав кнопку "ОК".
Вроде бы ничего не забыл. Ну а дальше публикуем веб-клиента (в конфигураторе "Администрирование – Публикация на веб-сервере") и наслаждаемся результатом, запустив отладку (в конфигураторе "Отладка – Начало отладки – Веб клиент: начать отладку").
Автор:
provlax Категория:
WEB-сервисы, WS-ссылки, XDTO-пакеты Яндекс, Google, Рамблер Карты и 1С Обработка демонстрирует возможности интеграции 1С с картографическими сервисами, в ней поддерживается работа трех поставщиков услуг / карт — Яндекс, Google. Рамблер.
Автор: Діма Головаченко - http://smaylukk.com.ua
но так вот сама обработка + еще 2 :
Скачивать файлы может только зарегистрированный пользователь!
Код Модуля Обработки:
Код 1C v 8.х Перем СтруктураПоставщиковКарт Экспорт;
Перем СтруктураЧисел;
/////////////////////////РАБОТА С JSON //////////////////////////////////////////
Функция СформироватьСтрокуJSONИзМассива(Объект)
СтрокаJSON = "[";
Для каждого Элемент Из Объект Цикл
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON(Элемент) + ",";
КонецЦикла;
Если Прав(СтрокаJSON, 1) = "," Тогда
СтрокаJSON = Лев(СтрокаJSON, СтрДлина(СтрокаJSON)-1);
КонецЕсли;
Возврат СтрокаJSON + "]";
КонецФункции
Функция СформироватьСтрокуJSONИзСтруктуры(Объект)
СтрокаJSON = "{";
Для каждого Элемент Из Объект Цикл
Если Элемент.Значение = "" Тогда
Продолжить;
КонецЕсли;
СтрокаJSON = СтрокаJSON + """" + Элемент.Ключ + """" + ":";
Если ТипЗнч(Элемент.Значение) = Тип("Строка") Тогда
СтрокаJSON = СтрокаJSON + """" + URLEncode(Элемент.Значение) + """";
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("Число") Тогда
СтрокаJSON = СтрокаJSON + СтрЗаменить(Строка(Элемент.Значение), Символы.НПП, "");
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("Булево") Тогда
СтрокаJSON = СтрокаJSON + Формат(Элемент.Значение, "БЛ=false; БИ=true ");
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("Дата") Тогда
// преобразование в unixtime
СтрокаJSON = СтрокаJSON + Формат(ТекущаяДата() - Дата(1970,1,1,1,0,0), "ЧГ=0");
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("Массив") Тогда
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON(Элемент.Значение);
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("Структура") Тогда
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON(Элемент.Значение);
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("ТаблицаЗначений") Тогда
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON(Элемент.Значение);
Иначе
СтрокаJSON = СтрокаJSON + """" + URLEncode(Строка(Элемент.Значение)) + """";
КонецЕсли;
СтрокаJSON = СтрокаJSON + ",";
КонецЦикла;
Если Прав(СтрокаJSON, 1) = "," Тогда
СтрокаJSON = Лев(СтрокаJSON, СтрДлина(СтрокаJSON)-1);
КонецЕсли;
Возврат СтрокаJSON + "}";
КонецФункции
Функция СформироватьСтрокуJSON(Объект) Экспорт
СтрокаJSON = "";
Если ТипЗнч(Объект) = Тип("Массив") Тогда
СтрокаJSON = СформироватьСтрокуJSONИзМассива(Объект);
ИначеЕсли ТипЗнч(Объект) = Тип("Структура") Тогда
СтрокаJSON = СформироватьСтрокуJSONИзСтруктуры(Объект);
ИначеЕсли ТипЗнч(Объект) = Тип("ТаблицаЗначений") Тогда
// преобразуем таблицу значений в массив структур - работает дольше, но кода меньше
// если нужна скорость, то нужно отдельно обработать таблицу значений
СоставСтруктуры = "";
Для каждого Колонка Из Объект.Колонки Цикл
СоставСтруктуры = СоставСтруктуры + ?(ЗначениеЗаполнено(СоставСтруктуры), ",", "") + Колонка.Имя;
КонецЦикла;
МассивСтрок = Новый Массив;
Для каждого Строка Из Объект Цикл
СтруктураКолонок = Новый Структура(СоставСтруктуры);
ЗаполнитьЗначенияСвойств(СтруктураКолонок, Строка);
МассивСтрок.Добавить(СтруктураКолонок);
КонецЦикла;
СтрокаJSON = СформироватьСтрокуJSONИзМассива(МассивСтрок);
КонецЕсли;
Возврат СтрокаJSON;
КонецФункции
Процедура ЗаполнитьДанныеИзОтветаJSON(Результат, ТекстJSON, ТипДанных)
ТекстJSON = СокрЛП(Сред(ТекстJSON, 2)); // удалим открывающий символ структуры(массива)
НомерЗначения = 0;
Пока ТекстJSON <> "" Цикл
ПервыйСимвол = Лев(ТекстJSON, 1);
Если ПервыйСимвол = "{" Тогда
// вложенная структура
Значение = Новый Структура;
ЗаполнитьДанныеИзОтветаJSON(Значение, ТекстJSON, "Структура");
Если ТипДанных = "Структура" Тогда
Результат.Вставить("Значение" + ?(НомерЗначения = 0, "", НомерЗначения), Значение);
НомерЗначения = НомерЗначения + 1;
ИначеЕсли ТипДанных = "Массив" Тогда
Результат.Добавить(Значение);
КонецЕсли;
ИначеЕсли ПервыйСимвол = "[" Тогда
// вложенный массив
Значение = Новый Массив;
ЗаполнитьДанныеИзОтветаJSON(Значение, ТекстJSON, "Массив");
Если ТипДанных = "Структура" Тогда
Результат.Вставить("Значение" + ?(НомерЗначения = 0, "", НомерЗначения), Значение);
НомерЗначения = НомерЗначения + 1;
Иначе
Результат.Добавить(Значение);
КонецЕсли;
ИначеЕсли ПервыйСимвол = "}" И ТипДанных = "Структура" Тогда
// структура закончилась
ТекстJSON = СокрЛП(Сред(ТекстJSON, 2));
Если Лев(ТекстJSON, 1) = "," Тогда
ТекстJSON = СокрЛП(Сред(ТекстJSON, 2));
КонецЕсли;
Возврат;
ИначеЕсли ПервыйСимвол = "]" И ТипДанных = "Массив" Тогда
// массив закончился
ТекстJSON = СокрЛП(Сред(ТекстJSON, 2));
Если Лев(ТекстJSON, 1) = "," Тогда
ТекстJSON = СокрЛП(Сред(ТекстJSON, 2));
КонецЕсли;
Возврат;
Иначе
Если ТипДанных = "Структура" Тогда
//ПервыйКавычка = Ложь;
//Если Лев(ТекстJSON, 1) = """" Тогда
// ПервыйКавычка = Истина;
//КонецЕсли;
Поз = Найти(ТекстJSON, ":");
Если Поз = 0 Тогда
// неверный формат, прервемся
Прервать;
КонецЕсли;
//ПредпоследнийКавычка = Ложь;
//Если Сред(ТекстJSON, Поз - 1, 1) = """" Тогда
// ПредпоследнийКавычка = Истина;
//КонецЕсли;
ИмяЗначения = СокрЛП(Лев(ТекстJSON, Поз - 1));
ИмяЗначения = СтрЗаменить(ИмяЗначения, """", "");
ТекстJSON = СокрЛП(Сред(ТекстJSON, Поз+1));
Если Лев(ТекстJSON, 1) = "{" Тогда
// значение является структурой
Значение = Новый Структура;
ЗаполнитьДанныеИзОтветаJSON(Значение, ТекстJSON, "Структура");
ИначеЕсли Лев(ТекстJSON, 1) = "[" Тогда
// значение является массивом
Значение = Новый Массив;
ЗаполнитьДанныеИзОтветаJSON(Значение, ТекстJSON, "Массив");
Иначе
// обычное значение
ПервыйКавычка = Ложь;
ПредпоследнийКавычка = Ложь;
Поз = 0;
Для Сч = 1 По СтрДлина(ТекстJSON) Цикл
Символ = Сред(ТекстJSON, Сч, 1);
Если Символ = """" Тогда
Если ПервыйКавычка Тогда
ПредпоследнийКавычка = Истина;
Иначе
ПервыйКавычка = Истина;
КонецЕсли;
КонецЕсли;
Если (Символ = "," И ((ПервыйКавычка И ПредпоследнийКавычка) Или (Не ПервыйКавычка И Не ПредпоследнийКавычка))) ИЛИ Символ = "]" ИЛИ Символ = "}" Тогда
Поз = Сч;
Прервать;
КонецЕсли;
КонецЦикла;
//ПредпоследнийКавычка = Ложь;
//Если Сред(ТекстJSON, Поз - 1, 1) = """" Тогда
// ПредпоследнийКавычка = Истина;
//КонецЕсли;
Если Поз = 0 Тогда
Значение = ТекстJSON;
ТекстJSON = "";
Иначе
Значение = Лев(ТекстJSON, Поз - 1);
Значение = СтрЗаменить(Значение, """", "");
ТекстJSON = СокрЛП(Сред(ТекстJSON, Поз + ?(Сред(ТекстJSON, Поз, 1) = ",", 1, 0)));
КонецЕсли;
Значение = СокрЛП(Значение);
КонецЕсли;
Результат.Вставить(ИмяЗначения, Значение);
ИначеЕсли ТипДанных = "Массив" Тогда
// обычное значение
Поз = 0;
Для Сч = 1 По СтрДлина(ТекстJSON) Цикл
Символ = Сред(ТекстJSON, Сч, 1);
Если Символ = "," ИЛИ Символ = "]" ИЛИ Символ = "}" Тогда
Поз = Сч;
Прервать;
КонецЕсли;
КонецЦикла;
//ПредпоследнийКавычка = Ложь;
//Если Сред(ТекстJSON, Поз - 1, 1) = """" Тогда
// ПредпоследнийКавычка = Истина;
//КонецЕсли;
Если Поз = 0 Тогда
Значение = ТекстJSON;
ТекстJSON = "";
Иначе
Значение = Лев(ТекстJSON, Поз - 1);
Значение = СтрЗаменить(Значение, """", "");
ТекстJSON = СокрЛП(Сред(ТекстJSON, Поз + ?(Сред(ТекстJSON, Поз, 1) = ",", 1, 0)));
КонецЕсли;
Значение = СокрЛП(Значение);
Результат.Добавить(Значение);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция ЗаполнитьСтруктуруИзОтветаJSON(Знач ТекстJSON) Экспорт
Результат = Новый Структура;
ТекстJSON = СтрЗаменить(ТекстJSON, "\""", """"); // заменим последовательность \" на "
//ТекстJSON = СтрЗаменить(ТекстJSON, """", ""); // а теперь удалим все кавычки
Если Лев(ТекстJSON, 1) = "{" Тогда
// начало структуры
ЗаполнитьДанныеИзОтветаJSON(Результат, ТекстJSON, "Структура");
ИначеЕсли Лев(ТекстJSON, 1) = "[" Тогда
// начало массива
МассивДанных = Новый Массив;
ЗаполнитьДанныеИзОтветаJSON(МассивДанных, ТекстJSON, "Массив");
Результат.Вставить("Значение", МассивДанных);
КонецЕсли;
Возврат Результат;
КонецФункции
Функция КодСимволаASCII(Символ)
КодUNICODE = КодСимвола(Символ);
Если ((КодUNICODE > 1039) И (КодUNICODE < 1104)) Тогда
Возврат (КодUNICODE - 848);
ИначеЕсли КодUNICODE = 8470 Тогда
Возврат 185;
ИначеЕсли КодUNICODE = 1105 Тогда
Возврат 184;
ИначеЕсли КодUNICODE = 1025 Тогда
Возврат 168;
Иначе
Возврат КодUNICODE;
КонецЕсли;
КонецФункции
Функция URLEncode(value)
table = "%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14" +
"%15%16%17%18%19%1A%1B%1C%1D%1E%1F%20%21%22%23%24%25%26%27%28" +
"%29%2A%2B%2C%2D%2E%2F%30%31%32%33%34%35%36%37%38%39%3A%3B%3C" +
"%3D%3E%3F%40%41%42%43%44%45%46%47%48%49%4A%4B%4C%4D%4E%4F%50" +
"%51%52%53%54%55%56%57%58%59%5A%5B%5C%5D%5E%5F%60%61%62%63%64" +
"%65%66%67%68%69%6A%6B%6C%6D%6E%6F%70%71%72%73%74%75%76%77%78" +
"%79%7A%7B%7C%7D%7E%7F%80%81%82%83%84%85%86%87%88%89%8A%8B%8C" +
"%8D%8E%8F%90%91%92%93%94%95%96%97%98%99%9A%9B%9C%9D%9E%9F%A0" +
"%A1%A2%A3%A4%A5%A6%A7%A8%A9%AA%AB%AC%AD%AE%AF%B0%B1%B2%B3%B4" +
"%B5%B6%B7%B8%B9%BA%BB%BC%BD%BE%BF%C0%C1%C2%C3%C4%C5%C6%C7%C8" +
"%C9%CA%CB%CC%CD%CE%CF%D0%D1%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC" +
"%DD%DE%DF%E0%E1%E2%E3%E4%E5%E6%E7%E8%E9%EA%EB%EC%ED%EE%EF%F0" +
"%F1%F2%F3%F4%F5%F6%F7%F8%F9%FA%FB%FC%FD%FE%FF";
result = "";
length = СтрДлина( value );
Для i = 1 По length Цикл
symbol = Сред( value, i, 1 );
//code = КодСимвола( symbol );
code = КодСимволаASCII( symbol );
result = result + Сред( table, code*3 + 1, 3 );
КонецЦикла;
Возврат result;
КонецФункции
/////////////////////////РАБОТА С JSON //////////////////////////////////////////
//Функция декодирует полученный unicod текст - из ответа геокодера Рамблера
// в привычный нам
//Параметры:
// Строка
//Возвращаемое значение:
// Строка
Функция UnicodeEncode(Строка) Экспорт
Результат = Истина;
Попытка
//регулярное выражение
Рег = Новый COMОбъект("VBScript.RegExp");
Рег.IgnoreCase = Истина;
Рег.Global = Истина;
Рег.Multiline = Ложь;
Рег.Pattern = "u[0-9a-f]+";
Колекция = Рег.Execute(Строка);
Для Каждого Элемент Из Колекция Цикл
Если СтрДЛина(Элемент.value) = 1 Тогда
Продолжить;
КонецЕсли;
КодСимвола = ПереводЧислаИз16в10(Сред(ВРег(Элемент.value), 2));
Символ = Символ(КодСимвола);
Строка = СтрЗаменить(Строка, "\" + Элемент.value, Символ);
КонецЦикла;
Исключение
Результат = Ложь;
Сообщить("Ошибка преобразования из Unicode", СтатусСообщения.Информация);
КонецПопытки;
Возврат Результат;
КонецФункции
Функция ПереводЧислаИз16в10(Знач Значение)
Результат = 0;
//перевод значения в строку
Если ТипЗнч(Значение) <> Тип("Строка") Тогда
Значение = СокрЛП(Строка(Значение));
КонецЕсли;
МаксРазрядЦелых = 0;
МаксРазрядЦелых = СтрДлина(Значение) - 1;
н = МаксРазрядЦелых;
Ин = 1;
Пока н >= 0 Цикл
ТекЗначение = СтруктураЧисел.Получить(Сред(Значение, Ин, 1)) * Pow(16, н);
Результат = Результат + ТекЗначение;
н = н - 1;
Ин = Ин + 1;
КонецЦикла;
Возврат Результат;
КонецФункции
///////////////////////////
СтруктураПоставщиковКарт = Новый Соответствие;
СтруктураПоставщиковКарт.Вставить(0, "Яндекс");
СтруктураПоставщиковКарт.Вставить(1, "Гугл");
СтруктураПоставщиковКарт.Вставить(2, "2ГИС");
СтруктураПоставщиковКарт.Вставить(3, "Рамблер");
СтруктураЧисел = Новый Соответствие;
СтруктураЧисел.Вставить("0", 0);
СтруктураЧисел.Вставить("1", 1);
СтруктураЧисел.Вставить("2", 2);
СтруктураЧисел.Вставить("3", 3);
СтруктураЧисел.Вставить("4", 4);
СтруктураЧисел.Вставить("5", 5);
СтруктураЧисел.Вставить("6", 6);
СтруктураЧисел.Вставить("7", 7);
СтруктураЧисел.Вставить("8", 8);
СтруктураЧисел.Вставить("9", 9);
СтруктураЧисел.Вставить("A", 10);
СтруктураЧисел.Вставить("B", 11);
СтруктураЧисел.Вставить("C", 12);
СтруктураЧисел.Вставить("D", 13);
СтруктураЧисел.Вставить("E", 14);
СтруктураЧисел.Вставить("F", 15);
Код Формы Управляемой:
Код 1C v 8.2 УП
&НаКлиенте
Процедура НайтиАдрес(Команда)
НайтиАдресНаКарте(ТекАдрес);
КонецПроцедуры
&НаКлиенте
Процедура ИнициализацияКарты(Команда)
ИнициализироватьКарту();
КонецПроцедуры
&НаКлиенте
Процедура СправочнаяИнформация(Команда)
Элементы.ГруппаСправка.Видимость = Не Элементы.ГруппаСправка.Видимость;
КонецПроцедуры
&НаКлиенте
Процедура Разработчик(Команда)
ЗапуститьПриложение("http://smaylukk.com.ua/?lang=Ru");
КонецПроцедуры
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Объект.ТипКарты = Параметры.ТипКарты;
ТекОбъект = РеквизитФормыВЗначение("Объект");
Поставщик = ТекОбъект.СтруктураПоставщиковКарт.Получить(Объект.ТипКарты);
Макет = ТекОбъект.ПолучитьМакет("Справка");
ТекстСправки = Макет.ПолучитьОбласть("Справка" + Поставщик).Область().Текст;
Справка = ТекстСправки;
КонецПроцедуры
&НаКлиенте
Процедура ПриОткрытии(Отказ)
Элементы.ГруппаСправка.Видимость = Ложь;
Заголовок = "Работа с картами. Поставщик - " + Поставщик;
ИнициализироватьКарту();
КонецПроцедуры
&НаКлиенте
Процедура ПриЗакрытии()
//удаление временных файлов
Для Каждого ТекЭлемент Из МассивВременныхФайлов Цикл
УдалитьФайлы(ТекЭлемент.Значение);
КонецЦикла;
КонецПроцедуры
&НаКлиенте
//Процедура составляет имя процедуры поставщика
// и запускает ее на исполнение
//Параметры:
// НачалоИмени - Строка
Процедура ВыполнитьПроцедуруПоставщика(ИмяПроцедуры)
Выполнить ИмяПроцедуры;
КонецПроцедуры
&НаКлиенте
//процедура инициализирует карту постащика из макета
Процедура ИнициализироватьКарту()
Текст = ПолучитьТекстМакета("Макет" + Поставщик);
Эксплорер = Текст;
КонецПроцедуры
&НаСервере
Функция ПолучитьТекстМакета(ИмяМакета)
Макет = РеквизитФормыВЗначение("Объект").ПолучитьМакет(ИмяМакета);
Результат = Макет.ПолучитьТекст();
Возврат Результат;
КонецФункции
&НаКлиенте
Процедура ОчисткаКарты()
Элементы.Эксплорер.document.getElementById("WebClientOperation").value = "Reset()";
Элементы.Эксплорер.document.getElementById("WebClient").click();
КонецПроцедуры
///////////////////////////////////////////////////////////////////////
///////////////////ГЕОКОДИРОВАНИЕ И ПОИСК АДРЕСА///////////////////////
///////////////////////////////////////////////////////////////////////
&НаКлиенте
Процедура НайтиАдресНаКарте(Адрес = "")
//поиск адреса
Если Адрес = "" Тогда
Адрес = "Москва";
КонецЕсли;
// дальше пробуем с помощью геокодинга вывести данные поиска в таблицу
ТаблицаАдресов.Очистить();
ПоискАдреса(Адрес);
Если Поставщик = "Яндекс" Тогда
ПроизвестиГеокодинг_Яндекс();
ИначеЕсли Поставщик = "Гугл" Тогда
ПроизвестиГеокодинг_Гугл();
ИначеЕсли Поставщик = "Рамблер" Тогда
ПроизвестиГеокодинг_Рамблер();
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПоискАдреса(Адрес)
Элементы.Эксплорер.document.getElementById("WebClientOperation").value = "FindAdres(""" + Адрес + """);";
Элементы.Эксплорер.document.getElementById("WebClient").click();
КонецПроцедуры
&НаСервере
//Процедура выводит в таблицу данные геокдинга Яндекса
//
//Параметры:
// ТекАдрес - Строка
Процедура ПроизвестиГеокодинг_Яндекс()
Яндекс = Новый HTTPСоединение("geocode-maps.yandex.ru");
ВременныйФайл = КаталогВременныхФайлов() + "Yandex_geocode_" + СокрЛП(Новый УникальныйИдентификатор);
Попытка
Яндекс.Получить("/1.x/?geocode=" + ТекАдрес + "&results=10", ВременныйФайл);
Исключение
Сообщить("Ошибка при попытке геокодировать по яндексу адрес: " + ТекАдрес);
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ВременныйФайл);
ПостроительDOM = Новый ПостроительDOM;
ДокументДОМ = ПостроительDOM.Прочитать(ЧтениеXML);
СписокText = ДокументДОМ.ПолучитьЭлементыПоИмени("text");
СписокPos = ДокументДОМ.ПолучитьЭлементыПоИмени("pos");
Если (СписокText.Количество() = 0) ИЛИ (СписокPos.Количество() = 0) Тогда
Возврат;
КонецЕсли;
Для ъ = 0 по СписокText.Количество()-1 Цикл
Координаты = СписокPos[Ъ].ТекстовоеСодержимое;
Разделитель = Найти(Координаты," ");
Широта = Число(Сред(Координаты, Разделитель + 1));
Долгота = Число(Лев(Координаты, Разделитель - 1));
Если Широта = 0 ИЛИ Долгота = 0 Тогда
Продолжить;
КонецЕсли;
стрАдрес = ТаблицаАдресов.Добавить();
Если СписокText.Количество() > ъ Тогда
стрАдрес.Адрес = СписокText[Ъ].ТекстовоеСодержимое;
стрАдрес.Широта = Широта;
стрАдрес.Долгота = Долгота;
КонецЕсли;
КонецЦикла;
МассивВременныхФайлов.Добавить(ВременныйФайл);
КонецПроцедуры
&НаСервере
//Процедура выводит в таблицу данные геокдинга Гугл
//
//Параметры:
// ТекАдрес - Строка
Процедура ПроизвестиГеокодинг_Гугл()
Гугл = Новый HTTPСоединение("maps.googleapis.com");
ВременныйФайл = КаталогВременныхФайлов() + "Google_geocode_" + СокрЛП(Новый УникальныйИдентификатор);
Попытка
Гугл.Получить("/maps/api/geocode/xml?address=" + ТекАдрес + "&language=ru&sensor=false", ВременныйФайл);
Исключение
Сообщить("Ошибка при попытке геокодировать по Google адрес: " + ТекАдрес);
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ВременныйФайл);
ПостроительDOM = Новый ПостроительDOM;
ДокументДОМ = ПостроительDOM.Прочитать(ЧтениеXML);
ТаблицаРезультатов = ДокументДОМ.ПолучитьЭлементыПоИмени("result");
Если ДокументДОМ.ПолучитьЭлементыПоИмени("status")[0].ТекстовоеСодержимое <> "OK" ИЛИ ТаблицаРезультатов.Количество() = 0 Тогда
Возврат;
КонецЕсли;
Для ТекРезультат = 0 по ТаблицаРезультатов.Количество() -1 Цикл
СписокText = ТаблицаРезультатов[ТекРезультат].ПолучитьЭлементыПоИмени("formatted_address");
ЭлементыШиротаДолгота = ТаблицаРезультатов[ТекРезультат].ПолучитьЭлементыПоИмени("location");
Широта = ЭлементыШиротаДолгота[0].ПолучитьЭлементыПоИмени("lat")[0].ТекстовоеСодержимое;
Долгота = ЭлементыШиротаДолгота[0].ПолучитьЭлементыПоИмени("lng")[0].ТекстовоеСодержимое;
Если Широта = 0 ИЛИ Долгота = 0 Тогда
Продолжить;
КонецЕсли;
стрАдрес = ТаблицаАдресов.Добавить();
стрАдрес.Широта = Широта;
стрАдрес.Долгота = Долгота;
стрАдрес.Адрес = СписокText[0].ТекстовоеСодержимое;
КонецЦикла;
МассивВременныхФайлов.Добавить(ВременныйФайл);
КонецПроцедуры
&НаСервере
//Процедура выводит в таблицу данные геокдинга Рамблер
//
//Параметры:
// ТекАдрес - Строка
Процедура ПроизвестиГеокодинг_Рамблер()
ТемпАдрес = СтрЗаменить(ТекАдрес, " ", "+");
Рамблер = Новый HTTPСоединение("maps.rambler.ru");
ВременныйФайл = КаталогВременныхФайлов() + "Рамблер_geocode_" + СокрЛП(Новый УникальныйИдентификатор);
Попытка
Рамблер.Получить("/search/?&a=search&q=" + ТемпАдрес + "&n=10", ВременныйФайл);
Исключение
Сообщить("Ошибка при попытке геокодировать по Рамблер адрес: " + ТекАдрес);
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
а = 1;
Т = Новый ТекстовыйДокумент;
Т.Прочитать(ВременныйФайл);
СтрокаОтвет = Т.ПолучитьТекст();
Результат = РеквизитФормыВЗначение("Объект").UnicodeEncode(СтрокаОтвет);
Если Результат Тогда
СтруктураJSON = РеквизитФормыВЗначение("Объект").ЗаполнитьСтруктуруИзОтветаJSON(СтрокаОтвет);
КонецЕсли;
МассивРезультатов = СтруктураJSON.res;
//обрабатываем элементы массива - только адреса. POI можно обработать отдельно пожеланию
Для Каждого Результат Из МассивРезультатов Цикл
Для Каждого ТекРезультат Из Результат.matches Цикл
стрАдрес = ТаблицаАдресов.Добавить();
стрАдрес.Долгота = Число(ТекРезультат.x);
стрАдрес.Широта = Число(ТекРезультат.y);
Если Результат.type = "addr" Тогда //Результат.type = "poi" - содержит в себе список точек интереса
стрАдрес.Адрес = ТекРезультат.addr;
Иначе
стрАдрес.Адрес = ТекРезультат.name + " - " + ТекРезультат.addr;
КонецЕсли;
КонецЦикла;
КонецЦикла;
МассивВременныхФайлов.Добавить(ВременныйФайл);
КонецПроцедуры
&НаКлиенте
Процедура ОбратнПоискАдреса(Широта, Долгота, Адрес)
Элементы.Эксплорер.document.getElementById("WebClientOperation").value = "ReverseSearchAdres(" + Широта + "," + Долгота + ", """ + Адрес + """);";
Элементы.Эксплорер.document.getElementById("WebClient").click();
КонецПроцедуры
&НаКлиенте
Процедура ТаблицаАдресовВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
Если ЗначениеЗаполнено(ТаблицаАдресов[ВыбраннаяСтрока].Широта) И ЗначениеЗаполнено(ТаблицаАдресов[ВыбраннаяСтрока].Долгота) Тогда
СтандартнаяОбработка = Ложь;
КонецЕсли;
Широта = Формат(ТаблицаАдресов[ВыбраннаяСтрока].Широта, "ЧЦ=10; ЧДЦ=7; ЧРД=.; ЧРГ=");
Долгота = Формат(ТаблицаАдресов[ВыбраннаяСтрока].Долгота, "ЧЦ=10; ЧДЦ=7; ЧРД=.; ЧРГ=");
ОбратнПоискАдреса(Широта, Долгота, ТаблицаАдресов[ВыбраннаяСтрока].Адрес);
КонецПроцедуры
&НаКлиенте
Процедура ТекАдресПриИзменении(Элемент)
НайтиАдресНаКарте(ТекАдрес);
КонецПроцедуры
///////////////////////////////////////////////////////////////////////
///////////////////МАРШРУТИЗАЦИЯ, КЛАСТЕРА И ПОЛИГОН///////////////////////////////////////
///////////////////////////////////////////////////////////////////////
&НаКлиенте
Процедура ЭксплорерПриНажатии(Элемент, ДанныеСобытия, СтандартнаяОбработка)
ПолучитьКоординаты();
КонецПроцедуры
&НаКлиенте
Процедура ПостроитьМаршрут(Команда)
Если ТаблицаТочек.Количество() <= 1 Тогда
Предупреждение("Недостаточно точек для построение маршрута!");
Возврат;
КонецЕсли;
Если Поставщик = "Яндекс" Тогда
ПостроитьМаршрут_Яндекс();
ИначеЕсли Поставщик = "Гугл" Тогда
ПостроитьМаршрут_Гугл();
ИначеЕсли Поставщик = "Рамблер" Тогда
ПостроитьМаршрут_Рамблер();
КонецЕсли;
КонецПроцедуры
&НаКлиенте
//Процедура выстраивает маршрут для Яндекса
//
//Параметры:
//
Процедура ПостроитьМаршрут_Яндекс()
ПараметрыМаршрута = ПолучитьПараметрыМаршрутаЯндекс();
ОчисткаКарты();
Элементы.Эксплорер.document.getElementById("WebClientOperation").value = "calcRoute(" + ПараметрыМаршрута + ")";
Элементы.Эксплорер.document.getElementById("WebClient").click();
КонецПроцедуры
&НаКлиенте
//Функция получает массив точек, для передачи параметров в Яндекс
//
//Параметры:
//
//Возвращаемое значение:
// Строка
Функция ПолучитьПараметрыМаршрутаЯндекс()
Результат = "";
Результат = Результат + "[[" + СтрЗаменить(Строка(ТаблицаТочек[0].Широта), ",", ".") + "," + СтрЗаменить(Строка(ТаблицаТочек[0].Долгота), ",", ".") + "],";
Для Ин = 1 По ТаблицаТочек.Количество() - 2 Цикл
Результат = Результат + "[" + СтрЗаменить(Строка(ТаблицаТочек[ин].Широта), ",", ".") + "," + СтрЗаменить(Строка(ТаблицаТочек[ин].Долгота), ",", ".") + "],";
КонецЦикла;
Результат = Результат + "[" + СтрЗаменить(Строка(ТаблицаТочек[ТаблицаТочек.Количество() - 1].Широта), ",", ".") + "," + СтрЗаменить(Строка(ТаблицаТочек[ТаблицаТочек.Количество() - 1].Долгота), ",", ".") + "]]";
Возврат Результат;
КонецФункции
&НаКлиенте
//Процедура выстраивает маршрут для Гугл
//
//Параметры:
//
Процедура ПостроитьМаршрут_Гугл()
ПараметрыМаршрута = ПолучитьПараметрыМаршрутаГугл();
ОчисткаКарты();
Элементы.Эксплорер.document.getElementById("WebClientOperation").value = "calcRoute(" + ПараметрыМаршрута + ")";
Элементы.Эксплорер.document.getElementById("WebClient").click();
КонецПроцедуры
&НаКлиенте
//Функция получает массив точек, для передачи параметров в Гугл
//
//Параметры:
//
//Возвращаемое значение:
// Строка
Функция ПолучитьПараметрыМаршрутаГугл()
Результат = "";
ВнутрМассив = "";
Результат = Результат + "[[" + СтрЗаменить(Строка(ТаблицаТочек[0].Широта), ",", ".") + "," + СтрЗаменить(Строка(ТаблицаТочек[0].Долгота), ",", ".") + "],";
Если ТаблицаТочек.Количество() = 2 Тогда
Результат = Результат + "[],";
Иначе
Для Ин = 1 По ТаблицаТочек.Количество() - 2 Цикл
ВнутрМассив = ВнутрМассив + "[" + СтрЗаменить(Строка(ТаблицаТочек[ин].Широта), ",", ".") + "," + СтрЗаменить(Строка(ТаблицаТочек[ин].Долгота), ",", ".") + "],";
КонецЦикла;
Результат = Результат + "[" + Сред(ВнутрМассив, 1, СтрДлина(ВнутрМассив) - 1) + "],";
КонецЕсли;
Результат = Результат + "[" + СтрЗаменить(Строка(ТаблицаТочек[ТаблицаТочек.Количество() - 1].Широта), ",", ".") + "," + СтрЗаменить(Строка(ТаблицаТочек[ТаблицаТочек.Количество() - 1].Долгота), ",", ".") + "]]";
Возврат Результат;
КонецФункции
&НаКлиенте
//Процедура выстраивает маршрут для Рамблера
//
//Параметры:
//
Процедура ПостроитьМаршрут_Рамблер()
ПараметрыМаршрута = ПолучитьПараметрыМаршрутаРамблер();
ОчисткаКарты();
Элементы.Эксплорер.document.getElementById("WebClientOperation").value = "calcRoute(" + ПараметрыМаршрута + ")";
Элементы.Эксплорер.document.getElementById("WebClient").click();
КонецПроцедуры
&НаКлиенте
//Функция получает массив точек, для передачи параметров в Рамблер
//
//Параметры:
//
//Возвращаемое значение:
// Строка
Функция ПолучитьПараметрыМаршрутаРамблер()
Результат = "";
Результат = Результат + "[[" + СтрЗаменить(Строка(ТаблицаТочек[0].Широта), ",", ".") + "," + СтрЗаменить(Строка(ТаблицаТочек[0].Долгота), ",", ".") + "],";
Для Ин = 1 По ТаблицаТочек.Количество() - 2 Цикл
Результат = Результат + "[" + СтрЗаменить(Строка(ТаблицаТочек[ин].Широта), ",", ".") + "," + СтрЗаменить(Строка(ТаблицаТочек[ин].Долгота), ",", ".") + "],";
КонецЦикла;
Результат = Результат + "[" + СтрЗаменить(Строка(ТаблицаТочек[ТаблицаТочек.Количество() - 1].Широта), ",", ".") + "," + СтрЗаменить(Строка(ТаблицаТочек[ТаблицаТочек.Количество() - 1].Долгота), ",", ".") + "]]";
Возврат Результат;
КонецФункции
&НаКлиенте
Процедура СоздатьКластер(Команда)
Если ТаблицаТочек.Количество() <= 1 Тогда
Предупреждение("Недостаточно точек для построение кластера!");
Возврат;
КонецЕсли;
ОчисткаКарты();
ПостроитьКластера();
КонецПроцедуры
&НаКлиенте
Процедура ПостроитьКластера()
Кол = ТаблицаТочек.Количество();
Индекс = 1;
Для Каждого ТекСтрока Из ТаблицаТочек Цикл
Широта = формат(ТекСтрока.Широта, "ЧРД=.");
Долгота = формат(ТекСтрока.Долгота, "ЧРД=.");
СодержимоеТочки = "Содерижмое точки"; //опять же можно вставить свое название
Элементы.Эксплорер.document.getElementById("WebClientOperation").value = "addToPointArray(" + Широта + "," + Долгота + ", '" + ТекСтрока.Точка + "', """ + СодержимоеТочки + """);";
Элементы.Эксплорер.document.getElementById("WebClient").click();
Состояние("Обработан " + Индекс + " из " + кол);
Индекс = Индекс + 1;
КонецЦикла;
Элементы.Эксплорер.document.getElementById("WebClientOperation").value = "drawCluster();";
Элементы.Эксплорер.document.getElementById("WebClient").click();
КонецПроцедуры
&НаКлиенте
Процедура ОчиститьВсе(Команда)
ОчисткаКарты();
ТаблицаТочек.Очистить();
КонецПроцедуры
&НаКлиенте
Процедура ОчиститьКарту(Команда)
ОчисткаКарты();
КонецПроцедуры
&НаКлиенте
Процедура ОчиститьТаблицу(Команда)
ТаблицаТочек.Очистить();
КонецПроцедуры
&НаКлиенте
//Процедура получает координаты установленной точки
Процедура ПолучитьКоординаты()
Попытка
ЧислоТип = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 12));
КоординатаX = Элементы.Эксплорер.document.getElementById("CoordX").value;
КоординатаX = ЧислоТип.ПривестиЗначение(КоординатаX);
КоординатаY = Элементы.Эксплорер.document.getElementById("CoordY").value;
КоординатаY = ЧислоТип.ПривестиЗначение(КоординатаY);
Кол = ТаблицаТочек.Количество();
Если КоординатаX > 0 И КоординатаY > 0 И (Кол = 0 Или КоординатаX <> ТаблицаТочек[Кол - 1].Широта И КоординатаY <> ТаблицаТочек[Кол - 1].Долгота) Тогда
НоваяСтрока = ТаблицаТочек.Добавить();
НоваяСтрока.Точка = "Точка" + ТаблицаТочек.Количество();
НоваяСтрока.Широта = КоординатаX;
НоваяСтрока.Долгота = КоординатаY;
КонецЕсли;
Исключение
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура ПострениеПолигона(Команда)
Если ТаблицаТочек.Количество() <= 1 Тогда
Предупреждение("Недостаточно точек для построение полигона!");
Возврат;
КонецЕсли;
ОчисткаКарты();
ПостроитьПолигон();
КонецПроцедуры
&НаКлиенте
//Процедура выстраивает маршрут для Рамблера
//
//Параметры:
//
Процедура ПостроитьПолигон()
МассивТочек = "[";
Для Каждого ТекТочка Из ТаблицаТочек Цикл
Широта = формат(ТекТочка.Широта, "ЧРД=.");
Долгота = формат(ТекТочка.Долгота, "ЧРД=.");
МассивТочек = МассивТочек + "[" + Широта + "," + Долгота + "],";
КонецЦикла;
МассивТочек = Сред(МассивТочек, 1, СтрДлина(МассивТочек) - 1) + "]";
Цвет16 = Получить16Цвет();
Название = "Полигон";//вставить свое
Элементы.Эксплорер.document.getElementById("WebClientOperation").value = "createPolygon(" + МассивТочек + ", '" + Название + "', '" + Цвет16 + "');";
Элементы.Эксплорер.document.getElementById("WebClient").click();
КонецПроцедуры
&НаСервере
//Функция возвращает значение случайного цвета в 16-ричном формате
//
//Параметры:
// нет
//Возвращаемое значение:
// Строка
Функция Получить16Цвет()
Результат = "";
Строка16 = "0123456789ABCDEF";
ГСЧ = Новый ГенераторСлучайныхЧисел;
Результат = "#";
Для н = 1 По 6 Цикл
м = ГСЧ.СлучайноеЧисло(1, 16);
Результат = Результат + Сред(Строка16, м, 1);
КонецЦикла;
Возврат Результат;
КонецФункции
Категория:
COM-объекты, WMI, WSH Добавим документы ODF (OpenOffice/LibreOffice) в стандартную обработку Загрузки Табличного документа Доброго времени суток!
Обработку ЗагрузкаданныхизТабличногоДокументаконечно должен знать каждый 1С-ник. И сколько бы обработок такого плана не появлялось, эта остается классикой. Даже претензии можно предъявлять если вы в ней что-то не понимаете к самой 1С. Хотя какие претензии, исходный код открыть – изучай, не хочу…
Еще чем мне нравится эта обработка – тем что вы читаете данные из внешнего источника, показываете их с помощью объекта табличное поле и только затем выбираете алгоритм загрузки в 1С. При чем загрузка у Вас происходит в среде 1С без привлечения дополнительных компонентов. Без всяких выпадов в неизвестный объект OLE, полей которые не прочитались в обработке загрузки. Если вы видете данные в табличном поле, то они и будут грузиться по вашему алгоритму.
Но что-то в ней не хватает. Конечно стандарта офисных документов ODF (Open Document Format и между прочим ГОСТ Р ИСО/МЭК 26300-2010). Как говаривал мой начальник – есть чем себя занять. Из всех внешних загрузок, которые сейчас есть к сожалению самыми распостраненными являются OLE(Com+) технологии. Возможно что-то еще появиться, но пока примемся за них.
Залезаем в код и видим несколько однотипных функуций
Функция мПрочитатьТабличныйДокументИзExcel(ТабличныйДокумент, ИмяФайла, НомерЛистаExcel = 1) Экспорт
Функция мПрочитатьТабличныйДокументИзТекста(ТабличныйДокумент, ИмяФайла, НомерЛистаExcel = 1) Экспорт
Пора добавить свою:
Код 1C v 8.х
// Функция считывает в табличный документ данные из файла в формате ODF Calc(ods)
//
// Параметры:
// ТабличныйДокумент – ТабличныйДокумент, в который необходимо прочитать данные
// ИмяФайла – имя файла в формате ODF, из которого необходимо прочитать данные
// НомерЛистаCalc – номер листа книги Calc, из которого необходимо прочитать данные
//
// Возвращаемое значение:
// Истина, если файл прочитан, Ложь – иначе
//
Функция мПрочитатьТабличныйДокументИзCalc(ТабличныйДокумент, ИмяФайла, НомерЛистаCalc = 1) Экспорт
ВыбФайл = Новый Файл(ИмяФайла);
Если НЕ ВыбФайл.Существует() Тогда
Сообщить(“Файл не существует!”);
Возврат Ложь;
КонецЕсли;
Попытка
ServiceManager = Новый COMОбъект(“com.sun.star.ServiceManager”);
Desktop = ServiceManager.CreateInstance(“com.sun.star.frame.Desktop”);
Desktop.getCurrentFrame().getContainerWindow().setVisible(Ложь); //сделаем невидимым основное окно.
//установим параметры – не показывать таблицу Calc
Параметры = Новый COMSafeArray(“VT_DISPATCH”, 1);
Свойство = ServiceManager.Bridge_GetStruct(“com.sun.star.beans.PropertyValue”);
Свойство.Name = “Hidden”;
Свойство.Value = true ;
Параметры.SetValue(0,Свойство);
Document = Desktop.LoadComponentFromURL(“file:///” + ИмяФайла, “_blank”, 0, Параметры);
Состояние(“Обработка файла Office Calc …”);
Листы = Document.getSheets();
Лист = Листы.getByIndex(НомерЛистаCalc-1);
Исключение
Сообщить(“Ошибка загрузки данных. Возможно неверно указан номер листа книги Calc.”);
Возврат ложь;
КонецПопытки;
ТабличныйДокумент.Очистить();
//Определение максимум ячейки с данными…
НульЯчейка = Лист.GetCellbyPosition(0,0);
НульКурсор = Лист.createCursorByRange(НульЯчейка);
НульКурсор.GotoEndOfUsedArea(1);
НульАдрес = НульКурсор.RangeAddress;
ПослСтрока = НульАдрес.EndRow;
ПослКолонка = НульАдрес.EndColumn;
//Для Column = 1 По ПослКолонка + 1 Цикл
// ТабличныйДокумент.Область(“C” + Формат(Column, “ЧГ=”)).ШиринаКолонки = Лист.getColumns.getByIndex(Column-1).Width;
//КонецЦикла;
Для Row = 1 По ПослСтрока + 1 Цикл
Если Лист.getCellByPosition(Column-1,Row-1).getType() = 0 Или Лист.getCellByPosition(Column-1,Row-1).getType() = 1 Тогда ТабличныйДокумент.Область(“R” + Формат(Row, “ЧГ=”) +”C” + Формат(Column, “ЧГ=”)).Текст = Лист.getCellByPosition(Column-1,Row-1).value;
ИначеЕсли Лист.getCellByPosition(Column-1,Row-1).getType() = 2 Тогда ТабличныйДокумент.Область(“R” + Формат(Row, “ЧГ=”) +”C” + Формат(Column, “ЧГ=”)).Текст = Лист.getCellByPosition(Column-1,Row-1).string;
КонецЕсли;
КонецЦикла;
//ServiceManager.quit();
Document.Dispose();
Document = 0;
Параметры = 0;
Desktop = 0;
ServiceManager = 0;
Возврат Истина;
КонецФункции
И добавим в форму выбора файла ods по тексту.
Код 1C v 8.х ДиалогВыбораФайла.Фильтр = “Табличный документ (*.mxl)|*.mxl|Лист Calc (*.ods)|*.ods|Лист Excel (*.xls)|*.xls|Текстовый документ (*.txt)|*.txt|dBase III (*.dbf)|*.dbf|”;
И выбор функции для ods
ИначеЕсли нРег(ФайлНаДиске.Расширение) = “.ods” Тогда
мПрочитатьТабличныйДокументИзCalc(ТабличныйДокумент,ДиалогВыбораФайла.ПолноеИмяФайла);
Вот так лучше.
Сайт
sikuda.ru Категория:
Работа с Microsoft Office и OpenOffice