ЗаписатьДатуJSON() в 1С 8.3: Код 1C v 8.3 Процедура ПреобразованиеДатыВДатуJSON() // Пример: 12.08.2023 09:15:29 ТестДата = Дата("20230812091529"); // Вариант записи - "ЛокальнаяДата" // Локальная дата без указания часового пояса. // // Преобразует дату в "2023-08-12T09:15:29" ДатаJSONСтрока = ЗаписатьДатуJSON(ТестДата, ФорматДатыJSON.ISO, ВариантЗаписиДатыJSON.ЛокальнаяДата); // Вариант записи - "ЛокальнаяДатаСоСмещением" // Локальная дата с указание смещения относительно всемирного координированного времени (UTC). // // Преобразует дату в "2023-08-12T09:15:29+03:00" ДатаJSONСтрока = ЗаписатьДатуJSON(ТестДата, ФорматДатыJSON.ISO, ВариантЗаписиДатыJSON.ЛокальнаяДатаСоСмещением); // Вариант записи - "УниверсальнаяДата // Дата в поясе UTC. // // Преобразует дату в "2023-08-12T09:15:29Z" ДатаJSONСтрока = ЗаписатьДатуJSON(ТестДата, ФорматДатыJSON.ISO, ВариантЗаписиДатыJSON.УниверсальнаяДата); //////////////////////// // Для формата: JavaScript , Microsoft, - необходимо использовать вариант записи "УниверсальнаяДата"! // Преобразует дату в "new Date(1691820929)" ДатаJSONСтрока = ЗаписатьДатуJSON(ТестДата, ФорматДатыJSON.JavaScript , ВариантЗаписиДатыJSON.УниверсальнаяДата); // Преобразует дату в "/Date(1691820929)/" ДатаJSONСтрока = ЗаписатьДатуJSON(ТестДата, ФорматДатыJSON.Microsoft, ВариантЗаписиДатыJSON.УниверсальнаяДата);КонецПроцедуры // ПреобразованиеДатыВДатуJSON()
Категория:
WEB-сервисы, WS-ссылки, XDTO-пакеты Функция получение содержимого адреса url (веб-страницы) методом GET // Возвращает содержимое ответа HTTP-сервера, полученного методом GET, в виде строки или двоичных данных
// ** Coded by Sergey (aka Porutchik) * 2014 http://forum.aeroion.ru/cat1.html //
// Параметры
// СерверПриемник - - доменное имя сервера или полный адрес (url) запрашиваемой ссылки.
// Может включать протокол (http://, https://) и порт.
// АдресСтраницы - - опционально. Адрес страницы на сервере без протокола (http://, https://),
// доменного имени сервера (хоста) и порта.
// Если не указано, адрес страницы будет извлечён из параметра СерверПриемник
// ПараметрыСоединения - - опционально. Структура, содержащая дополнительные параметры для HTTPСоединение.
// Назначение ключей:
// Логин или Пользователь - Тип Строка - Имя пользователя на указанном сервере.
// Пароль - Тип Строка - Пароль пользователя на указанном сервере.
// Прокси - Тип ИнтернетПрокси - Прокси, используемый для соединения с сервером.
// Таймаут - Тип Число - Таймаут осуществляемого соединения и операций, в секундах. 0 - не устанавливать таймаут..
// ЗаголовкиHTTP - - опционально.
// Заголовки, которые будут отправлены на сервер в виде соответствия: "Заголовок" - "Значение".
// Если указано, функция возвратит в программу заголовки HTTP-ответа с кодом состояния в ключе StatusCode,
// имя файла в ключе FileName, url-кодированное имя в ключе EncodeFileName
// ПолучитьКакДвоичныеДанные - - опционально. Определяет, в каком виде получить содержимое ответа сервера
// По умолчанию Ложь.
// ЗащищенноеСоединение - - опционально. По умолчанию Ложь.
// Если Истина, соединение будет происходить по протоколу https://
//
// Возвращаемое значение:
// , - содержимое ответа сервера, если ресурс найден по указанному адресу.
//
Функция ПолучитьСодержимоеВебАдреса(Знач СерверПриемник, Знач АдресСтраницы = "",
Знач ПараметрыСоединения = Неопределено, ЗаголовкиHTTP = Неопределено,
Знач ПолучитьКакДвоичныеДанные = Ложь, Знач ЗащищенноеСоединение = Ложь) Экспорт
Перем ИмяФайлаОтветаКодированное, ИмяФайлаОтвета, Порт, Логин, Пользователь, Пароль, Прокси, Таймаут;
Если Не ЗначениеЗаполнено(СерверПриемник) Тогда Возврат Неопределено; КонецЕсли;
Если ТипЗнч(ЗаголовкиHTTP) Тип("Соответствие") Тогда ЗаголовкиHTTP = Новый Соответствие; КонецЕсли;
Если Найти(Нрег(СерверПриемник), "https://") = 1 Тогда ЗащищенноеСоединение = Истина; КонецЕсли;
Протокол = ?(Найти(Нрег(СерверПриемник), "https://") = 1 ИЛИ ЗащищенноеСоединение, "https://", "http://");
Если Лев(НРег(СерверПриемник), СтрДлина(Протокол)) = Протокол Тогда
СерверПриемник = Сред(СерверПриемник, СтрДлина(Протокол) + 1);
КонецЕсли;
Если НЕ ЗначениеЗаполнено(АдресСтраницы) Тогда
Позиция = Найти(СерверПриемник, "/");
Если Позиция > 0 Тогда
АдресСтраницы = Сред(СерверПриемник, Позиция, СтрДлина(СерверПриемник));
СерверПриемник = Лев(СерверПриемник, Позиция - 1);
Иначе
АдресСтраницы = "/";
КонецЕсли;
КонецЕсли;
СерверПриемник = СтрЗаменить(СерверПриемник, "/", "");
//Выделяем порт из доменного имени
ПозицияДвоеточия = Найти(СерверПриемник, ":");
Если ПозицияДвоеточия > 0 Тогда
Порт = Число(Сред(СерверПриемник, ПозицияДвоеточия + 1));
СерверПриемник = Лев(СерверПриемник, ПозицияДвоеточия - 1);
КонецЕсли;
Если ТипЗнч(ПараметрыСоединения) = Тип("Структура") Тогда
Для каждого КлючЗначение из ПараметрыСоединения Цикл
Значение = КлючЗначение.Значение; Выполнить(КлючЗначение.Ключ + " = Значение;");
КонецЦикла;
Пользователь = ?(ЗначениеЗаполнено(Пользователь), Пользователь, Логин);
КонецЕсли;
НТТР = Новый HTTPСоединение(СерверПриемник, Порт, Пользователь, Пароль, Прокси, Таймаут,
?(ЗащищенноеСоединение, Новый ЗащищенноеСоединениеOpenSSL(), Неопределено));
//Ответ от сервера получим в возвращаемом значении типа HTTPОтвет
ОтветHTTP = НТТР.Получить(Новый HTTPЗапрос(АдресСтраницы, ЗаголовкиHTTP)); //
ОшибкаЗапроса = (ОтветHTTP.КодСостояния >= 400);
//После получения ответа сервера необходимо проверить статус или код состояния.
//http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.... //Если сервер вернул один из статусов переадресации
//301 Moved Permanently («перемещено навсегда») или 302 Moved Temporarily («перемещено временно»),
//то в этом случае можно попытаться перейти на ресурс, на который переадресовал сервер
Если ОтветHTTP.КодСостояния = 301 или ОтветHTTP.КодСостояния = 302 Тогда
Если ОтветHTTP.Заголовки.Количество() > 0 Тогда
//Адрес страницы переадресации содержится в поле Location заголовка ответа
АдресСтраницы = ОтветHTTP.Заголовки["Location"]; //
Если ЗначениеЗаполнено(АдресСтраницы) Тогда
Если Найти(НРег(АдресСтраницы), "http://") = 0 И Найти(НРег(АдресСтраницы), "https://") = 0 Тогда
АдресСтраницы = ?(Лев(АдресСтраницы, 1) = "/", Сред(АдресСтраницы, 2), АдресСтраницы);
Если Найти(АдресСтраницы, СерверПриемник + "/") = 0 Тогда
АдресСтраницы = Протокол + СерверПриемник + ?(ЗначениеЗаполнено(Порт), ":" + Порт, "") + "/" + АдресСтраницы;
КонецЕсли;
КонецЕсли;
//Если сервер вернул cookies (http://ru.wikipedia.org/wiki/HTTP_cookie, http://www.faqs.org/rfcs/rfc6265.html?#41;, //вставим их в заголовки для передачи на страницу перехода
Куки = ОтветHTTP.Заголовки["Set-Cookie"];//
Если ЗначениеЗаполнено(Куки) Тогда ЗаголовкиHTTP.Вставить("Cookie", Куки); КонецЕсли;
//Рекурсивный вызов
Возврат ПолучитьСодержимоеВебАдреса(АдресСтраницы, , , ЗаголовкиHTTP, ПолучитьКакДвоичныеДанные, ЗащищенноеСоединение);//
КонецЕсли;
КонецЕсли;
ИначеЕсли ОтветHTTP.КодСостояния >= 100 И ОтветHTTP.КодСостояния 0 Тогда
ТипСодержимого = ОтветHTTP.Заголовки["Content-Type"];
//http://ru.wikipedia.org/wiki/Список_MIME-типов Если Найти(ТипСодержимого, "text/") = 1 ИЛИ Найти(ТипСодержимого, "/javascript ")
ИЛИ Найти(ТипСодержимого, "+xml") ИЛИ Найти(ТипСодержимого, "/xml") 0 ИЛИ Найти(ТипСодержимого, "/json") 0 Тогда
ПолучитьКакДвоичныеДанные = Ложь;
ИначеЕсли Найти(ТипСодержимого, "image/") = 1 ИЛИ Найти(ТипСодержимого, "video/") = 1
ИЛИ Найти(ТипСодержимого, "application/") = 1 ИЛИ Найти(ТипСодержимого, "audio/") = 1 Тогда
//Если содержимое полученного ответа представляет собой изображение, видео, приложение,
//возвращаем двоичные данные, так как возвращать в виде строки не имеет смысла.
ПолучитьКакДвоичныеДанные = Истина;
КонецЕсли;
//Некоторые сервера возвращают в типе содержимого имя отданного файла, например image/png; name="Имя файла.png"
//или отдают в заголовке Content-Disposition: attachment; filename=Имя файла.png (http://www.http11.ru/post.php?post=2) Если ОтветHTTP.Заголовки["Content-Disposition"] Неопределено Тогда
ТипСодержимого = ОтветHTTP.Заголовки["Content-Disposition"];
КонецЕсли;
ТипСодержимого = СтрЗаменить(СтрЗаменить(ТипСодержимого, """", ""), "'", "");
//в ключе filename*=UTF-8'' содержится url-кодированное имя файла
ПозицияИмениФайла = Найти(ТипСодержимого, "filename*=UTF-8");
Если ПозицияИмениФайла 0 Тогда
ИмяФайлаОтветаКодированное = Сред(ТипСодержимого, ПозицияИмениФайла + СтрДлина("filename*=UTF-8"));
ПозицияДвоеточия = Найти(ИмяФайлаОтветаКодированное, ";");
Если ПозицияДвоеточия 0 Тогда
ИмяФайлаОтветаКодированное = Лев(ИмяФайлаОтветаКодированное, ПозицияДвоеточия - 1);
КонецЕсли;
КонецЕсли;
//в ключе filename= содержится обычное имя файла
ПозицияИмениФайла = Найти(ТипСодержимого, "name=");
Если ПозицияИмениФайла 0 Тогда
ИмяФайлаОтвета = Сред(ТипСодержимого, ПозицияИмениФайла + СтрДлина("name="));
ПозицияДвоеточия = Найти(ИмяФайлаОтвета, ";");
Если ПозицияДвоеточия 0 Тогда
ИмяФайлаОтвета = Лев(ИмяФайлаОтвета, ПозицияДвоеточия - 1);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ЗаголовкиHTTP = ОтветHTTP.Заголовки;
//Добавляем в заголовки ответа код состояния (ответа) HTTP-сервера и имя файла содержимого, если есть.
ЗаголовкиHTTP.Вставить("StatusCode", ОтветHTTP.КодСостояния);
Если ЗначениеЗаполнено(ИмяФайлаОтвета) Тогда ЗаголовкиHTTP.Вставить("FileName", ИмяФайлаОтвета); КонецЕсли;
Если ЗначениеЗаполнено(ИмяФайлаОтветаКодированное) Тогда
ЗаголовкиHTTP.Вставить("EncodeFileName", ИмяФайлаОтветаКодированное);
КонецЕсли;
Если ОшибкаЗапроса ИЛИ НЕ ПолучитьКакДвоичныеДанные Тогда Возврат ОтветHTTP.ПолучитьТелоКакСтроку(); КонецЕсли;
Возврат ОтветHTTP.ПолучитьТелоКакДвоичныеДанные();
КонецФункции // ПолучитьСодержимоеВебАдреса()
//Источник: http://forum.aeroion.ru/topic749.html [/pre]Примеры использования:
// Получение содержимого в виде строки//
СодержимоеАдреса = ПолучитьСодержимоеВебАдреса("
//
ЗаголовкиHTTP = Новый Соответствие;
ЗаголовкиHTTP.Вставить("Referer", "a href="http://some_site.com/" )"="">http://some_site.com/");
СодержимоеАдреса = ПолучитьСодержимоеВебАдреса(" Категория: Нет
Как получить координаты выделенной области на Яндекс Карте? На одном проекте потребовалось получать координаты выделенной области на яндекс карте, после долгих изучений получилось следующее:
Вид Формы: На карте выделяете объект, нажимаете кнопку Получить координаты выделенной области и заполняется таблица координат
Код инициализации карты и обработчик кнопки получения координат:
Код 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С Формат 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 Как в 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-пакеты Загрузка данных из таблицы OpenOffice Calc v.3 Код 1C v 8.х Процедура ЗагрузитьПрайс(Кнопка)
Попытка
ServiceManager = Новый ComОбъект("com.sun.star.ServiceManager");
МетодЗагрузки = "ОО";
Исключение
Сообщить("Отсутствует приложение для загрузки файла");
КонецПопытки;
Если МетодЗагрузки = "ОО" Тогда
scr = Новый ComОбъект("MSScriptControl.ScriptControl");
scr.language = "javascript ";
scr.eval("MassivParametrov = new Array()");
MassivParametrov = scr.eval("MassivParametrov");
scr.AddObject("OpenOffice", ServiceManager);
scr.eval("MassivParametrov[0]=OpenOffice.Bridge_GetStruct('com.sun.star.beans.PropertyValue')");
scr.eval("MassivParametrov[0].Name='Hidden'");
scr.eval("MassivParametrov[0].Value=true");
Desktop = ServiceManager.CreateInstance("com.sun.star.frame.Desktop");
URL = ConvertToURL(ПутьКПрайсу);
Doc = Desktop.LoadComponentFromURL(URL, "_blank", 0, MassivParametrov);
Doc.lockControllers();
Doc.addActionLock();
Sheets = Doc.GetSheets();;
Документ = Sheets.GetByIndex(0);
//Документ = Sheets.GetByName("Лист1");
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Артикул");
ТЗ.Колонки.Добавить( "Цена");
Дальше = 1;
ТекСтрокаДок = НачальнаяСтрока;
Пока Дальше = 1 Цикл
Проверка = СокрЛП(""+Документ.getCellByPosition(0, ТекСтрокаДок).getString());
Если ПустаяСтрока(Проверка) Тогда
Прервать;
КонецЕсли;
Артикул = СокрЛП(""+Документ.getCellByPosition(КолонкаАртикула-1, ТекСтрокаДок).getString());
Попытка
Цена = Число(СокрЛП(""+Документ.getCellByPosition(КолонкаЦены-1 , ТекСтрокаДок).getString()));
Исключение
Цена = 0;
КонецПопытки;
Если (НЕ ПустаяСтрока(СокрЛП(Артикул))) и (НЕ Цена = 0) Тогда
НоваяСтрока = ТЗ.Добавить();
НоваяСтрока.Артикул = Артикул;
НоваяСтрока.Цена = Цена;
КонецЕсли;
Состояние("Обрабатываем - "+ТекСтрокаДок);
ТекСтрокаДок = ТекСтрокаДок+1;
КонецЦикла;
Если ТЗ.Количество() > 0 Тогда
Док = Документы.УстановкаЦенНоменклатуры.СоздатьДокумент();
Док.Дата = ДатаУстановкиЦен;
ДобавитьТипЦен = Док.ТипыЦен.Добавить();
ДобавитьТипЦен.ТипЦен = ТипЦены;
Для Каждого ТекСтрока из ТЗ Цикл
Номенклатура = Справочники.Номенклатура.НайтиПоРеквизиту("Артикул", ТекСтрока.Артикул);
Если НЕ Номенклатура.Пустая() Тогда
НоваяСтрока = Док.Товары.Добавить();
НоваяСтрока.Номенклатура = Номенклатура;
НоваяСтрока.ТипЦен = ТипЦены;
НоваяСтрока.Цена = ТекСтрока.Цена;
НоваяСтрока.Валюта = Валюта;
НоваяСтрока.ЕдиницаИзмерения = Номенклатура.ЕдиницаХраненияОстатков;
КонецЕсли;
КонецЦикла;
Если Док.Товары.Количество() > 0 Тогда
Док.Записать();
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
функция ConvertToURL(FileName)
ИмяФайла = СтрЗаменить(FileName," ","%20" );
ИмяФайла = СтрЗаменить(ИмяФайла,"\","/");
Возврат "file:/" + "/localhost/" + ИмяФайла;
Конецфункции
Категория:
Работа с Microsoft Office и OpenOffice Google maps, поиск оптимального маршрута В данном посте хочу коснуться основных аспектов построения оптимального маршрута с использованием API Google maps. Исходные данные для построения маршрута:
* Географические координаты объектов, которые хранятся в базе;
* Координаты начальной и конечной точек маршрута.
В процессе решения задачи был использован
пример API Google maps, так же само
описание использование массива точек для построения оптимального маршрута.
Для построения оптимального маршрута, необходимо сформировать HTML-код, который будет показан в элементе управления вида «Поле HTML документа».
Во время формирования HTML-кода в него пишутся координаты объектов, которые надо посетить. В нашем случае это строковая переменная МассивОбъектовПосещения, в которой храниться массив объектов посещения. Каждый объект посещения это элемент, который заполняется по примеру: ['Объект посещения', '49.438022, 32.069693'] (первый элемент – описание объекта, второй – географические координаты объекта). Переменная МассивОбъектовПосещения в коде инициализируется следующим образом:
Код 1C v 8.х Сч = 0; МассивОбъектовПосещения = "";
Для Каждого ТекСтрока Из ТаблицаОбъектов Цикл
МассивОбъектовПосещения = МассивОбъектовПосещения + "
| ['" + ?(ОтображатьПодчиненных, ТекСтрока.Ответственный, "") + ТекСтрока.Наименование + "', '"
+ СтрЗаменить(Строка(ТекСтрока.Широта),",",".") + ", "+ СтрЗаменить(Строка(ТекСтрока.Долгота),",",".") +"'],";
Сч = Сч + 1;
КонецЦикла;
МассивОбъектовПосещения = Лев(МассивОбъектовПосещения, СтрДлина(МассивОбъектовПосещения)-1);
Для построения оптимального маршрута используется вызов функции directionsService.route(), в которую необходимо передать параметры поиска. Параметры передаются следующие:
* origin – точка, с которой будет начинаться маршрут
* destination – точка, в которой будет заканчиваться маршрут
* waypoints – массив точек, которые надо обойти
* optimizeWaypoints – признак возможности оптимизации точек в массиве. В нашем случае необходимо определить его в true, тогда для алгоритма будет не важен порядок обхода точек.
* travelMode – признак того, какой вид транспорта используется. Мы ищем маршрут для автомобиля, поэтому необходимо установить значение google.maps.TravelMode.DRIVING.
После вызова функции directionsService.route() необходимо проверить результат построения (status == google.maps.DirectionsStatus.OK). Затем в цикле обходим составляющие маршрута и выводим информацию про маршрут в правую панель. В коде, приведенном ниже, цикл обхода: for (var i = 0; i < route.legs.length; i++) {}. Инициализация строковой переменной СтраницаХТМЛ, которая отображается в элементе управления с видом «Поле HTML документа», происходит следующим образом:
Код 1C v 8.х СтраницаХТМЛ =
"var directionDisplay;
| var directionsService = new google.maps.DirectionsService();
| var map;
| var myarr = [
| " + МассивОбъектовПосещения + "
| ];
| function initialize() {
| directionsDisplay = new google.maps.DirectionsRenderer();
| var myOptions = {mapTypeId: google.maps.MapTypeId.ROADMAP}
| map = new google.maps.Map(document.getElementById(""map_canvas""), myOptions);
| directionsDisplay.setMap(map);
| calcRoute();
| }
| function calcRoute() {
| var waypts = [];
| for (var i = 0; i < myarr.length; i++) {
| waypts.push({
| location:myarr[i][1],
| stopover:true});
| }
| var request = {
| origin: '" + НачалоМаршрута + "',
| destination: '" + КонецМаршрута + "',
| 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 = """";
| var summaryDistance = 0;
| // For each route, display summary information.
| for (var i = 0; i < route.legs.length; i++) {
| var routeSegment = i + 1;
| summaryPanel.innerHTML += ""Маршрут: "" + routeSegment;
| summaryPanel.innerHTML += route.legs[i].start_address + "" to "";
| summaryPanel.innerHTML += route.legs[i].end_address;
| summaryPanel.innerHTML += route.legs[i].distance.text;
| summaryDistance += parseFloat(route.legs[i].distance.value);
| }
| summaryPanel.innerHTML += ""Общая длинна маршрута: "";
| summaryPanel.innerHTML += summaryDistance;
| }
| });
| }
| initialize();
Андрей Данилюк Категория:
COM-объекты, WMI, WSH Простые примеры реализации демо-версий обработок на платформе «1С:Предприятие 8». Каждый из тех кто продает свой интеллектуальный труд, не раз сталкивался с необходимостью создания демо-версии разработки, дабы продемонстрировать клиенту функциональность, но при этом сохранить для клиента потребность в приобретении полнофункциональной версии. В этой статье я хотел бы рассмотреть несколько не сложных примеров создания демо-версий обработок/отчетов для платформы «1С:Предприятие 8».
Перед тем как приступить, собственно, к сути вопроса, хотелось бы сделать небольшое отступление для «крутых хакеров». Как известно, штатные возможности 1С, не представляют достаточно надежных средств для защиты исходного кода, поэтому приведенные здесь примеры – это исключительно защита от ПОЛЬЗОВАТЕЛЯ и ничего более.
Да и в целом, по моему глубокому убеждению, открытость кода в 1С – это одно из важнейших (если не самое важное) её достоинств. Поэтому я сторонник «установки пароля на модуль, поставки без исходного текста», только в случае демо-версии разработки. А при приобретении обработки, клиент приобретает её ЦЕЛИКОМ, в том числе и исходный код.
Для начала, немного общих моментов. Для того что бы ограничить использование нашего «уникального» функционала, будь-то алгоритм проведения документа или процедура формирования отчета, необходимо вынести код в модуль объекта и скрыть его от пользователя. Это можно достичь двумя путями. Во-первых установка пароля на модуль объекта. Что бы установить пароль, откройте модуль объекта, далее в меню «Текст» выберите пункт «Установить пароль». Во-вторых поставка без исходного кода. Что бы получить обработку/отчет без исходного кода, необходимо сначала создать поставку включающую в себя наш отчет без исходного кода, а затем сохранить его как внешний. Настройка поставки производится в диалоге «Конфигурация > Поставка конфигурации > Настройка поставки».
Итак, пример № 1. Ограничение по времени использования. Заключается в том, что функционал работает в течении определенного, ограниченного времени, например 10 дней. Для этого, нам надо как-то «запомнить» дату первого запуска, сделаем это с помощью реестра Windows.
Код 1C v 8.х Функция СрокДемоЗакончился()
Перем Значение;
RegProv=ПолучитьCOMОбъект("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv");
// 2147483649 - раздел реестра HKEY_CURRENT_USER
RegProv.GetStringValue("2147483649","Software\1C\1Cv8\Report","StartDate",Значение);
Если Значение=NULL Тогда // Ключ ещё не создан, считаем этот запуск первым
// Создадим ключ, установив значение в текущую дату
RegProv.CreateKey("2147483649","Software\1C\1Cv8\Report"); // создание раздела
// установка значения для ключа
RegProv.SetStringValue("2147483649","Software\1C\1Cv8\Report","StartDate",Строка(Формат(ТекущаяДата(),"ДФ=ггггММддЧЧммсс")));
Возврат Ложь;
Иначе
// проверка срока использования демо-версии
ДатаСтарта=Дата(Значение);
КонецПериода=ДатаСтарта+ 60 * 60 * 24 * 10; // 10 дней
ТекДата=ТекущаяДата();
Возврат НЕ (ТекДата>ДатаСтарта И ТекДата<=КонецПериода);
КонецЕсли;
КонецФункции
Таким образом, осталось только вставить проверку на продолжение работы в нашу основную процедуру, например:
Код 1C v 8.х Процедура СформироватьОтчет() Экспорт
Если СрокДемоЗакончился() Тогда
Возврат;
КонецЕсли;
…
КонецПроцедуры
Для особо хитрых пользователей, можно сделать запрос точного времени из Интернета, что бы защититься от изменения системного времени. Например, так:
Код 1C v 8.х Функция ТочноеВремяПоГринвичу()
XMLHTTP=Новый COMОбъект("MSXML2.XMLHTTP");
XMLHTTP.Open("get","http://ntp.greenwichmeantime.com/time/scripts/clock-7/x.php",Ложь);
XMLHTTP.Send();
UTC=Цел(XMLHTTP.Responsetext/1000); // в секундах
Возврат '19700101000000'+ UTC + 60 * 60 * 4; // по Москве, летнее время
КонецФункции
Пример №2. Ограничение по количеству выполнений. То есть к примеру, отчет в демо-версии можно сформировать не более 5-ти раз. Делается аналогично предыдущему варианту, разница заключается лишь в том, что в реестр на этот раз будем записывать номер текущего запуска.
Код 1C v 8.х Функция СрокДемоЗакончился()
Перем Значение;
RegProv=ПолучитьCOMОбъект("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv");
RegProv.GetDWORDValue("2147483649","Software\1C\1Cv8\Report","Count",Значение);
ЭтотЗапуск=1;
Если Значение=NULL Тогда
RegProv.CreateKey("2147483649","Software\1C\1Cv8\Report");
Иначе
ЭтотЗапуск=Значение+1;
КонецЕсли;
Если ЭтотЗапуск<=5 Тогда
RegProv.SetDWORDValue("2147483649","Software\1C\1Cv8\Report","Count",ЭтотЗапуск);
Возврат Ложь;
Иначе
Возврат Истина;
КонецЕсли;
КонецФункции
Пример №3. Реализация защиты «пароль-ответ». Недостаток предыдущих способов, заключается в том, что полнофункциональная версия является отдельной разработкой, которую клиенту необходимо переслать, привести, установить и т.д. При использовании же, следующего способа, всё что потребуется для получения полной версии разработки – это зарегистрировать обработку, т.е. ввести правильный код.
Суть этого способа состоит в том, что при запуске у клиента формируется некий уникальный ключ, для которого, по только нам известному алгоритму, можно сформировать «ответный пароль». И в случае совпадения пары ключ-ответ обработка считается успешно зарегистрированной.
В качестве такого уникального ключа можно, к примеру, использовать серийный номер жесткого диска, MAC-адрес, имя пользователя и т.д. Рассмотрим пример с серийным номером жесткого диска.
Код 1C v 8.х Функция ПолучитьСерийныйНомерЖесткогоДиска(Диск)
ФСО=Новый COMОбъект("Scripting.FileSystemObject");
ФСО_Диск=ФСО.GetDrive(Диск);
Возврат ФСО_Диск.SerialNumber;
КонецФункции
Алгоритм получения «ответного значения» по ключу, ограничен лишь Вашей фантазией. Здесь же, в качестве примера, я буду использовать простую перестановку символов в обратном порядке.
Код 1C v 8.х Функция ПолучитьОтветПоКлючу(Ключ)
н=СтрДлина(Ключ);
Результат="";
Пока н<>0 Цикл
Результат=Результат+Сред(Ключ,н,1);
н=н-1;
КонецЦикла;
Возврат Результат;
КонецФункции
Таким образом, наша процедура проверки и подтверждения регистрации будет выглядеть так:
Код 1C v 8.х Функция ЭтоЗарегистрированнаяКопия()
Перем Значение,Ответ;
RegProv=ПолучитьCOMОбъект("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv");
RegProv.GetDWORDValue("2147483649","Software\1C\1Cv8\Report","Registered",Значение);
Если Значение=NULL Тогда // необходима регистрация копии
Регистрация=Ложь;
Ключ=ПолучитьСерийныйНомерЖесткогоДиска("C");
Если ВвестиСтроку(Ответ,"Ключ: "+Ключ) Тогда
Если Ответ=ПолучитьОтветПоКлючу(Ключ) Тогда
// подтвердим регистрацию
RegProv.SetDWORDValue("2147483649","Software\1C\1Cv8\Report","Registered",1);
Регистрация=Истина;
Иначе
Предупреждение("Регистрационный код введен не верно!");
КонецЕсли;
КонецЕсли;
Возврат Регистрация;
Иначе // эта копия уже зарегистрированна
Возврат Истина;
КонецЕсли;
КонецФункции
Осталось только вставить проверку регистрации в нашу основную процедуру:
Код 1C v 8.х Процедура СформироватьОтчет() Экспорт
Если НЕ ЭтоЗарегистрированнаяКопия() Тогда
// работа в демо-режиме
...
КонецЕсли;
...
КонецПроцедуры
На данный момент, существуют различные декомпиляторы, плагины к Total Commander и др. разработки, позволяющие получить исходный программный код, даже если он закрыт паролем или поставляется в скомпилированном варианте. Дабы чуть-чуть усложнить жизнь пользователям умеющим пользоваться Google, можно ключевые моменты алгоритма, такие как работа с реестром или проверка регистрационного кода, дополнительно вынести во внешний шифрованный скрипт.
Начиная с Windows Script 5.0, появилась возможность чтения зашифрованных сценариев машинами сценариев. Поэтому любой сценарий написанный на VBScript или
JavaScript , может быть выполнен в зашифрованном виде. Что бы преобразовать код на VBScript в зашифрованный вид, воспользуемся бесплатной утилитой «Windows Script Encoder», которую можно скачать с сайта Microsoft. В результате, например скрипт создания в реестре Windows раздела «HKEY_CURRENT_USER\Software\1C\1Cv8\Report», будет выглядеть следующим образом:
#@~^ZAAAAA==jY~UtVV{ZMnlD+64N+^OvJU^DbwYcj4+^Vr#@#@&j4VsR"noqDrOPJuF;jw?KWDhCM+ 'FZ'F;-%'InwKDOwr~\(HE^V@#@&hyAAAA==^#~@
Приведу пример функции, осуществляющей проверку введенного пользователем регистрационного кода, с использованием шифрованного скрипта:
Код 1C v 8.х Функция ПроверитьРегистрационныйКод(Код)
Скрипт=Новый COMОбъект("MSScriptControl.ScriptControl");
Скрипт.Language="VBScript.Encode";
Скрипт.AddCode("#@~^ewAAAA==o!x^DkKxP;t"+Символ(127)+"^3v|nX*@#@&7zx/SnD{4wCs/"+Символ(127)+"@#@&d(0~F"+Символ(127)+"XxJ9^+Rl{qOv0q*rPPt"+Символ(127)+"U,bUkh"+Символ(127)+"D'74:.E"+Символ(127)+"P3x9P(W@#@&d;4+13'zUdh"+Символ(127)+"D@#@&3x[~wEUmDrW hyQAAA==^#~@ ");
Возврат Скрипт.CodeObject.Check(Код);
КонецФункции
Эта функция вернет «Истина», если в качестве регистрационного кода передать ей строку «dce8a7196f14». Аналогичным образом можно скрыть и всю работу с реестром. Но, тем не менее, не следует забывать о существующих специализированных программных продуктах, позволяющих отслеживать чтение и запись реестра.
В заключении, хочется сказать, что как известно, надежная защита для программного продукта – это такая защита, стоимость взлома которой, превышает стоимость законного приобретения. Поэтому для крупных проектов следует использовать более надежные средства от незаконного копирования и использования, такие как вынос ключевых функций во внешние dll, аппаратные ключи защиты и пр. Здесь же я попытался привести несколько простых примеров в качестве основ так сказать…
Источник Категория:
Полезные, Универсальные Функции Использование регулярных выражений (RegExp) в 1С Регулярные выражения (Regular Expressions) являются известным и мощным средством для поиска, тестирования и замены подстрок. Эта технология доступна и в 1С - через объект VBScript.RegExp. Нужный объект уже встроен в современные версии Windows (начиная с Windows 98), и устанавливать дополнительно ничего не нужно.
Приведенные ниже примеры были протестированы в 1С:Предприятие 7.7; для 1С:Предприятие 8.x изменяется способ создания объекта:
Код 1C v 8.х RegExp = Новый COMОбъект("VBScript.RegExp");
Кроме того, там уже есть логические константы Истина и Ложь - объявлять их не нужно.
Более подробное описание самой технологии RegExp (что означают те или иные значки или скобочки, или какие шаблоны поиска или замены можно использовать в типичных ситуациях) можно найти в специальной литературе (например Бен Форта "Освой самостоятельно регулярные выражения (regexp) за 10 минут") или на сайтах в сети Internet.
Код 1C v 7.x ///////////////////////////////////////////////////////////////////////
//Поиск вхождений подстроки
Процедура RegExp_Exec()
//Для 1С 7.7:
Истина=-1;
Ложь=0;
RegExp = CreateObject("VBScript.RegExp");
RegExp.IgnoreCase = Ложь; //Игнорировать регистр
RegExp.Global = Истина; //Поиск всех вхождений шаблона
RegExp.MultiLine = Ложь; //Многострочный режим
RegExp.Pattern = "<[^>]*>"; //Ищем теги HTML
Matches=RegExp.Execute("Это <hr> строка <br> с тегами HTML");
ЧислоВхождений=Matches.Count();
Если ЧислоВхождений>0 Тогда
Для к = 0 По ЧислоВхождений-1 Цикл
Match = Matches.Item(к);
Сообщить("Найден тег:"+ Match.Value);
КонецЦикла;
Иначе
Сообщить("Вхождений шаблона не найдено");
КонецЕсли;
//Выдаст в окно сообщений:
//Найден тег:<hr>
//Найден тег:<br>
КонецПроцедуры
Более продвинутый пример разбора HTML использует подвыражения (SubMatches) и позволяет находить как сами теги, так и текст между ними.
Код 1C v 7.x ///////////////////////////////////////////////////////////////////////
//Поиск вхождений подстроки с использованием подвыражений
Процедура RegExp_Exec1()
//Для 1С 7.7:
Истина=-1;
Ложь=0;
RegExp = CreateObject("VBScript.RegExp");
RegExp.IgnoreCase = Ложь; //Игнорировать регистр
RegExp.Global = Истина; //Поиск всех вхождений шаблона
RegExp.MultiLine = Ложь; //Многострочный режим
RegExp.Pattern = "([^<]*)(<[^>]*>)([^<]*)"; //Ищем теги HTML, а также текст до и после тега
Matches=RegExp.Execute(" <tr><td id=aaa>Дятел <td> долбит <td> сосну </tr>");
ЧислоВхождений=Matches.Count();
Если ЧислоВхождений>0 Тогда
Для к = 0 По ЧислоВхождений-1 Цикл
Match = Matches.Item(к);
SubMatches = Match.SubMatches;
ЧислоПодвыражений=SubMatches.Count();
Для н = 0 По ЧислоПодвыражений-1 Цикл
SubMatch=SubMatches.Item(н);
Если SubMatch="" Тогда
Продолжить;
КонецЕсли;
Сообщить("Подстрока: "+SubMatch);
КонецЦикла;
КонецЦикла;
Иначе
Сообщить("Вхождений шаблона не найдено");
КонецЕсли;
КонецПроцедуры
//Выводит в окно сообщений:
//Подстрока:
//Подстрока: <tr>
//Подстрока: <td id=aaa>
//Подстрока: Дятел
//Подстрока: <td>
//Подстрока: долбит
//Подстрока: <td>
//Подстрока: сосну
//Подстрока: </tr>
Часто регулярные выражения используются для тестирования строк, например пользовательского ввода.
Этот пример позволяет узнать, является ли строка целым числом.
Код 1C v 7.x ///////////////////////////////////////////////////////////////////////
//Проверка подстроки
Процедура RegExp_Test()
RegExp = CreateObject("VBScript.RegExp");
RegExp.Pattern = "^\d+$"; //Шаблон, который соответствует целому числу
стр="12345";//Строка, которую тестируем
Если RegExp.Test(стр)=0 Тогда
Сообщить("Это не целое число");
Иначе
Сообщить("Это целое число");
КонецЕсли;
//Выдаст в окно сообщений:
//"Это целое число"
КонецПроцедуры
Регулярные выражения поддерживают не только поиск, но и замену текста. При этом найденные подвыражения (в круглых скобках) могут быть представлены в строке замены как $1, $2 и т. д.
(знак доллара используется в VBScript.RegExp; в других средах программирования, например в
JavaScript , используемый для этой цели символ может отличаться).
Код 1C v 7.x ///////////////////////////////////////////////////////////////////////
//Замена текста в подстроке
Процедура RegExp_Replace()
//Строка, где мы будем производить замены
стр="Дятел долбил сосну";
Истина=-1;
Ложь=0;
RegExp = CreateObject("VBScript.RegExp");
RegExp.IgnoreCase = Истина; //Игнорировать регистр
RegExp.Global = Истина; //Поиск всех вхождений шаблона
RegExp.MultiLine = Истина; //Многострочный режим
RegExp.Pattern = "(долбил)";
стр=RegExp.Replace(стр, "про$1");
Сообщить(стр);
//Выдаст в окно сообщений:
//"Дятел продолбил сосну"
КонецПроцедуры
Источник Категория:
Регулярные выражения Выгрузка в PDF из 1С (Средствами OpenOffice) Возникла задача отправлять счета почтой. PDFcreator не подошёл поскольку не удалось вместить счёт на одну страницу по ширине. Решил попробовать OpenOffice. Как сохранять в PDF нашёл быстро, а вот как уместить счёт на одну страницу вширь искал долго.
В версии 1С 8.2.232 появилась возможность сохранять табличный документ в xls файл на сервера под линуксом. А вот работать с Опеном офисом из-под линукса пока не получается. Собственно комментари ненужны. Вот весь код. Самое интересное это бодание со стилями страниц в Опене Офисе. Жаль что этот фрагмент работает только на клиенте. На сервере вопрос не решается *08
Код 1C v 8.2 УП Процедура КнопкаВыполнитьНажатие(Кнопка)
Если Письмо.Основание.Пустая() Тогда
Возврат
КонецЕсли;
// Открыть OpenOffice
Попытка
ServiceManager = Новый COMОбъект("com.sun.star.ServiceManager");
Исключение
Возврат // опен офис не установлен :-(
КонецПопытки;
// получим печатную форму и запишем её во временный XLS файл
Заказ = Письмо.Основание.ПолучитьОбъект();
//Получим печатную форму
Расшифровка=Новый Структура;
Расшифровка.Вставить("СсылкаНаВнешнююОбработку",Константы.ПФСчетаДляКлиента.Получить());
Расшифровка.Вставить("ВидПечатнойФормы",Перечисления.ВидыДополнительныхВнешнихОбработок.ПечатнаяФорма);
Расшифровка.Вставить("НомерСтроки",1);
тд = УниверсальныеМеханизмы.НапечататьВнешнююФорму(Заказ, Расшифровка);
ВременныйФайл =ПолучитьИмяВременногоФайла();
ВременныйФайлXLS =ВременныйФайл + ".xls";
ВременныйФайлPDF =ВременныйФайл + ".pdf";
тд.Записать(ВременныйФайлXLS, ТипФайлаТабличногоДокумента.XLS97);
// Преобразовываем временный xls файл В PDF
Desktop = ServiceManager.createInstance("com.sun.star.frame.Desktop");
НастройкиОткрытия = Новый COMSafeArray("VT_VARIANT", 1);
PropertyValue = ServiceManager.Bridge_GetStruct("com.sun.star.beans.PropertyValue");
PropertyValue.Name = "Hidden";
PropertyValue.Value = Истина;
НастройкиОткрытия.SetValue(0, PropertyValue);
ВременныйФайлXLS_какУРЛ = "file:///" + СтрЗаменить(ВременныйФайлXLS, "\", "/"); // приводим путь к файлу из виндового формата в опен офисный
// Откроем файл в опене офисе
ОпенОфис = Desktop.LoadComponentFromURL(ВременныйФайлXLS_какУРЛ, "_blank", 0, НастройкиОткрытия);
//ПараметрыСтраницы = ОпенОфис.createInstance("com.sun.star.style.PageStyle");
//ПараметрыСтраницы.ScaleToPagesX = 1;
//
// Установим масштаб, чтобы счёт помещался на одной странице вширь
// страниц почему-то много, поэтому устанавливаем масштаб для всех
Стили = ОпенОфис.StyleFamilies.getByName("PageStyles");
Для поз = 0 по Стили.count - 1 Цикл
МойСтиль = Стили.getByIndex(поз);
МойСтиль.ScaleToPagesX = 1; // уместить на одной странице вширь
//МойСтиль.PageScale = 50; // масштаб 50%
КонецЦикла;
НастройкиСохранения = Новый COMSafeArray("VT_VARIANT", 1);
PropertyValue = ServiceManager.Bridge_GetStruct("com.sun.star.beans.PropertyValue");
PropertyValue.Name = "FilterName";
PropertyValue.Value = "calc_pdf_Export";
НастройкиСохранения.SetValue(0, PropertyValue);
ВременныйФайлPDF_какУРЛ = "file:///" + СтрЗаменить(ВременныйФайлPDF, "\", "/"); // приводим путь к файлу из виндового формата в опен офисный
ОпенОфис.storeToURL(ВременныйФайлPDF_какУРЛ, НастройкиСохранения); // сохранили PDF файл
ОпенОфис.close(-1);
ОпенОфис = Неопределено;
// С опеном офисом разобрались. Прикрепляем вложение к письму и удаляем временные файлы.
//Файл = Новый Файл(ВременныйФайлPDF);
объектПисьмо = Письмо.ПолучитьОбъект();
стрВложение = объектПисьмо.Вложения.Добавить();
стрВложение.ИмяФайла = "Счёт " + Строка(Заказ.Номер) + ".pdf";
стрВложение.Файл = Новый ХранилищеЗначения(Новый ДвоичныеДанные(ВременныйФайлPDF));
объектПисьмо.Записать();
Попытка
УдалитьФайлы(ВременныйФайлXLS);
УдалитьФайлы(ВременныйФайлPDF);
Исключение
КонецПопытки;
КонецПроцедуры
Автор:
Трактор
Функция позволяющая выполнить выгрузку табличного документа в PDF средствами OpenOffice
Код 1C v 8.х // Функция превращает табличный документ в PDF документ
// Возвращаемое значение: тип "Строка" - имя созданного PDF файла, 0 - в случае ошибки
// Параметры: ДанныеВыгрузки - Табличный или текстовый документ, который нужно выгрузить в PDF
// ПутьВыгрузки - тип "Строка", путь для сохраниения PDF файла (без имени и расширения файла)
// ИмяФайлаБезРасширения - тип "Строка", имя для вновь сформированного PDF файла
// Тестировалось на OpenOffice 3.x
Функция ВыгрузитьТабличныйДокументВPDF(ДанныеВыгрузки, ПутьВыгрузки, ИмяФайлаБезРасширения)
Если НЕ ЗначениеЗаполнено(ПутьВыгрузки) Тогда
ПутьВыгрузки = КаталогВременныхФайлов();
КонецЕсли;
ПутьВыгрузки = ?(Прав(ПутьВыгрузки, 1) = "\", ПутьВыгрузки, ПутьВыгрузки + "\");
РасширениеXSL = ".xls";
РасширениеPDF = ".pdf";
ПолноеИмяФайлаXLS = ПутьВыгрузки + ИмяФайлаБезРасширения + РасширениеXSL;
//Выгрузка данных печати в файл XLS
#Если Клиент Тогда
Состояние("Создание временного файла...");
#КонецЕсли
Попытка
Если ТипЗнч(ДанныеВыгрузки) = Тип("ТабличныйДокумент") Тогда
ДанныеВыгрузки.Записать(ПолноеИмяФайлаXLS, "XLS");
ИначеЕсли ТипЗнч(ДанныеВыгрузки) = Тип("ТекстовыйДокумент") Тогда
ДанныеВыгрузки.Записать(ПолноеИмяФайлаXLS, "XLS");
Иначе
#Если Клиент Тогда
Сообщить("Данные для выгрузки переданы в неподдерживаемом формате. Дальнейшее выполнение невозможно." + Символы.ПС + ОписаниеОшибки());
#КонецЕсли
Возврат 0;
КонецЕсли;
Исключение
#Если Клиент Тогда
Сообщить("Произошла ошибка при выгрузке временного файла. Возможно ошибка доступа к папке, в которую происходит запись." + Символы.ПС + ОписаниеОшибки());
#КонецЕсли
Возврат 0;
КонецПопытки;
Попытка
#Если Клиент Тогда
Состояние("Открытие компоненты OpenOffice...");
#КонецЕсли
ServiceManager = Новый COMОбъект("com.sun.star.ServiceManager");
Скрипт = Новый COMОбъект("MSScriptControl.ScriptControl");
Скрипт.language = "javascript ";
Скрипт.AddObject("OpenOffice", ServiceManager);
//Открытие временного файла без отображения его окна
#Если Клиент Тогда
Состояние("Открытие временного файла...");
#КонецЕсли
Скрипт.eval("Массив=new Array()");
Массив = Скрипт.eval("Массив");
Скрипт.eval("Массив[0] = OpenOffice.Bridge_GetStruct('com.sun.star.beans.PropertyValue')");
Скрипт.eval("Массив[0].Name = 'Hidden'");
Скрипт.eval("Массив[0].Value = true");
Скрипт.AddCode("function SetItem(ind,val){Массив[ind]=val}");
Скрипт.AddObject("ServiceManager",ServiceManager);
Desktop = ServiceManager.createInstance("com.sun.star.frame.Desktop");
Document = Desktop.LoadComponentFromURL("file:///" + ПолноеИмяФайлаXLS, "_blank", 0, Массив);
//Сохранение в PDF встроенными средствами OpenOffice
#Если Клиент Тогда
Состояние("Запись в PDF...");
#КонецЕсли
Скрипт.eval("Массив2=new Array()");
Массив2 = Скрипт.eval("Массив2");
Скрипт.eval("Массив2[0] = OpenOffice.Bridge_GetStruct('com.sun.star.beans.PropertyValue')");
Скрипт.eval("Массив2[0].Name = 'FilterName'");
Скрипт.eval("Массив2[0].Value = 'writer_pdf_Export'");
ПолноеИмяФайлаPDF = "file:///" + СтрЗаменить(ПолноеИмяФайлаXLS, РасширениеXSL, РасширениеPDF);
ПолноеИмяФайлаPDF = СтрЗаменить(ПолноеИмяФайлаPDF, ВРег(РасширениеXSL), РасширениеPDF);
ПолноеИмяФайлаPDF = СтрЗаменить(ПолноеИмяФайлаPDF, "\", "/");
Document.storeToURL(ПолноеИмяФайлаPDF, Массив2);
Document.close(-1); //Закрыть документ
//Контрольная очистка переменных
Document = Неопределено;
Desktop = Неопределено;
//Удаление временного файла
#Если Клиент Тогда
Состояние("Удаление временного файла...");
#КонецЕсли
Попытка
УдалитьФайлы(ПолноеИмяФайлаXLS);
Исключение
#Если Клиент Тогда
Сообщить("Произошла ошибка при удалении временного файла. Возможно, потребуется удалить его вручную." + Символы.ПС + ОписаниеОшибки());
#КонецЕсли
КонецПопытки;
ПолноеИмяФайлаPDF = СтрЗаменить(ПолноеИмяФайлаPDF, "file:///", "");
ПолноеИмяФайлаPDF = СтрЗаменить(ПолноеИмяФайлаPDF, "/", "\");
#Если Клиент Тогда
Состояние("Выгрузка выполнена.");
Предупреждение("Выгрузка выполнена." + Символы.ПС + ПолноеИмяФайлаPDF);
#КонецЕсли
Возврат ПолноеИмяФайлаPDF;
Исключение
Document.close(-1);
#Если Клиент Тогда
Предупреждение(ОписаниеОшибки());
#КонецЕсли
Возврат 0;
КонецПопытки
КонецФункции
Автор:
doom_2001 Категория:
Работа с Microsoft Office и OpenOffice 1C и Google Maps была поставлена задача отображения на географической карте медицинских учреждений. После обзора предлагаемых решений был выбран сервис google. Но так же подобного рода подход будет работать и с картами сервиса yandex. Во время решения задачи было решено использовать геокодирование сервиса Google и Google Visualization для отображение элементов на карте.
Геокодирование – процесс преобразования адресов·(Украина, Киевская область, Киев, Крещатик 20) в географические координаты (широта 37.423021 и долгота -122.083739), которые можно использовать для размещения маркеров или расположения карты. Подробно про геокодирование можно почитать
тут .
Для работы с геокодированием необходимо
зарегистрировать ключ API карт Google .
Важный момент: если у вас программа работает в локальной сети и в Internet, то вам необходимо регистрировать два ключа. В зависимости от того, с какого места подключается пользователь к базе подставлять тот или иной ключ.
И так, собственно программная реализация.
В конфигурации есть две общих формы:
* Форма подбора координат. Данная форма формирует запрос на геокодирование и обрабатывает результат.
* Форма отображения объектов. Данная форма использует
API визуализации Google . В частности данная форма использует визуализацию
Map .
Запрос и обработка результата геокодирования.
Формирование запроса происходит с ключом output=csv, для вывода результата запроса в csv файл. После выполнения запроса проверяется код результата запроса и разбор csv файла на широту и долготу.
Код 1C v 8.2 УП #НаСервере
Процедура ОтправитьЗапросНаПоискКоординат()
Город = Параметры.ОбъектПодбора.Город.Наименование;
Страна = Параметры.ОбъектПодбора.Город.Владелец.Владелец.Наименование;
Адрес = Параметры.ОбъектПодбора.Адрес;
ПараметрПоиска = Страна + " " + Город + " " + Адрес;
АдресOutput = ПолучитьИмяВременногоФайла();
Ключ = Константы.КлючКарта.Получить();
ТекстСсылки = "maps/geo?q=" + EncodeURL(ПараметрПоиска)+"&output=csv&oe=utf8&sensor=false&key=" + Ключ;
ПроксиСервер = Неопределено;
HTTPСервис = Новый HTTPСоединение("maps.google.com",,,,ПроксиСервер,Ложь);
ПравильностьВыполнения = Истина;
Попытка
HTTPСервис.Получить(ТекстСсылки, АдресOutput);
Исключение
Сообщить(ОписаниеОшибки(), СтатусСообщения.Важное);
ПравильностьВыполнения = Ложь;
КонецПопытки;
Если ПравильностьВыполнения Тогда
// Распарсить результат ответа поиска
Текст = Новый ТекстовыйДокумент;
Текст.Прочитать(АдресOutput);
РезультатПоиска = Текст.ПолучитьСтроку(1);
КодРезультата = Лев(РезультатПоиска,3);
РезультатПоиска = Сред(РезультатПоиска, 7, СтрДлина(РезультатПоиска));
Если КодРезультата <> "200" Тогда
Возврат;
КонецЕсли;
Широта = Число(Сред(РезультатПоиска,0,10));
Долгота = Число(Сред(РезультатПоиска,12,10));
КонецЕсли;
КонецПроцедуры
Формирование карты отображения
При формировании отображения объекта на карте к стандартному коду визуализации добавлен следующий:
Код 1C v 8.х if(!google.visualization) setTimeout(checkIfGoogleLoad, 1000);
else drawMap();
Это связано с тем, что платформа не хочет сразу обновлять фрейм поля html документа.
Код 1C v 8.2 УП #НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
СсылкаНаБазу = ПолучитьНавигационнуюСсылкуИнформационнойБазы();
APIГугла = Константы.КлючКарта.Получить();
ТаблицаОбъектовДляВывода = Новый ТаблицаЗначений;
ТаблицаОбъектовДляВывода.Колонки.Добавить("Наименование",Новый ОписаниеТипов("Строка"));
ТаблицаОбъектовДляВывода.Колонки.Добавить("Город",Новый ОписаниеТипов("Строка"));
ТаблицаОбъектовДляВывода.Колонки.Добавить("Адрес",Новый ОписаниеТипов("Строка"));
ТаблицаОбъектовДляВывода.Колонки.Добавить("Широта",Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(10,6)));
ТаблицаОбъектовДляВывода.Колонки.Добавить("Долгота",Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(10,6)));
Если Параметры.ОтображатьСОтветственными Тогда
ТаблицаОбъектовДляВывода.Колонки.Добавить("Ответственный",Новый ОписаниеТипов("Строка"));
КонецЕсли;
Для Каждого ТекЭлемент Из Параметры.ОбъектыДляОтображения Цикл
КоординатыОбъекта = ОбщийМодульКартаСервер.ПолучитьКоординатыОбъекта(ТекЭлемент.Значение.ОбъектПосещения);
Если КоординатыОбъекта = Неопределено Тогда
Продолжить;
Иначе
НоваяСтрока = ТаблицаОбъектовДляВывода.Добавить();
НоваяСтрока.Наименование = ТекЭлемент.Значение.ОбъектПосещения.Наименование;
НоваяСтрока.Город = ТекЭлемент.Значение.ОбъектПосещения.Город.Наименование;
НоваяСтрока.Адрес = ТекЭлемент.Значение.ОбъектПосещения.Адрес;
НоваяСтрока.Широта = КоординатыОбъекта[0];
НоваяСтрока.Долгота = КоординатыОбъекта[1];
Если Параметры.ОтображатьСОтветственными Тогда
НоваяСтрока.Ответственный = ТекЭлемент.Значение.Ответственный.Наименование;
КонецЕсли;
КонецЕсли;
КонецЦикла;
ТекстСкрипта = "data.addRows(" + Строка(ТаблицаОбъектовДляВывода.Количество()) + ");";
Сч = 0;
Для Каждого ТекСтрока Из ТаблицаОбъектовДляВывода Цикл
ТекстСкрипта = ТекстСкрипта + " data.setCell(" + Строка(Сч) + ", 0, " +СтрЗаменить(Строка(ТекСтрока.Широта),",",".") + ");";
ТекстСкрипта = ТекстСкрипта + " data.setCell(" + Строка(Сч) + ", 1, " +СтрЗаменить(Строка(ТекСтрока.Долгота),",",".") + ");";
ТекстСкрипта = ТекстСкрипта + " data.setCell(" + Строка(Сч) + ", 2, '" +Строка(ТекСтрока.Наименование) + " "
+ Строка(ТекСтрока.Город) + " " + Строка(ТекСтрока.Адрес) + " " + ?(Параметры.ОтображатьСОтветственными, ".Ответственный: " + Строка(ТекСтрока.Ответственный), "") + " " + "');";
Сч = Сч + 1;
КонецЦикла;
СтраницаХТМЛ = "<html>
| <head>
| <script src=""http://maps.google.com/maps?file=api&v=2&key=" + APIГугла + """ type=""text/javascript ""></script>
| <script type=""text/javascript "" src=""http://www.google.com/jsapi""></script>
| </head>
|
| <body>
| <div id=""map_div"" style=""width: 800px; height: 550px""></div>
| <script type=""text/javascript "">
|
| google.load(""visualization"", ""1"", {packages:[""map"">);
| google.setOnLoadCallback(drawMap);
| function checkIfGoogleLoad() {
| if(!google.visualization) setTimeout(checkIfGoogleLoad, 1000);
| else drawMap();
| }
| function drawMap() {
| var data = new google.visualization.DataTable();
| data.addColumn('number', 'Lat');
| data.addColumn('number', 'Lon');
| data.addColumn('string', 'Name');" + ТекстСкрипта + "
| var map = new google.visualization.Map(document.getElementById('map_div'));
| map.draw(data, {showTip: true, mapType: 'normal'});
| }
| checkIfGoogleLoad();
| </script>
| </body>
|</html>";
КонецПроцедуры
Андрей Данилюк Категория:
COM-объекты, WMI, WSH Настройка веб-браузеров для работы в веб-клиенте 8.2 Microsoft Internet Explorer
Для работы с веб-клиентом в операционной системе Windows XP SP 2 требуется наличие системной библиотеки jscript.dll версии 5.6.0.8834 или выше. Библиотека находится в каталоге system32 операционной системы. Если на вашем компьютере установлена более раняя версия библиотки, то возможно значительное замедление работы веб-клиента. Для обновления версии необходимо скачать пакет обновлений. Находящийся по адресу
http://support.Microsoft.com/kb/942840/en-us .
Для начала работы необходимо выполнить следующие настройки подключения:
· открыть браузер, в меню Сервис (Tools) выбрать пункт Свойства обозревателя (Internet Options).
· в открывшемся окне перейти на закладку Безопасность (Security).
· нажать кнопку Другой (Custom level…).
· в открывшемся окне в разделе Сценарии (Scripting) для параметра Активные сценарии (Active scripting) установить Разрешить или Включить (Enable) и нажать ОК.
· перейти на закладку Конфиденциальность (Privacy) и с помощью регулятора выбрать уровень использования cookies умеренный или Средний (Medium) (рекомендуется не выше Умеренно высокий (Medium High).
· на этой же закладке в разделе Блокирование всплывающих окон (Pop-up Bloker) снять флажок Блокировать всплывающие окна или Включить блокирование всплывающих окон (Blok Pop-ups или Turn on Pop-up Blocker).
Mozilla Firefox - Настройки подключения
Для начала работы необходимо выполнить следующие настройки:
· Открыть браузер. В меню Инструменты (Tools) выбрать пункт Настройки (Options).
· В открывшемся окне перейти в раздел Содержимое (Content).
· Снять флажок Блокировать всплывающие окна (Block pop-up Windows).
· Установить флажок Использовать
JavaScript (Enable
JavaScript ).
· Перейти в раздел Приватность (Privacy) и установить флажок Принимать cookies с сайтов (Assept cookies from sites).
Автоматическая аутентификация
Для браузера Mozilla Firefox имеется возможность сконфигурировать веб-браузер для использования автоматической аутентификации ОС. Для этого необходимо выполнить следующие настройки:
· в адресной строке браузера набрать Aboutconfig
· затем на странице настроек в строке фильтра ввести название параметра.
Данная настройка осуществляется для трех параметров:
a) network.automatic-ntlm-auth.trusted-uris,
b) network.negotiate-auth.delegation-uris,
c) network.negotiate-auth.trusted-uris.
· Далее задать список веб-серверов, через которые будет осуществляться работа с базой «1С-Предприятия».
Источник Категория:
Администрирование