Функция получение содержимого адреса 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/");
СодержимоеАдреса = ПолучитьСодержимоеВебАдреса(" Категория: Нет
Как декодировать (преобразовать) Unicode в 1С При разработке очередного обмена с интернет магазином через API столкнулисть что сайт возвращает ответ в виде:
Код VBS {"ok":"true","description":"\u0421\u0442\u0430\u0442\u0443\u0441 \u0437\u0430\u043a\u0430\u0437\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d"}
из кода ясно что это JSON и используя код ПрочитатьJSON
Код 1C v 8.3 Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(стрВходящая);
ДанныеЛога = ПрочитатьJSON(Чтение);
Чтение.Закрыть();
В переменной ДанныеЛога будет структура в виде
В результате получилась функция с 2-мя вариантами возрата, в зависимости от того как нужно
Код 1C v 8.3 //Функция читает полученный JSON декадируя текст юникод
Функция ДекодироватьUniCodeВJSON(стрВходящая)
// стрВходящая содержит {"ok":"true","description":"\u0421\u0442\u0430\u0442\u0443\u0441 \u0437\u0430\u043a\u0430\u0437\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d"}
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(стрВходящая);
ДанныеЛога = ПрочитатьJSON(Чтение);
Чтение.Закрыть();
// Вариант 1 используя перебор структуры и вывод в текстовую переменную
Текст = "";
Для каждого Элемент Из ДанныеЛога Цикл
//добавим разделитель после предыдущего значения
Текст = Текст + ?(НЕ ПустаяСтрока(Текст), Символы.ПС, "");
//добавим представление ключа и значения:
Текст = Текст + Элемент.Ключ + " = " + Элемент.Значение;
КонецЦикла;
Возврат Текст; //Вернет ok = true description = Статус заказа изменен
// Вариант 2 мспользуя ЗаписьJSON
Запись = Новый ЗаписьJSON;
Запись.УстановитьСтроку(Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет));
ЗаписатьJSON(Запись, ДанныеЛога,);
Возврат Запись.Закрыть(); // Вернет JSON {"ok":"true","description":"Статус заказа изменен"}
КонецФункции
На просторах интернета была найдена еще одна функция:
Код 1C v 8.3 //Параметры: Строка в Юникод (обязательный) Тип: Строка. Исходная строка.
//Возвращаемое значение: Тип: Строка. Строка обработанных символов.
//Описание: Возвращает преобразованную строку из формата Unicod.
//Автор: Александр Кияница (treedo)
Функция ПереобразоватьЮникод(Строка)
ГотововаяСтрока = "" ;
МасУкр = Новый Массив(66) ;
МасУкр[0]="А"; МасУкр[1]="Б"; МасУкр[2]="В"; МасУкр[3]="Г"; МасУкр[4]="Ґ"; МасУкр[5]="Д";
МасУкр[6]="Е"; МасУкр[7]="Є"; МасУкр[8]="Ж"; МасУкр[9]="З"; МасУкр[10]="И"; МасУкр[11]="І";
МасУкр[12]="Ї"; МасУкр[13]="Й"; МасУкр[14]="К"; МасУкр[15]="Л"; МасУкр[16]="М"; МасУкр[17]="Н";
МасУкр[18]="О"; МасУкр[19]="П"; МасУкр[20]="Р"; МасУкр[21]="С"; МасУкр[22]="Т"; МасУкр[23]="У";
МасУкр[24]="Ф"; МасУкр[25]="Х"; МасУкр[26]="Ц"; МасУкр[27]="Ч"; МасУкр[28]="Ш"; МасУкр[29]="Щ";
МасУкр[30]="Ь"; МасУкр[31]="Ю"; МасУкр[32]="Я";
МасУкр[33]="а"; МасУкр[34]="б"; МасУкр[35]="в"; МасУкр[36]="г"; МасУкр[37]="ґ"; МасУкр[38]="д";
МасУкр[39]="е"; МасУкр[40]="є"; МасУкр[41]="ж"; МасУкр[42]="з"; МасУкр[43]="и"; МасУкр[44]="і";
МасУкр[45]="ї"; МасУкр[46]="й"; МасУкр[47]="к"; МасУкр[48]="л"; МасУкр[49]="м"; МасУкр[50]="н";
МасУкр[51]="о"; МасУкр[52]="п"; МасУкр[53]="р"; МасУкр[54]="с"; МасУкр[55]="т"; МасУкр[56]="у";
МасУкр[57]="ф"; МасУкр[58]="х"; МасУкр[59]="ц"; МасУкр[60]="ч"; МасУкр[61]="ш"; МасУкр[62]="щ";
МасУкр[63]="ь"; МасУкр[31]="ю"; МасУкр[65]="я";
МасКод = Новый Массив(66) ;
МасКод[0]="0410"; МасКод[1]="0411"; МасКод[2]="0412"; МасКод[3]="0413"; МасКод[4]="0490"; МасКод[5]="0414";
МасКод[6]="0415"; МасКод[7]="0404"; МасКод[8]="0416"; МасКод[9]="0417"; МасКод[10]="0418"; МасКод[11]="0406";
МасКод[12]="0407"; МасКод[13]="0419"; МасКод[14]="041A"; МасКод[15]="041B"; МасКод[16]="041C"; МасКод[17]="041D";
МасКод[18]="041E"; МасКод[19]="041F"; МасКод[20]="0420"; МасКод[21]="0421"; МасКод[22]="0422"; МасКод[23]="0423";
МасКод[24]="0424"; МасКод[25]="0425"; МасКод[26]="0426"; МасКод[27]="0427"; МасКод[28]="0428"; МасКод[29]="0429";
МасКод[30]="042C"; МасКод[31]="042E"; МасКод[32]="042F";
МасКод[33]="0430"; МасКод[34]="0431"; МасКод[35]="0432"; МасКод[36]="0413"; МасКод[37]="0491"; МасКод[38]="0434";
МасКод[39]="0435"; МасКод[40]="0454"; МасКод[41]="0436"; МасКод[42]="0437"; МасКод[43]="0438"; МасКод[44]="0456";
МасКод[45]="0457"; МасКод[46]="0439"; МасКод[47]="043A"; МасКод[48]="043B"; МасКод[49]="043C"; МасКод[50]="043D";
МасКод[51]="043E"; МасКод[52]="043F"; МасКод[53]="0440"; МасКод[54]="0441"; МасКод[55]="0442"; МасКод[56]="0443";
МасКод[57]="0444"; МасКод[58]="0445"; МасКод[59]="0446"; МасКод[60]="0447"; МасКод[61]="0448"; МасКод[62]="0449";
МасКод[63]="044C"; МасКод[31]="044E"; МасКод[65]="044F";
тмпСтрока = "" ;
Для Счетчик = 1 По СтрДлина(Строка) Цикл
Если Лев(Строка, 1) = "\" Тогда
Если Лев(Строка, 2) = "\u" Тогда
тмпСтрока = Прав(Лев(Строка, 6),4) ;
Если МасКод.Найти(тмпСтрока) = Неопределено Тогда
СтрокаЗамены = Прав(тмпСтрока, 1) ;
тмпСтрока = СтрЗаменить(тмпСтрока,СтрокаЗамены,ТРег(СтрокаЗамены));
Если МасКод.Найти(тмпСтрока) = Неопределено Тогда
Сообщить("Код символа не найден: " + тмпСтрока) ;
Иначе
ГотововаяСтрока = ГотововаяСтрока + МасУкр[МасКод.Найти(тмпСтрока)] ;
КонецЕсли;
Иначе
ГотововаяСтрока = ГотововаяСтрока + МасУкр[МасКод.Найти(тмпСтрока)] ;
КонецЕсли;
Строка = Прав(Строка, (СтрДлина(Строка)-6)) ;
Иначе
Строка = Прав(Строка, (СтрДлина(Строка)-2)) ;
КонецЕсли;
Иначе
ГотововаяСтрока = ГотововаяСтрока + Лев(Строка, 1) ;
Строка = Прав(Строка, (СтрДлина(Строка)-1)) ;
КонецЕсли;
КонецЦикла;
Возврат ГотововаяСтрока ;
КонецФункции
Категория:
WEB-сервисы, WS-ссылки, XDTO-пакеты Функции сохранения таблицы значений в файл и чтения из файла В данном примере хочу привести несколько универсальных функций по выгрузке таблицы значений в файл и дальнейшего чтения из файла:
П орядок программных действий при выгрузке в файл выглядит так:
Подготавливаем таблицу значений (выгружаем из табличной части, выбираем колонки); Конвертируем таблицу значений в табличный документ; Сохраняем табличный документ в MXL. При загрузке таблицы порядок действий такой:
Читаем из файла табличный документ; Конвертируем табличный документ в таблицу значений; Используем эту таблицу значений в своих целях (загружаем в табличную часть). Соответственно файл для хранения данных таблицы имеет расширение *.mxl.
Основные функции для реализации поставленной задачи следующие:
ПреобразоватьТДвТЗ – Функция преобразования табличного документа в таблицу значений.
ПреобразоватьТЗвТД – Функция обратного преобразования таблицы значений в табличный документ.
ПрочитатьТЗИзMXL – Читает из файла данные, определяет колонки таблицы и преобразует эти данные в таблицу значений.
ЗаписатьТЗВMXL – Преобразует таблицу значений в табличный документ и записывает его в файл.
Код 1C v 8.3 // Преобразовать табличный документ в таблицу значений.
//
// Параметры:
// ТабДок - <ТабличныйДокумент> - Исходный табличный документ;
// СтруктураКолонок - <Структура>, <ТаблицаЗначений> - Структура колонок;
// НачалоСтрока - <Число> - Строка начала области;
// НачалоСтолбец - <Число> - Столбец начала области;
// КонецСтрока - <Число> - Строка конца области;
// КонецСтолбец - <Число> - Столбец конца области.
//
// Возвращаемое значение:
// <ТаблицаЗначений> - Полученная таблица значений.
//
Функция ПреобразоватьТДвТЗ(ТабДок, СтруктураКолонок, Знач НачалоСтрока = Неопределено, Знач НачалоСтолбец = Неопределено, Знач КонецСтрока = Неопределено, Знач КонецСтолбец = Неопределено) Экспорт
// Определение габаритов таблицы
Если НачалоСтрока = Неопределено И НачалоСтолбец = Неопределено Тогда
НачалоСтрока = 1;
НачалоСтолбец = 1;
КонецЕсли;
Если НачалоСтрока = Неопределено Тогда
НачалоСтрока = 1;
Пока НЕ ТабДок.Область(НачалоСтрока, НачалоСтолбец).СодержитЗначение
И НачалоСтрока < ТабДок.ВысотаТаблицы
Цикл
НачалоСтрока = НачалоСтрока + 1;
КонецЦикла;
ИначеЕсли НачалоСтолбец = Неопределено Тогда
НачалоСтолбец = 1;
Пока НЕ ТабДок.Область(НачалоСтрока, НачалоСтолбец).СодержитЗначение
И НачалоСтолбец < ТабДок.ШиринаТаблицы
Цикл
НачалоСтолбец = НачалоСтолбец + 1;
КонецЦикла;
КонецЕсли;
КонецСтрока = ?(КонецСтрока = Неопределено, ТабДок.ВысотаТаблицы, КонецСтрока);
КонецСтолбец = ?(КонецСтолбец = Неопределено, ТабДок.ШиринаТаблицы, КонецСтолбец);
// Преобразование
ЭтоТаблица = (ТипЗнч(СтруктураКолонок) = Тип("ТаблицаЗначений"));
ТабЗначений = ПолучитьТаблицуВывода(СтруктураКолонок);
Для ИндексСтроки = НачалоСтрока По КонецСтрока Цикл
СтрокаТЗ = ТабЗначений.Добавить();
ИндексКолонки = НачалоСтолбец;
Для Каждого Колонка Из СтруктураКолонок Цикл
НаименованиеКолонки = ?(ЭтоТаблица, Колонка.Наименование, Колонка.Ключ);
пИндексКолонки = ?(ЭтоТаблица, Колонка.СтолбецОтчёт, ИндексКолонки);
Если ТабДок.Область(ИндексСтроки, пИндексКолонки).СодержитЗначение Тогда
СтрокаТЗ[НаименованиеКолонки] = ТабДок.Область(ИндексСтроки, пИндексКолонки).Значение;
Иначе
СтрокаТЗ[НаименованиеКолонки] = ТабДок.Область(ИндексСтроки, пИндексКолонки).Текст;
КонецЕсли;
ИндексКолонки = ИндексКолонки + 1;
КонецЦикла;
КонецЦикла;
Возврат ТабЗначений;
КонецФункции;
// Преобразовать таблицу значений в табличный документ.
//
// Параметры:
// ТабЗначений - <ТаблицаЗначений> - Исходная таблица значений;
// ТабДок - <ТабличныйДокумент> - Полученный табличный документ. Если параметр не задан,
// то документ создаётся заново и возвращается функцией;
// НачалоСтрока - <Число> - Строка начала области;
// НачалоСтолбец - <Число> - Столбец начала области;
// ВыводитьЗаголовки - <Булево> - Определяет выводить ли имена колонок или нет.
//
// Возвращаемое значение:
// <ТабличныйДокумент> - Полученный табличный документ (возвращает параметр "ТабДок").
//
Функция ПреобразоватьТЗвТД(ТабЗначений, ТабДок = Неопределено, Знач НачалоСтрока = Неопределено, Знач НачалоСтолбец = Неопределено, ВыводитьЗаголовки = Ложь) Экспорт
Если ТабДок = Неопределено Тогда
ТабДок = Новый ТабличныйДокумент;
КонецЕсли;
// Определение габаритов таблицы
НачалоСтрока = ?(НачалоСтрока = Неопределено, 1, НачалоСтрока);
НачалоСтолбец = ?(НачалоСтолбец = Неопределено, 1, НачалоСтолбец);
// Преобразование
ИндексСтроки = НачалоСтрока;
Если ВыводитьЗаголовки Тогда
ИндексКолонки = НачалоСтолбец;
Для Каждого Колонка Из ТабЗначений.Колонки Цикл
ТабДок.Область(ИндексСтроки, ИндексКолонки).Текст = ?(ПустаяСтрока(Колонка.Заголовок), Колонка.Имя, Колонка.Заголовок);
ИндексКолонки = ИндексКолонки + 1;
КонецЦикла;
ИндексСтроки = ИндексСтроки + 1;
КонецЕсли;
Для Каждого Элемент Из ТабЗначений Цикл
ИндексКолонки = НачалоСтолбец;
Для Каждого Колонка Из ТабЗначений.Колонки Цикл
ТабДок.Область(ИндексСтроки, ИндексКолонки).СодержитЗначение = Истина;
ТабДок.Область(ИндексСтроки, ИндексКолонки).ТипЗначения = Новый ОписаниеТипов(Колонка.ТипЗначения);
ТабДок.Область(ИндексСтроки, ИндексКолонки).Значение = Элемент[Колонка.Имя];
ИндексКолонки = ИндексКолонки + 1;
КонецЦикла;
ИндексСтроки = ИндексСтроки + 1;
КонецЦикла;
Возврат ТабДок;
КонецФункции;
// Читает табличный документ из файла MXL и преобразует его в таблицу значений.
//
// Параметры:
// ИмяФайла - <Строка> - Путь к файлу MXL;
// СтруктураКолонок - <Структура>, <ТаблицаЗначений> - Структура колонок. Если этот параметр
// не задан, то структура колонок формируется из самого табличного документа;
// ЕстьЗаголовок - <Булево> - Есть ли первая строка с заголовками или нет.
//
// Возвращаемое значение:
// <ТаблицаЗначений> - Полученная таблица значений.
//
Функция ПрочитатьТЗИзMXL(ИмяФайла, СтруктураКолонок = Неопределено, ЕстьЗаголовок = Истина) Экспорт
ТабДок = Новый ТабличныйДокумент;
ТабДок.Прочитать(ИмяФайла);
Если СтруктураКолонок = Неопределено И ЕстьЗаголовок Тогда
СтруктураКолонок = Новый Структура;
Для ИндексКолонки = 1 По ТабДок.ШиринаТаблицы Цикл
Обл1 = ТабДок.Область(1, ИндексКолонки);
Обл2 = ТабДок.Область(2, ИндексКолонки);
ИмяКолонки = СокрЛП(Обл1.Текст);
ИмяКолонки = ?(Найти(ИмяКолонки, " ") > 0, СтрЗаменить(ТРег(ИмяКолонки), " ", ""), ИмяКолонки);
СтруктураКолонок.Вставить(ИмяКолонки, ?(Обл2.СодержитЗначение, Обл2.ТипЗначения, Новый ОписаниеТипов));
КонецЦикла;
ИначеЕсли СтруктураКолонок = Неопределено И НЕ ЕстьЗаголовок Тогда
СтруктураКолонок = Новый Структура;
Для ИндексКолонки = 1 По ТабДок.ШиринаТаблицы Цикл
Обл2 = ТабДок.Область(1, ИндексКолонки);
ИмяКолонки = "К" + Формат(ИндексКолонки, "ЧДЦ=0; ЧН=0; ЧГ=0");
СтруктураКолонок.Вставить(ИмяКолонки, ?(Обл2.СодержитЗначение, Обл2.ТипЗначения, Новый ОписаниеТипов));
КонецЦикла;
КонецЕсли;
Таблица = ПреобразоватьТДвТЗ(ТабДок, СтруктураКолонок, ?(ЕстьЗаголовок, 2, 1), 1);
Возврат Таблица;
КонецФункции;
// Сохраняет таблицу значений в файле в виде табличного документа.
//
// Параметры:
// ИмяФайла - <Строка> - Путь к файлу MXL;
// ТабЗначений - <ТаблицаЗначений> - Сохраняемая таблица значений;
// ЕстьЗаголовок - <Булево> - Есть ли первая строка с заголовками или нет.
//
Процедура ЗаписатьТЗВMXL(ИмяФайла, ТабЗначений, ЕстьЗаголовок = Истина) Экспорт
ТабДок = ПреобразоватьТЗвТД(ТабЗначений, Неопределено, 1, 1, ЕстьЗаголовок);
ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.MXL);
КонецПроцедуры;
Еще небольшой набор функций для вывода таблицы значений в табличный документ. После формирования табличного документа, - сохраняем его в файл mxl.
Табличный документ можно сохранить a файлы следующих типов:
ANSITXT - Текстовый документ DOCX - документ MS Word HTML HTML3 HTML4 HTML5 MXL MXL7 ODS - Файл Open Office PDF - файл Acrobat Readr TXT - Текстовый документ XLS - файл Excel XLS95 - файл Excel95 XLS97 - файл Excel97 XLSX - файл Excel2010 Код 1C v 8.3 // Получаем таблицу значения из файла.
Функция ЗагрузитьТЗизФайла(ИмяФайла)
Путь = КаталогВременныхФайлов() + ИмяФайла;
Текст = Новый ЧтениеТекста(Путь, КодировкаТекста.UTF8);
стрТЗ = Текст.Прочитать();
Текст.Закрыть();
// получим таблицу значений из строки
ТЗ = ЗначениеИзСтрокиВнутр(стрТЗ);
Возврат ТЗ;
КонецФункции
// Заполнить ячейки в строке значениями
//
Функция ЗаписьТЗ2ТабДок(записьТЗ,НомерСтроки,ТабличныйДокумент)
НомерКолонки = 1;
Символ160 = Символ(160);
// цикл по колонкам таблицы
// РезультатЗапроса.Колонки.Количество() // - количество колонок
Для каждого полеТЗ из ЗаписьТЗ цикл
// значения ячейки в Excel
типПоляТЗ = ТипЗнч(полеТЗ);
если типПоляТЗ = Тип("Число") тогда
полеТЗ=Строка(полеТЗ);
полеТЗ=СтрЗаменить(полеТЗ,Символ160,"");
полеТЗ=СтрЗаменить(полеТЗ,",",".");
иначеесли типПоляТЗ = Тип("Строка") тогда
иначе
полеТЗ = строка(полеТЗ);
КонецЕсли;
имяОбласти = "R" + номерСтроки + "C" + НомерКолонки;
имяОбласти = СтрЗаменить(имяОбласти,Символ(160),"");
Ячейка = ТабличныйДокумент.Область(имяОбласти);
Ячейка.Текст = полеТЗ;
НомерКолонки = НомерКолонки + 1;
КонецЦикла;
КонецФункции
// Заполнить наименованиями колонок таблицу
Функция НаимКолонок2Mxl(ТаблицаЗначений,ТабличныйДокумент)
// массКолонки = новый массив();
номерСтроки=1;
номКолонки=1;
ТабличныйДокумент = новый ТабличныйДокумент;
// цикл по коллекции колонок
Для НомКол=0 по ТаблицаЗначений.Колонки.Количество() - 1 Цикл
//Сообщить(Колонка.Имя + "(" + Колонка.ТипЗначения + ")" );
имяКолонки=ТаблицаЗначений.Колонки[НомКол].Имя;
//ТабличныйДокумент.Область(
имяОбласти = "R" + номерСтроки + "C" + номКолонки;
имяОбласти = СтрЗаменить(имяОбласти,Символ(160),"");
Ячейка = ТабличныйДокумент.Область(имяОбласти);
//значениеЯчейки = СтрЗаменить(имяОбласти,Символ(160),"");
Ячейка.Текст = имяКолонки;
// на основе текущего шрифта сделаем Жирный
ЖирныйШрифт = ?(ЖирныйШрифт = Неопределено,Новый Шрифт(Ячейка.Шрифт,,,Истина),ЖирныйШрифт);
Ячейка.Шрифт = ЖирныйШрифт;
номКолонки = номКолонки + 1;
КонецЦикла;
КонецФункции
// Заполнить построчно табличный документ
Функция Таблица2Mxl(ТаблицаЗначений,ТабличныйДокумент)
//Выборка = РезультатЗапроса.Выбрать();
НомСтр=1; // заполняем данными начиная со 2-й строки
// цикл по строкам таблицы
Для каждого записьТЗ из ТаблицаЗначений Цикл
НомСтр = НомСтр + 1;
// цикл по колонкам таблицы
ЗаписьТЗ2ТабДок(записьТЗ,НомСтр,ТабличныйДокумент);
КонецЦикла;
КонецФункции
// Таблица значений в табличный документ
Функция ТаблицаЗначений2Mxl(ТаблицаЗначений,ФайлMxl)
ТабличныйДокумент = новый ТабличныйДокумент;
// вывести колонки
НаимКолонок2Mxl(ТаблицаЗначений,ТабличныйДокумент);
// вывести содержимое таблицы
Таблица2Mxl(ТаблицаЗначений,ТабличныйДокумент);
ТабличныйДокумент.Записать(ФайлMxl,ТипФайлаТабличногоДокумента.MXL);
ТабличныйДокумент.Показать(ФайлMxl,ФайлMxl);
Возврат 0;
КонецФункции
Функция Тест_ВыгрузитьТЗвMxl();
файл_мТЗИсходныеДанные = "мТЗИсходныеДанные.dat";
ТЗ = ЗагрузитьТЗизФайла(файл_мТЗИсходныеДанные);
ФайлMxl = КаталогВременныхФайлов() + СтрЗаменить(файл_мТЗИсходныеДанные,".dat",".mxl");
ТаблицаЗначений2Mxl(ТЗ,ФайлMxl);
КонецФункции
Тест_ВыгрузитьТЗвMxl();
Пример выгруженной таблицы значений в файл:
Категория:
Работа с Таблицей Значений Скрипт автообновления типовых конфигураций Батник на "языке 1С" для клиент серверных баз, скачивает с сайта ИТС нужное обновление, бекапит базу и обновляет. Подойдет как рабочая заготовка для собственных "обновляторов". В текущем виде все работает. Надо только занести свои переменные.
Код 1C v 8.3 // Путь к обновлениям
Перем мРасположениеОбновлений;
//Параметры для подключения к серверу обновления 1С
Перем мИтсЛогин;
Перем мИтсПароль;
//****
Перем home;
Перем DumpIB;
Перем ФайлСписокОбновленийZIP;
Перем ФайлСписокОбновленийXML;
Перем КодВозврата;
// Проверка существования файла или каталога.
//
// Параметр:
// ПутьКФайлу - Строка - путь к файлу или каталогу, существование которого
// нужно проверить.
//
// Возвращаемое значение:
// Булево - признак существования файла или каталога.
//
Функция ФайлСуществует(Знач ПутьКФайлу) Экспорт
Файл = Новый Файл(ПутьКФайлу);
Возврат Файл.Существует();
КонецФункции
Процедура УстановитьКонстанты()
каталог_tmplts = "D:\tmplts";
мИтсЛогин = "---";
мИтсПароль = "---";
//**Ниже можно не менять.
мРасположениеОбновлений = каталог_tmplts + "\1c";
home = каталог_tmplts + "\1Cupdate";
DumpIB = home + "\DumpIB\";
ФайлСписокОбновленийXML = home + "\v8cscdsc.xml";
ФайлСписокОбновленийZIP = home + "\v8upd11.zip";
Если НЕ ФайлСуществует(home) Тогда
СоздатьКаталог(home);
КонецЕсли;
Если НЕ ФайлСуществует(DumpIB) Тогда
СоздатьКаталог(DumpIB);
КонецЕсли;
Если НЕ ФайлСуществует(мРасположениеОбновлений) Тогда
СоздатьКаталог(мРасположениеОбновлений);
КонецЕсли;
КонецПроцедуры
Функция ВернутьРелизИПлатформу(мИмяСервера,мИмяБазы,мВерсияПлатформы,мБазаЛогин,мБазаПароль)
ПараметрыБазы = Неопределено;
Попытка
//Создаем COM-объект с идентификатором V82.COMConnector
COMОбъект = Новый COMОбъект("V"+мВерсияПлатформы+".COMConnector"); //выйдет V82.COMConnector
Исключение
Сообщить("Не удалось создать COM-объект!");
Возврат ПараметрыБазы;
КонецПопытки;
ПутьКБазе = "srvr="""+ СокрЛП(мИмяСервера) +""";" + "ref=""" + СокрЛП(мИмяБазы) +""";";
СтрокаСоединения = ПутьКБазе + "Usr="""+ СокрЛП(мБазаЛогин) +""";" + "Pwd="""+ СокрЛП(мБазаПароль) + """;";
Попытка
//Устанавливаем внешнее соединение с информационной базой через COM-соединение
V82 = COMОбъект.Connect(СтрокаСоединения);
Исключение
Сообщить(СтрокаСоединения);
Сообщить("Внешнее соединение не установлено!");
Возврат ПараметрыБазы;
КонецПопытки;
ПараметрыБазы = Новый Структура;
ПараметрыБазы.Вставить("ТекущаяВерсия", v82.Метаданные.Версия);
ПараметрыБазы.Вставить("ПутьКПлатформе",v82.КаталогПрограммы() + "1cv8.exe");
Возврат ПараметрыБазы;
КонецФункции
Процедура УстановитьCOMСоединение(мИмяСервера,мИмяБазы,мВерсияПлатформы,мБазаЛогин,мБазаПароль)
Попытка
//Создаем COM-объект с идентификатором V82.COMConnector
COMОбъект = Новый COMОбъект("V"+мВерсияПлатформы+".COMConnector"); //выйдет V82.COMConnector
Исключение
Сообщить("Не удалось создать COM-объект!");
Возврат;
КонецПопытки;
//Инициализируем строку подключения к информационной базе:
// Если ФайловаяИБ Тогда
//Файловый вариант
// ПутьКБазе = "File="""+ СокрЛП(КаталогИБ) +""";";
// Иначе
//Серверных вариант
ПутьКБазе = "srvr="""+ СокрЛП(мИмяСервера) +""";"+
"ref=""" + СокрЛП(мИмяБазы) +""";";
// КонецЕсли;
СтрокаСоединения = ПутьКБазе +
"Usr="""+ СокрЛП(мБазаЛогин) +""";"+
"Pwd="""+ СокрЛП(мБазаПароль) +""";";
Сообщить(СтрокаСоединения);
Попытка
//Устанавливаем внешнее соединение с информационной базой через COM-соединение
V82 = COMОбъект.Connect(СтрокаСоединения);
Исключение
Сообщить(СтрокаСоединения);
Сообщить("Внешнее соединение не установлено!");
Возврат;
КонецПопытки;
КонецПроцедуры
// Загрузка списка обновлений из файла XML
// Достаем из XML файла, наибольший номер возможного обновления
Функция ВыполнитьЗагрузкуСпискаОбновлений(ИмяФайлаЗагрузки,ТекущаяВерсияКонфигурации)
СообщениеОбОшибке = "Ошибка при чтении файла списка обновлений.";
Если НЕ ФайлСуществует(ИмяФайлаЗагрузки) Тогда
Сообщить("Нету XML файла (списка обновлений)");
Возврат Неопределено;
КонецЕсли;
ВерсияДляОбновления = Неопределено;
Попытка
// ТаблицаЗначений = Новый ТаблицаЗначений;
// ТаблицаЗначений.Колонки.Добавить("Конфигурация", Тип("Строка"));
// ТаблицаЗначений.Колонки.Добавить("Поставщик", Тип("Строка"));
// ТаблицаЗначений.Колонки.Добавить("Версия", Тип("Строка"));
// ТаблицаЗначений.Колонки.Добавить("ВерсияДляОбновления", Тип("Строка"));
// ТаблицаЗначений.Колонки.Добавить("ПутьКФайлуОбновления", Тип("Строка"));
// ТаблицаЗначений.Колонки.Добавить("РазмерФайлаОбновления", Тип("Число"));
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ИмяФайлаЗагрузки);
ЧтениеXML.Прочитать(); // <?xml version="1.0" encoding="UTF-8" ?>
// Дата формирования файла.
ЧтениеXML.Прочитать();
ЧтениеXML.Прочитать();
ДатаФормирования = ЧтениеXML.Значение;
ЧтениеXML.Прочитать();
// Читаем начало элемента Update или конец элемента UpdateList.
Пока ЧтениеXML.Прочитать() Цикл
Если ЧтениеXML.Имя = "v8u:updateList" Тогда
Прервать;
Иначе
Конфигурация = ЧтениеXML.ПолучитьАтрибут("configuration");
Пока ЧтениеXML.Прочитать() Цикл
Если ЧтениеXML.Имя = "v8u:update" Тогда
Прервать;
Иначе
Если ЧтениеXML.Имя = "v8u:vendor" Тогда
ЧтениеXML.Прочитать();
Поставщик = ЧтениеXML.Значение;
ИначеЕсли ЧтениеXML.Имя = "v8u:version" Тогда
ЧтениеXML.Прочитать();
Версия = ЧтениеXML.Значение;
ИначеЕсли ЧтениеXML.Имя = "v8u:file" Тогда
ЧтениеXML.Прочитать();
ПутьКФайлуОбновления = ЧтениеXML.Значение;
ИначеЕсли ЧтениеXML.Имя = "v8u:size" Тогда
ЧтениеXML.Прочитать();
РазмерФайлаОбновления = ЧтениеXML.Значение;
ИначеЕсли ЧтениеXML.Имя = "v8u:target" Тогда
ЧтениеXML.Прочитать();
// НоваяСтрока = ТаблицаЗначений.Добавить();
// НоваяСтрока.Конфигурация = Конфигурация;
// НоваяСтрока.Поставщик = Поставщик;
// НоваяСтрока.Версия = Версия;
// НоваяСтрока.ВерсияДляОбновления = ЧтениеXML.Значение;
// НоваяСтрока.ПутьКФайлуОбновления = ПутьКФайлуОбновления;
// НоваяСтрока.РазмерФайлаОбновления = РазмерФайлаОбновления;
Если ЧтениеXML.Значение = ТекущаяВерсияКонфигурации Тогда //279 Новые в конце. на последнюю полученную и будем обновяться
ВерсияДляОбновления = Версия;
КонецЕсли;
КонецЕсли;
ЧтениеXML.Прочитать();
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЦикла;
Исключение
Сообщить(СообщениеОбОшибке);
ЧтениеXML.Закрыть();
Возврат Неопределено;
КонецПопытки;
//Возврат ТаблицаЗначений;
ЧтениеXML.Закрыть();
Возврат ВерсияДляОбновления;
КонецФункции // ВыполнитьЗагрузкуСпискаОбновлений()
//Входящие Сервер - База - ТипКонфигурации - ВерсияРелиза - ВерсияПлатформы-ИТС логин и пароль необязательно
Процедура ПроверитьОбновлениеКонфигурации(мИмяСервера,мИмяБазы,мТипКонфигурации,мВерсияРелиза,мВерсияПлатформы,мБазаЛогин,мБазаПароль)
Сообщить("----------------------------------------------------------------------");
//удалить старые файлы
УдалитьФайлы(ФайлСписокОбновленийXML);
УдалитьФайлы(ФайлСписокОбновленийZIP);
// Качаем v8cscdsc.xml в виде v8upd11.zip
// Создание HTTP-соединения с сервером обновлений
СерверОбновлений = Новый HTTPСоединение("downloads.1c.ru",,мИтсЛогин,мИтсПароль,);
ЗапросКСерверуОбновлений = Новый HTTPЗапрос("/ipp/ITSREPV/V8Update/Configs/"+мТипКонфигурации+"/"+мВерсияРелиза+"/"+мВерсияПлатформы+"/v8upd11.zip");
СерверОбновлений.Получить(ЗапросКСерверуОбновлений,ФайлСписокОбновленийZIP);
// Распаковываем v8cscdsc.xml
ФайлZip = Новый ЧтениеZipФайла(ФайлСписокОбновленийZIP);
ФайлZip.ИзвлечьВсе(home);
ФайлZip.Закрыть();
УдалитьФайлы(ФайлСписокОбновленийZIP);
//+++++ Запрос версии конфигурации базы...
ПараметрыComБазы = ВернутьРелизИПлатформу(мИмяСервера,мИмяБазы,мВерсияПлатформы,мБазаЛогин,мБазаПароль);
Если ПараметрыComБазы = Неопределено Тогда
Возврат;
КонецЕсли;
ВерсияДляОбновления = ВыполнитьЗагрузкуСпискаОбновлений(ФайлСписокОбновленийXML,ПараметрыComБазы.ТекущаяВерсия);
ТребуетсяОбновление = Ложь;
Если ВерсияДляОбновления = Неопределено Тогда
Сообщить(мИмяБазы + " ver: " +ПараметрыComБазы.ТекущаяВерсия+ " ОБНОВЛЕНИЕ НЕ ТРЕБУЕТСЯ");
Возврат;
КонецЕсли;
Сообщить(мИмяБазы + " ver: " +ПараметрыComБазы.ТекущаяВерсия+ " update: " + ВерсияДляОбновления);
//----- Запрос версии конфигурации базы...
КомандаПакетногоАрхивирования = """" + ПараметрыComБазы.ПутьКПлатформе +""""+" CONFIG /S"+мИмяСервера+"\"+мИмяБазы+" /N"""+мБазаЛогин+""" /P"""+мБазаПароль+""" /DumpIB "+DumpIB + мИмяБазы + ".dt /OUT """+home+"\"+мИмяБазы+".log"" -NoTruncate";
//NoTruncate - не очищать логи
//Сообщить(КомандаПакетногоАрхивирования);
ЗапуститьПриложение(КомандаПакетногоАрхивирования,,Истина,КодВозврата);
Если КодВозврата = 0 Тогда
Сообщить("Резервная копия успешно создана.");
Иначе
Сообщить("Ошибка при создании резервной копии");
Возврат;
КонецЕсли;
Версия_Для_Обновления = СтрЗаменить(ВерсияДляОбновления, ".", "_"); //в каталоге шаблонов через подчеркивание храняться
//качаем новую версию, если уже не скачено
Если НЕ ФайлСуществует(мРасположениеОбновлений +"\"+мТипКонфигурации+"\"+Версия_Для_Обновления+"\") Тогда
//качаем новую
// Создание HTTP-соединения с сервером обновлений
Заголовки = Новый Соответствие();
Заголовки.Вставить("User-Agent", "1C+Enterprise/8.2"); //без заголовка сайт не даст скачать.
СерверОбновлений = Новый HTTPСоединение("downloads.v8.1c.ru",,мИтсЛогин,мИтсПароль,);
СтрокаЗапросHTTP = "/tmplts/1c/"+мТипКонфигурации+"/"+ Версия_Для_Обновления +"/1cv8.zip";
Сообщить(СтрокаЗапросHTTP);
ЗапросКСерверуОбновлений = Новый HTTPЗапрос(СтрокаЗапросHTTP,Заголовки);
СерверОбновлений.Получить(ЗапросКСерверуОбновлений, мРасположениеОбновлений+"\1cv8.zip");
ФайлZip = Новый ЧтениеZipФайла(мРасположениеОбновлений+"\1cv8.zip");
ФайлZip.ИзвлечьВсе(мРасположениеОбновлений+"\"+мТипКонфигурации+"\"+Версия_Для_Обновления);
ФайлZip.Закрыть();
УдалитьФайлы(мРасположениеОбновлений+"\1cv8.zip");
КонецЕсли;
//запускаем обновление
КомандаПакетногоОбновления = """" + ПараметрыComБазы.ПутьКПлатформе +""""+" CONFIG /S"+мИмяСервера+"\"+мИмяБазы+" /N"""+мБазаЛогин+""" /P"""+мБазаПароль+""" /UpdateCfg "+мРасположениеОбновлений+"\"+мТипКонфигурации+"\"+Версия_Для_Обновления + "\1cv8.cfu /UpdateDBCfg /OUT """+home+"\"+мИмяБазы+".log"" -NoTruncate";
//Сообщить(КомандаПакетногоОбновления);
ЗапуститьПриложение(КомандаПакетногоОбновления,,Истина,КодВозврата);
Если КодВозврата = 0 Тогда
Сообщить("База Успешно обновлена");
Иначе
Сообщить("ОШИБКА ПРИ ОБНОВЛЕНИИ");
Возврат;
КонецЕсли;
//Еще разок запрос версии
//+++++ Запрос версии конфигурации базы...
ПараметрыComБазы = ВернутьРелизИПлатформу(мИмяСервера,мИмяБазы,мВерсияПлатформы,мБазаЛогин,мБазаПароль);
Если ПараметрыComБазы = Неопределено Тогда
Возврат;
КонецЕсли;
ВерсияДляОбновления = ВыполнитьЗагрузкуСпискаОбновлений(ФайлСписокОбновленийXML,ПараметрыComБазы.ТекущаяВерсия);
ТребуетсяОбновление = Ложь;
Если ВерсияДляОбновления = Неопределено Тогда
Сообщить(мИмяБазы + " ver: " +ПараметрыComБазы.ТекущаяВерсия+ " ОБНОВЛЕНИЕ НЕ ТРЕБУЕТСЯ");
Возврат;
КонецЕсли;
Сообщить(мИмяБазы + " ver: " +ПараметрыComБазы.ТекущаяВерсия+ " update: " + ВерсияДляОбновления);
//----- Запрос версии конфигурации базы...
КонецПроцедуры
УстановитьКонстанты();
//ОСНОВНЫЕ
//ЗУП 2.5
ПроверитьОбновлениеКонфигурации("ka1sql1:1641","up_el","HRM","25","82","Администратор","Администратор");
ПроверитьОбновлениеКонфигурации("ka1sql1:1641","up_spb","HRM","25","82","Администратор","Администратор");
//БП 3.0
ПроверитьОбновлениеКонфигурации("ka1sql1:1741","bp_domx","Accounting","30","83","Администратор","Администратор");
ПроверитьОбновлениеКонфигурации("ka1sql1:1741","bp_el","Accounting","30","83","Администратор","Администратор");
//СВЕТЛАНЫ
//БП 3.0
ПроверитьОбновлениеКонфигурации("ka1sql1:1741","bp_ip","Accounting","30","83","Администратор","Администратор");
ПроверитьОбновлениеКонфигурации("ka1sql1:1741","bp_guild","Accounting","30","83","Администратор","Администратор");
ПроверитьОбновлениеКонфигурации("ka1sql1:1741","bp_lebedeva","Accounting","30","83","Администратор","Администратор");
//ПроверитьОбновлениеКонфигурации("ka1sql1:1741","bp_service","AccountingBase","30","83","Администратор","Администратор");
ПроверитьОбновлениеКонфигурации("ka1sql1:1741","bp_porsche","Accounting","30","83","Администратор","Администратор");
//ЗУП 2.5
ПроверитьОбновлениеКонфигурации("ka1sql1:1641","up_service","HRM","25","82","Администратор","Администратор");
Источник
Категория:
Администрирование Пример создания внешней печатной формы для управляемого приложения Пример создания внешней печатной формы АКТа для Бухгалтерии 3.0
1. В конфигураторе 1C Предприятия 8 создаем внешнюю обработку (Файл->Новый->Внешняя обработка), задаем имя.
2. В модуле обработки пишем код. Постараюсь его максимально комментировать. Главное должно быть:
функция ПечатьВнешнейПечатнойФормы табличного документа - которая выведет данные в макет функция Печать - вызывается из конфигурации! в нее передается массив печатаемых объектов и функция СведенияОВнешнейОбработке(). Она необходима для регистрации печатной формы в справочнике ДополнительныеОтчетыИОбработки, в ней собирается структура с данными для подключения формы. Эта функция, а также ряд сопутствующих ей, практически одинаковы для всех печатных форм, поэтому их можно просто копировать в новую печатную форму ничего не меняя. Код 1C v 8.3 // Функция формирует табличный документ с Внешней печатной формой
//
// Возвращаемое значение:
// Табличный документ - печатная форма акта
Функция ПечатьВнешнейПечатнойФормы(МассивОбъектов, ОбъектыПечати, Подписант) Экспорт
ТабДок = новый ТабличныйДокумент;
Макет = ПолучитьМакет("Макет");
ОбластьШапки = Макет.ПолучитьОбласть("Шапка");
ОбластьДанные = Макет.ПолучитьОбласть("Данные");
ОбластьПодвал = Макет.ПолучитьОбласть("Подвал");
Запрос = новый запрос;
Запрос.УстановитьПараметр("МассивОбъектов",МассивОбъектов);
Запрос.Текст = "ВЫБРАТЬ
| РеализацияТоваровУслугТовары.Номенклатура,
| РеализацияТоваровУслугТовары.Сумма,
| РеализацияТоваровУслугТовары.Количество,
| РеализацияТоваровУслугТовары.Цена,
| РеализацияТоваровУслугТовары.Ссылка КАК Ссылка
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
|ГДЕ
| РеализацияТоваровУслугТовары.Ссылка В(&МассивОбъектов)
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| РеализацияТоваровУслугУслуги.Номенклатура,
| РеализацияТоваровУслугУслуги.Сумма,
| РеализацияТоваровУслугУслуги.Количество,
| РеализацияТоваровУслугУслуги.Цена,
| РеализацияТоваровУслугУслуги.Ссылка
|ИЗ
| Документ.РеализацияТоваровУслуг.Услуги КАК РеализацияТоваровУслугУслуги
|ГДЕ
| РеализацияТоваровУслугУслуги.Ссылка В(&МассивОбъектов)
|
|УПОРЯДОЧИТЬ ПО
| Ссылка";
ОбщаяВыборка = Запрос.Выполнить().Выгрузить();
Для Каждого СсылкаНаОбъект из МассивОбъектов Цикл
ОбластьШапки.Параметры.ТекстЗаголовка = "Акт № "+СсылкаНаОбъект.Номер;
ОбластьШапки.Параметры.Организация = СсылкаНаОбъект.Организация;
ТабДок.Вывести(ОбластьШапки);
Отбор = Новый Структура;
Отбор.Вставить("Ссылка",СсылкаНаОбъект);
Выборка = ОбщаяВыборка.НайтиСтроки(Отбор);
ИтогоСумма = 0;
ИтогоКоличество = 0;
Для Каждого Стр из Выборка Цикл
ЗаполнитьЗначенияСвойств(ОбластьДанные.Параметры,Стр);
ИтогоСумма = ИтогоСумма + Стр.Сумма;
ИтогоКоличество = ИтогоКоличество + Стр.Количество;
ТабДок.Вывести(ОбластьДанные);
КонецЦикла;
ОбластьПодвал.Параметры.ИтогоСумма = ИтогоСумма;
ОбластьПодвал.Параметры.Подписант = Подписант;
ТабДок.Вывести(ОбластьПодвал);
ТабДок.ВывестиГоризонтальныйРазделительСтраниц();
КонецЦикла;
Возврат ТабДок;
КонецФункции
// Экспортная процедура печати, вызываемая из основной программы
//
// Параметры:
// ВХОДЯЩИЕ:
// МассивОбъектовНазначения - Массив - список объектов ссылочного типа для печати документа
// Как правило, содержит один элемент с ссылкой на вызвавший форму объект (документ, справочник)
//
// ИСХОДЯЩИЕ:
// КоллекцияПечатныхФорм - ТаблицаЗначений - таблица сформированных табличных документов.
// Как правило, содержит одну строку с именем текущей печатной формы
// ОбъектыПечати - СписокЗначений - список объектов печати.
// ПараметрыВывода - Структура - Параметры сформированных табличных документов. Содержит поля:
// ДоступнаПечатьПоКомплектно - булево - по умолчанию Ложь
// ПолучательЭлектронногоПисьма
// ОтправительЭлектронногоПисьма
//
Процедура Печать(МассивОбъектовНазначения, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "АКТПечатьВнешняя") Тогда
ТабличныйДокумент = ПечатьВнешнейПечатнойФормы(МассивОбъектовНазначения, ОбъектыПечати, "");
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(КоллекцияПечатныхФорм, "АКТПечатьВнешняя", "АКТ (внешний)", ТабличныйДокумент);
ИначеЕсли УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "АКТПечатьВнешняяИван") Тогда
ТабличныйДокумент = ПечатьВнешнейПечатнойФормы(МассивОбъектовНазначения, ОбъектыПечати, "Иванов А.Ю.");
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(КоллекцияПечатныхФорм, "АКТПечатьВнешняяИван", "АКТ (внешний) Иванов", ТабличныйДокумент);
ИначеЕсли УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "АКТПечатьВнешняяПетр") Тогда
ТабличныйДокумент = ПечатьВнешнейПечатнойФормы(МассивОбъектовНазначения, ОбъектыПечати, "Петров В.С.");
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(КоллекцияПечатныхФорм, "АКТПечатьВнешняяПетр", "АКТ (внешний) Петров", ТабличныйДокумент);
КонецЕсли;
КонецПроцедуры
#Область СведенияОВнешнейОбработке
// Сервисная экспортная функция. Вызывается в основной программе при регистрации обработки в информационной базе
// Возвращает структуру с параметрами регистрации
//
// Возвращаемое значение:
// Структура с полями:
// Вид - строка, вид обработки, один из возможных: "ДополнительнаяОбработка", "ДополнительныйОтчет",
// "ЗаполнениеОбъекта", "Отчет", "ПечатнаяФорма", "СозданиеСвязанныхОбъектов"
// Назначение - Массив строк имен объектов метаданных в формате:
// <ИмяКлассаОбъектаМетаданного>.[ * | <ИмяОбъектаМетаданных>].
// Например, "Документ.СчетЗаказ" или "Справочник.*". Параметр имеет смысл только для назначаемых обработок, для глобальных может не задаваться.
// Наименование - строка - Наименование обработки, которым будет заполнено наименование элемента справочника по умолчанию.
// Информация - строка - Краткая информация или описание по обработке.
// Версия - строка - Версия обработки в формате “<старший номер>.<младший номер>” используется при загрузке обработок в информационную базу.
// БезопасныйРежим - булево - Принимает значение Истина или Ложь, в зависимости от того, требуется ли устанавливать или отключать безопасный режим
// исполнения обработок. Если истина, обработка будет запущена в безопасном режиме.
//
Функция СведенияОВнешнейОбработке() Экспорт
//Инициализируем структуру с параметрами регистрации
ПараметрыРегистрации = Новый Структура;
// Первый параметр, который мы должны указать - это какой вид обработки системе должна зарегистрировать.
// Допустимые типы: ДополнительнаяОбработка, ДополнительныйОтчет, ЗаполнениеОбъекта, Отчет, ПечатнаяФорма, СозданиеСвязанныхОбъектов
ПараметрыРегистрации.Вставить("Вид", "ПечатнаяФорма"); //может быть - ПечатнаяФорма, ЗаполнениеОбъекта, ДополнительныйОтчет, СозданиеСвязанныхОбъектов...
МассивНазначений = Новый Массив;
// Теперь нам необходимо передать в виде массива имен, к чему будет подключена наша ВПФ
// Имейте ввиду, что можно задать имя в таком виде: Документ.* - в этом случае обработка будет подключена ко всем документам в системе,
// которые поддерживают механизм ВПФ
МассивНазначений.Добавить("Документ.РеализацияТоваровУслуг"); //Указываем документ к которому делаем внешнюю печ. форму
ПараметрыРегистрации.Вставить("Назначение", МассивНазначений);
ПараметрыРегистрации.Вставить("Наименование", "АКТ (Внешний)"); //имя под которым обработка будет зарегестрирована в справочнике внешних обработок
ПараметрыРегистрации.Вставить("БезопасныйРежим", ЛОЖЬ); // Зададим право обработке на использование безопасного режима. Более подробно можно узнать в справке к платформе (метод УстановитьБезопасныйРежим)
ПараметрыРегистрации.Вставить("Версия", "1.0"); // эти два параметра играют больше информационную роль,
ПараметрыРегистрации.Вставить("Информация", "Дополнительная печатная форма"); // т.е. это то, что будет видеть пользователь в информации к обработке
// Создадим таблицу команд (подробнее смотрим ниже)
ТаблицаКоманд = ПолучитьТаблицуКоманд();
ДобавитьКоманду(ТаблицаКоманд, "Внешний: АКТ", "АКТПечатьВнешняя", "ВызовСерверногоМетода", Истина, "ПечатьMXL");
ДобавитьКоманду(ТаблицаКоманд, "Внешний: АКТ (Иванов)", "АКТПечатьВнешняяИван", "ВызовСерверногоМетода", Истина, "ПечатьMXL");
ДобавитьКоманду(ТаблицаКоманд, "Внешний: АКТ (Петров)", "АКТПечатьВнешняяПетр", "ВызовСерверногоМетода", Истина, "ПечатьMXL");
ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд);
Возврат ПараметрыРегистрации;
КонецФункции
#КонецОбласти
#Область Вспомогательное
// ВСПОМОГАТЕЛЬНЫЕ ПРОЦЕДУРЫ И ФУНКЦИИ РЕГИСТРАЦИИ ОБРАБОТКИ
// Формирует структуру с параметрами регистрации регистрации обработки в информационной базе
//
// Параметры:
// ОбъектыНазначенияФормы - Массив - Массив строк имен объектов метаданных в формате:
// <ИмяКлассаОбъектаМетаданного>.[ * | <ИмяОбъектаМетаданных>].
// или строка с именем объекта метаданных
// НаименованиеОбработки - строка - Наименование обработки, которым будет заполнено наименование элемента справочника по умолчанию.
// Необязательно, по умолчанию синоним или представление объекта
// Информация - строка - Краткая информация или описание обработки.
// Необязательно, по умолчанию комментарий объекта
// Версия - строка - Версия обработки в формате “<старший номер>.<младший номер>” используется при загрузке обработок в информационную базу.
//
//
// Возвращаемое значение:
// Структура
//
Функция ПолучитьПараметрыРегистрации(ОбъектыНазначенияФормы = Неопределено, НаименованиеОбработки = "", Информация = "", Версия = "1.0")
Если ТипЗнч(ОбъектыНазначенияФормы) = Тип("Строка") Тогда
ОбъектНазначенияФормы = ОбъектыНазначенияФормы;
ОбъектыНазначенияФормы = Новый Массив;
ОбъектыНазначенияФормы.Добавить(ОбъектНазначенияФормы);
КонецЕсли;
ПараметрыРегистрации = Новый Структура;
ПараметрыРегистрации.Вставить("Вид", "ПечатнаяФорма");
ПараметрыРегистрации.Вставить("БезопасныйРежим", Истина);
ПараметрыРегистрации.Вставить("Назначение", ОбъектыНазначенияФормы);
Если Не ЗначениеЗаполнено(НаименованиеОбработки) Тогда
НаименованиеОбработки = ЭтотОбъект.Метаданные().Представление();
КонецЕсли;
ПараметрыРегистрации.Вставить("Наименование", НаименованиеОбработки);
Если Не ЗначениеЗаполнено(Информация) Тогда
Информация = ЭтотОбъект.Метаданные().Комментарий;
КонецЕсли;
ПараметрыРегистрации.Вставить("Информация", Информация);
ПараметрыРегистрации.Вставить("Версия", Версия);
Возврат ПараметрыРегистрации;
КонецФункции
// Формирует таблицу значений с командами печати
//
// Возвращаемое значение:
// ТаблицаЗначений
//
Функция ПолучитьТаблицуКоманд()
Команды = Новый ТаблицаЗначений;
//Представление команды в пользовательском интерфейсе
Команды.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
//Уникальный идентификатор команды или имя макета печати
Команды.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка"));
//Способ вызова команды: "ОткрытиеФормы", "ВызовКлиентскогоМетода", "ВызовСерверногоМетода"
// "ОткрытиеФормы" - применяется только для отчетов и дополнительных отчетов
// "ВызовКлиентскогоМетода" - вызов процедуры Печать(), определённой в модуле формы обработки
// "ВызовСерверногоМетода" - вызов процедуры Печать(), определённой в модуле объекта обработки
Команды.Колонки.Добавить("Использование", Новый ОписаниеТипов("Строка"));
//Показывать оповещение.
//Если Истина, требуется показать оповещение при начале и при завершении работы обработки.
//Имеет смысл только при запуске обработки без открытия формы
Команды.Колонки.Добавить("ПоказыватьОповещение", Новый ОписаниеТипов("Булево"));
//Дополнительный модификатор команды.
//Используется для дополнительных обработок печатных форм на основе табличных макетов.
//Для таких команд должен содержать строку ПечатьMXL
Команды.Колонки.Добавить("Модификатор", Новый ОписаниеТипов("Строка"));
Возврат Команды;
КонецФункции
// Вспомогательная процедура.
//
Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование = "ВызовСерверногоМетода", ПоказыватьОповещение = Ложь, Модификатор = "ПечатьMXL")
НоваяКоманда = ТаблицаКоманд.Добавить();
НоваяКоманда.Представление = Представление;
НоваяКоманда.Идентификатор = Идентификатор;
НоваяКоманда.Использование = Использование;
НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
НоваяКоманда.Модификатор = Модификатор;
КонецПроцедуры
#КонецОбласти
3. Добавляем макет вывода печатной формы:
4. Сохраняем и добавляем в конфигурацию:
Подключается через Администрирование - Печатные формы, отчеты и обработки:
Создаете новую обработку, записывайте и при открытии документа Реализация, нажав на Печать - появляются доступные печатные формы с разными подписывающими.
Скачать Шаблон внешней печатной формы для управляемого приложения
Категория:
Внешние печатные формы, отчеты и обработк… Как получить текст из html? Один мой хороший клиент использует встроенный в 1С почтовый клиент.
До этого все работало хорошо, но недавно из-за установки нового банк-клиента на компьютере обновили Internet Explorer до 11 версии - стала появляться ошибка:
Поле объекта не обнаружено innerText
Пришлось немного доработать типовую функцию получения текста из html:
Код 1C v 8.х Функция ПреобразоватьТекстИзХТМЛФорматаВПростой(ТекстВФорматеХТМЛ) Экспорт
Попытка
НовыйHTMLДокумент = Новый COMОбъект("HtmlFile");
НовыйHTMLДокумент.open("text/html");
НовыйHTMLДокумент.write(ТекстВФорматеХТМЛ);
НовыйHTMLДокумент.close();
Возврат СтрЗаменить(НовыйHTMLДокумент.all.item(0).innerText, Символ(13), "");
Исключение
Построитель = Новый ПостроительDOM;
ЧтениеHTML = Новый ЧтениеHTML;
ЧтениеHTML.УстановитьСтроку(ТекстВФорматеХТМЛ);
ДокументHTML = Построитель.Прочитать(ЧтениеHTML);
Возврат СокрЛП(ДокументHTML.Тело.ТекстовоеСодержимое);
КонецПопытки;
КонецФункции
еще функции пример получения:
Код 1C v 8.х // Процедура изменяет признак формат текста письма (Текст, HТМЛ),
// и при этом конвертирует сам текст.
//
// Параметры:
// ЭУHTML,ЭУТекст - Элементы управления формы, соответственно поле HTML и поле Текст
// Кнопка - выбранная кнопка ее текст "Простой текст" или "HTML" новый вид текста письма
// либо текст кнопки если пометку кнопки менять не требуется, соответственно
// вопрос о потере форматирования задаваться не будет
// Возвращаемое значение:
// Булево, признак выполнения изменения формата
//
Функция удИзменитьФорматТекста(ЭУHTML,ЭУТекст, Кнопка) Экспорт
Если ТипЗнч(Кнопка) = Тип("Строка") Тогда
НовыйВидТекстаПисьма = Кнопка;
ЕстьКнопка = Ложь;
Иначе
Если Кнопка.Пометка Тогда
Возврат Ложь;
КонецЕсли;
НовыйВидТекстаПисьма = Кнопка.Текст;
ЕстьКнопка = Истина;
КонецЕсли;
Если Найти(НовыйВидТекстаПисьма,"Простой текст") > 0 Тогда
ИсходныйТекст = ЭУHTML.ПолучитьТекст();
НачалоBODY = Найти(ИсходныйТекст, "<BODY>");
КонецBODY = Найти(ИсходныйТекст, "</BODY>");
Если ЕстьКнопка и (НачалоBODY > 0 И КонецBODY > 0 И (НачалоBODY + 6) < КонецBODY) Тогда
СтрокаВопроса = "Будет потеряно форматирование текста. Продолжить?";
ОтветНаВопрос = Вопрос(СтрокаВопроса, РежимДиалогаВопрос.ДаНет, , КодВозвратаДиалога.Нет);
Если ОтветНаВопрос <> КодВозвратаДиалога.Да Тогда
Возврат Ложь;
КонецЕсли;
КонецЕсли;
ФорматТекста = ЭУHTML.Документ.all.item(0).innerText;
ЭУТекст.Значение = СтрЗаменить(ФорматТекста, Символ(13), "");
ЭУТекст.Видимость = Истина;
ЭУHTML.Видимость = Ложь;
ЭУHTML.УстановитьТекст("");
Иначе
ФорматХТМЛ = СтрЗаменить(ЭУТекст.Значение, Символы.ПС, "<BR>");
ЭУHTML.УстановитьТекст(ФорматХТМЛ);
ЭУHTML.Видимость = Истина;
ЭУТекст.Видимость = Ложь;
КонецЕсли;
Если ЕстьКнопка Тогда
Кнопка.Пометка = Истина;
КонецЕсли;
Возврат Истина;
КонецФункции // обИзменитьФорматТекста()
Категория:
Работа с Интернет, Почтой (Mail), FTP Функции для работы с ZIP-архивами В работе часто приходится сжимать выгруженные данные в zip архив, отправлять по почте, и потом автоматически разархивировать полученный zip файл:
Код 1C v 8.х // Распаковывает файл архива ZIP в указанный каталог; Извлекает все файлы архива
//
// Параметры:
// ПолноеИмяФайлаАрхива - Строка - имя файла архива, который необходимо распаковать
// ПутьРаспаковкиФайлов - Строка - путь по которому необходимо распаковать файлы
// ПарольАрхива - Строка - пароль для распаковки архива. По умолчанию пустая строка
//
// Возвращаемое значение:
// Результат - Булево - Истина, если успешно, Ложь, если нет.
//
Функция РаспаковатьZipФайл(Знач ПолноеИмяФайлаАрхива, Знач ПутьРаспаковкиФайлов, Знач ПарольАрхива = "") Экспорт
// возвращаемое значение функции
Результат = Истина;
Попытка
Архиватор = Новый ЧтениеZipФайла(ПолноеИмяФайлаАрхива, ПарольАрхива);
Исключение
Архиватор = Неопределено;
СообщитьОбОшибке(КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
Возврат Ложь;
КонецПопытки;
Попытка
Архиватор.ИзвлечьВсе(ПутьРаспаковкиФайлов, РежимВосстановленияПутейФайловZIP.НеВосстанавливать);
Исключение
СтрокаСообщения = НСтр("ru = 'Ошибка при распаковке файлов архива: %1 в каталог: %2'");
СтрокаСообщения = ПодставитьПараметрыВСтроку(СтрокаСообщения, ПолноеИмяФайлаАрхива, ПутьРаспаковкиФайлов);
Сообщить(СтрокаСообщения);
Результат = Ложь;
КонецПопытки;
Архиватор.Закрыть();
Архиватор = Неопределено;
Возврат Результат;
КонецФункции
// Запаковывает указанный каталог в файл архива ZIP
//
// Параметры:
// ПолноеИмяФайлаАрхива - Строка - имя файла архива, в который необходимо запаковать
// МаскаУпаковкиФайлов - Строка - имя файла, помещаемого в архив, или маска.
// Недопустимо использование в именах файлов и папок букв национальных алфавитов, которые при
// преобразовании из символов UNICODE в узкие символы могут быть преобразованы с потерей информации.
// Рекомендуется использовать в именах файлов и папок символы латинского алфавита.
// ПарольАрхива - Строка - пароль для архива. По умолчанию пустая строка
//
// Возвращаемое значение:
// Результат - Булево - Истина, если успешно, Ложь, если нет.
//
Функция ЗапаковатьВZipФайл(Знач ПолноеИмяФайлаАрхива, Знач МаскаУпаковкиФайлов, Знач ПарольАрхива = "") Экспорт
// возвращаемое значение функции
Результат = Истина;
Попытка
Архиватор = Новый ЗаписьZipФайла(ПолноеИмяФайлаАрхива, ПарольАрхива);
Исключение
Архиватор = Неопределено;
СообщитьОбОшибке(КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
Возврат Ложь;
КонецПопытки;
Попытка
Архиватор.Добавить(МаскаУпаковкиФайлов, РежимСохраненияПутейZIP.НеСохранятьПути);
Архиватор.Записать();
Исключение
СтрокаСообщения = НСтр("ru = 'Ошибка при запаковке файлов архива: %1 из каталог: %2'");
СтрокаСообщения = ПодставитьПараметрыВСтроку(СтрокаСообщения, ПолноеИмяФайлаАрхива, МаскаУпаковкиФайлов);
Сообщить(СтрокаСообщения);
Результат = Ложь;
КонецПопытки;
Архиватор = Неопределено;
Возврат Результат;
КонецФункции
В примере используется строковая функция ПодставитьПараметрыВСтроку ():
Код 1C v 8.х // Подставляет параметры в строку. Максимально возможное число параметров - 9.
// Параметры в строке задаются как %<номер параметра>. Нумерация параметров начинается с единицы.
//
// Параметры:
// СтрокаПодстановки – Строка – шаблон строки с параметрами (вхождениями вида "%ИмяПараметра");
// Параметр<n> - Строка - подставляемый параметр.
//
// Возвращаемое значение:
// Строка – текстовая строка с подставленными параметрами.
//
// Пример:
// ПодставитьПараметрыВСтроку(НСтр("ru='%1 пошел в %2'"), "Вася", "Зоопарк") = "Вася пошел в Зоопарк".
//
Функция ПодставитьПараметрыВСтроку(Знач СтрокаПодстановки,
Знач Параметр1, Знач Параметр2 = Неопределено, Знач Параметр3 = Неопределено,
Знач Параметр4 = Неопределено, Знач Параметр5 = Неопределено, Знач Параметр6 = Неопределено,
Знач Параметр7 = Неопределено, Знач Параметр8 = Неопределено, Знач Параметр9 = Неопределено) Экспорт
Если СтрокаПодстановки = Неопределено ИЛИ СтрДлина(СтрокаПодстановки) = 0 Тогда
Возврат "";
КонецЕсли;
Результат = "";
НачПозиция = 1;
Позиция = 1;
Пока Позиция <= СтрДлина(СтрокаПодстановки) Цикл
СимволСтроки = Сред(СтрокаПодстановки, Позиция, 1);
Если СимволСтроки <> "%" Тогда
Позиция = Позиция + 1;
Продолжить;
КонецЕсли;
Результат = Результат + Сред(СтрокаПодстановки, НачПозиция, Позиция - НачПозиция);
Позиция = Позиция + 1;
СимволСтроки = Сред(СтрокаПодстановки, Позиция, 1);
Если СимволСтроки = "%" Тогда
Позиция = Позиция + 1;
НачПозиция = Позиция;
Результат = Результат + "%";
Продолжить;
КонецЕсли;
Попытка
НомерПараметра = Число(СимволСтроки);
Исключение
ВызватьИсключение НСтр("ru='Входная строка СтрокаПодстановки имеет неверный формат: %'" + СимволСтроки);
КонецПопытки;
Если СимволСтроки = "1" Тогда
ЗначениеПараметра = Параметр1;
ИначеЕсли СимволСтроки = "2" Тогда
ЗначениеПараметра = Параметр2;
ИначеЕсли СимволСтроки = "3" Тогда
ЗначениеПараметра = Параметр3;
ИначеЕсли СимволСтроки = "4" Тогда
ЗначениеПараметра = Параметр4;
ИначеЕсли СимволСтроки = "5" Тогда
ЗначениеПараметра = Параметр5;
ИначеЕсли СимволСтроки = "6" Тогда
ЗначениеПараметра = Параметр6;
ИначеЕсли СимволСтроки = "7" Тогда
ЗначениеПараметра = Параметр7;
ИначеЕсли СимволСтроки = "8" Тогда
ЗначениеПараметра = Параметр8;
ИначеЕсли СимволСтроки = "9" Тогда
ЗначениеПараметра = Параметр9;
Иначе
ВызватьИсключение НСтр("ru='Входная строка СтрокаПодстановки имеет неверный формат: %'" + ЗначениеПараметра);
КонецЕсли;
Если ЗначениеПараметра = Неопределено Тогда
ЗначениеПараметра = "";
Иначе
ЗначениеПараметра = Строка(ЗначениеПараметра);
КонецЕсли;
Результат = Результат + ЗначениеПараметра;
Позиция = Позиция + 1;
НачПозиция = Позиция;
КонецЦикла;
Если (НачПозиция <= СтрДлина(СтрокаПодстановки)) Тогда
Результат = Результат + Сред(СтрокаПодстановки, НачПозиция, СтрДлина(СтрокаПодстановки) - НачПозиция + 1);
КонецЕсли;
Возврат Результат;
КонецФункции
Категория:
Работа с Файлами и Каталогами Функции ЕстьРеквизитДокумента и ЕстьРеквизитОбъекта При разработке частенько нужно проверить наличие реквизита в документе или справочнике.
Ниже приведены функции позволяющие проверить наличие заданных реквизитов в объектах конфигурации:
Код 1C v 8.х // Позволяет определить есть ли среди реквизитов шапки Объекта реквизит с переданным именем.
Функция ЕстьРеквизитОбъекта(ИмяРеквизита, Объект) Экспорт
МетаданныеОбъекта = Объект.Метаданные();
Если МетаданныеОбъекта.Реквизиты.Найти(ИмяРеквизита) = Неопределено Тогда
Возврат Ложь;
Иначе
Возврат Истина;
КонецЕсли;
КонецФункции
Для документа:
Код 1C v 8.х // Позволяет определить есть ли среди реквизитов шапки документа
// реквизит с переданным именем.
//
// Параметры:
// ИмяРеквизита - строковое имя искомого реквизита,
// МетаданныеДокумента - объект описания метаданных документа, среди реквизитов которого производится поиск.
//
// Возвращаемое значение:
// Истина - нашли реквизит с таким именем, Ложь - не нашли.
//
Функция ЕстьРеквизитДокумента(ИмяРеквизита, МетаданныеДокумента) Экспорт
Если МетаданныеДокумента.Реквизиты.Найти(ИмяРеквизита) = Неопределено Тогда
Возврат Ложь;
Иначе
Возврат Истина;
КонецЕсли;
КонецФункции
P.S. Посмотрите еще Полезные функции по работе с метаданными
Категория:
Метаданные Как преобразовать дату в формат RFC 822 и обратно? Создавая обмены данными между 1С и сайтами, часто приходится форматировать вывод даты в стандарт RCF-822 или преобразовывать его в понятную для 1С ДатуВремя.
Дата в формате RFC-822 выглядит так: Tue, 12 Aug 2013 14:15:00 +0400
Небольшая справка по стандартам:
Как дату перевести в формат RFC-822?
Код 1C v 8.2 УП ДатаВФорматеRFC822 = Формат(ТекущаяДата(),"Л=en_US; ДФ='ddd, dd MMM yyyy hh:mm:ss +0400 '");
Как из формата RFC-822 получить дату и время для 1С?
Код 1C v 8.2 УП // Функция преобразовывает дату в формате RFC822 к формату 1С - дата и время
// Параметры
// ДатаВФорматеRFC822 – Строка вида "Thu, 10 Aug 2006 14:48:27 +0400"
// Возвращаемое значение:
// <Дата> – Результат преобразования или Неопределено, если преобразование не удалось
Функция ПреобразоватьRFC822КДате0(ДатаВФорматеRFC822) Экспорт
КопияСтроки = ДатаВФорматеRFC822;
СтруктураДаты = Новый Структура("Год,Месяц,День,Час,Минута,Секунда", "","","","","","");
Месяцы = Новый Структура("Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec", "01","02","03","04","05","06","07","08","09","10","11","12");
Для каждого КлючИЗначение Из Месяцы Цикл
Позиция = Найти(КопияСтроки,КлючИЗначение.Ключ);
Если Позиция > 0 Тогда
СтруктураДаты.Месяц = КлючИЗначение.Значение;
Прервать;
КонецЕсли;
КонецЦикла;
Состояние = 0;
Для ш=0 По СтрДлина(КопияСтроки) Цикл
ТекущийСимвол = ПолучитьСимвол(КопияСтроки, ш);
ТекСимволЦифра= ЭтоЦифра(ТекущийСимвол);
Если ТекСимволЦифра И Состояние = 0 Тогда
СтруктураДаты.День = СтруктураДаты.День + ТекущийСимвол;
Состояние = 1; //начало день
ИначеЕсли ТекСимволЦифра И Состояние = 1 Тогда
СтруктураДаты.День = СтруктураДаты.День + ТекущийСимвол;
Состояние = 2; //ждем год
ИначеЕсли ТекСимволЦифра И Состояние = 2 Тогда
СтруктураДаты.Год = СтруктураДаты.Год + ТекущийСимвол;
Состояние = 3; //продолжаем год
ИначеЕсли ТекСимволЦифра И Состояние = 3 Тогда
СтруктураДаты.Год = СтруктураДаты.Год + ТекущийСимвол;
ИначеЕсли ТекущийСимвол = " " И Состояние = 3 Тогда
Состояние = 4; //дальше час
ИначеЕсли ТекСимволЦифра И Состояние = 4 Тогда
СтруктураДаты.Час = СтруктураДаты.Час + ТекущийСимвол;
ИначеЕсли ТекущийСимвол = ":" И Состояние = 4 Тогда
Состояние = 5; //дальше минута
ИначеЕсли ТекСимволЦифра И Состояние = 5 Тогда
СтруктураДаты.Минута = СтруктураДаты.Минута + ТекущийСимвол;
ИначеЕсли ТекущийСимвол = ":" И Состояние = 5 Тогда
Состояние = 6; //дальше секунда
ИначеЕсли ТекСимволЦифра И Состояние = 6 Тогда
СтруктураДаты.Секунда = СтруктураДаты.Секунда + ТекущийСимвол;
ИначеЕсли ТекущийСимвол = " " И Состояние = 6 Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Попытка
Результат = Дата(СтруктураДаты.Год+СтруктураДаты.Месяц+СтруктураДаты.День
+СтруктураДаты.Час+СтруктураДаты.Минута+СтруктураДаты.Секунда);
Исключение
Результат = Неопределено;
КонецПопытки;
Возврат Результат;
КонецФункции // ПреобразоватьRFC822КДате()
В процессе изучения вопроса, встретил еще несколько вариантов:
Код 1C v 8.х // Автор: Mavka
// По типу: Wed, 30 Mar 2011 17:50:11 +0200
// Я написала код, но без учета часовых поясов(
Функция ВДатуRFC822(Дата1С, ПоправкаGMT) Экспорт
Перем ТемпДата;
Перем ТемпГод;
Перем ТемпМесяц;
Перем ТемпДень;
Перем ДатаRFC822;
Перем ТемпЧас;
Перем ТемпМинута;
Перем ТемпСекунда;
Перем НомерДняНедели;
Перем ТемпДеньНедели;
Перем МесяцИмя;
ТемпДата = Дата1С - 60 * 60 * ПоправкаGMT;
ТемпГод = СтрЗаменить(Формат(Год(ТемпДата),"ND=4; NLZ="),Символы.НПП,"");
ТемпМесяц = Месяц(ТемпДата);
Если ТемпМесяц = 1 Тогда
МесяцИмя = "Jan";
ИначеЕсли ТемпМесяц = 2 Тогда
МесяцИмя = "Feb";
ИначеЕсли ТемпМесяц = 3 ТОгда
МесяцИмя = "Mar";
ИначеЕсли ТемпМесяц = 4 Тогда
МесяцИмя = "Apr";
ИначеЕсли ТемпМесяц = 5 Тогда
МесяцИмя = "May";
ИначеЕсли ТемпМесяц = 6 Тогда
МесяцИмя = "Jun";
ИначеЕсли ТемпМесяц = 7 Тогда
МесяцИмя = "Jul";
ИначеЕсли ТемпМесяц = 8 ТОгда
МесяцИмя = "Aug";
ИначеЕсли ТемпМесяц = 9 Тогда
МесяцИмя = "Sep";
ИначеЕсли ТемпМесяц = 10 Тогда
МесяцИмя = "Oct";
ИначеЕсли ТемпМесяц = 11 Тогда
МесяцИмя = "Nov";
Иначе
МесяцИмя = "Dec";
КонецЕсли;
ТемпДень = Формат(День(ТемпДата),"ND=2; NLZ=");
НомерДняНедели = ДеньНедели(ТемпДата);
Если НомерДняНедели = 1 Тогда
ТемпДеньНедели = "Mon";
ИначеЕсли НомерДняНедели = 2 Тогда
ТемпДеньНедели = "Tue";
ИначеЕсли НомерДняНедели = 3 ТОгда
ТемпДеньНедели = "Wed";
ИначеЕсли НомерДняНедели = 4 Тогда
ТемпДеньНедели = "Thu";
ИначеЕсли НомерДняНедели = 5 Тогда
ТемпДеньНедели = "Fri";
ИначеЕсли НомерДняНедели = 6 Тогда
ТемпДеньНедели = "Sat";
Иначе
ТемпДеньНедели = "Sun";
КонецЕсли;
ТемпЧас = ?(Час(ТемпДата) = 0, "00", Формат(Час(ТемпДата),"ND=2; NLZ="));
ТемпМинута = ?(Минута(ТемпДата) = 0, "00", Формат(Минута(ТемпДата),"ND=2; NLZ="));
ТемпСекунда = ?(Секунда(ТемпДата) = 0, "00", Формат(Секунда(ТемпДата),"ND=2; NLZ="));
ДатаRFC822 = ТемпДеньНедели+ ", " + ТемпДень + " " + МесяцИмя + " " + ТемпГод + " " + ТемпЧас + ":" + ТемпМинута + ":" + ТемпСекунда + " +0200";
Возврат ДатаRFC822;
КонецФункции
Категория:
Работа с Датами (Временем) Как мы писали парсер сайта с ценами для 1С Недавно, мой постоянный клиент решил проводить маркетинговые исследования по изменению цен на товары у конкурентов... и эти данные захотел использовать в 1С в связке с его прайс-листом + куча отчетов с графиками и процентным отклонением от цен основного конкурента
В результате этого, была написана обработка собирающая данные со страниц разных сайтов. Из целей конфиденциальности - сайты раскрывать не буду...
Вид обработки загрузки данных с сайта в 1С
Ниже код загрузки данных со страницы сайта , смысл такой :
в функция передается адрес страницы сайта полученный текст страницы обрабатывается, удаляются теги из полученного текста формируется ТЗ с данными По названию ищется поставщик из вспомогательного справочника Справочники.Pr_Поставщики.НайтиПоНаименованию(, если нет - создается на выходе ТЗ с данными Код 1C v 8.х Функция ПолучитьТаблицуДанных(Строка)
тзДанных = Новый ТаблицаЗначений;
Сервер = "site.ru";
Соединение = Новый HTTPСоединение(Сервер);
Заголовки = Новый Соответствие;
Заголовки.Вставить("host", Сервер);
ТекАдрес = СтрЗаменить(Строка.Наименование.УРЛСтраницы,"http://","");
ТекАдрес = СтрЗаменить(ТекАдрес,Сервер,"");
Запрос = Новый HTTPЗапрос(ТекАдрес, Заголовки);
Ответ =Соединение.Получить(Запрос);
Если Ответ.КодСостояния = 200 Тогда // Данные получены, обрабатываем их
Содержимое= Ответ.ПолучитьТелоКакСтроку();
//Выведем тест полученной страницы
НачалоБлока = "<table id=" + """" + "table-price" + """" + " cellspacing=" + """" + "0" + """" + " border=" + """" + "1" + """" + " bordercolor=" + """" + "#dedede" + """" + " class=" + """" + "tablesorter" + """" + " >";
//НачалоБлока = "<div class=" + """" + "w100fl" + """" + " id=" + """" + "kurs" + """" + ">";
КонецБлока = "</table>";
ТекстБлока = Сред(Содержимое, Найти(Содержимое, НачалоБлока) + СтрДлина(НачалоБлока), Найти(Содержимое, КонецБлока) - Найти(Содержимое, НачалоБлока) - СтрДлина(НачалоБлока));
//Обработаем тест
обрТекст = СтрЗаменить(ТекстБлока,"<tr>","");
обрТекст = СтрЗаменить(обрТекст,"</tr>",Символы.ПС);
обрТекст = СтрЗаменить(обрТекст," >", ">");
обрТекст = СтрЗаменить(обрТекст,"</th> <th>", " | ");
обрТекст = СтрЗаменить(обрТекст,"</td> <td>", " | ");
обрТекст = СтрЗаменить(обрТекст,"</th> <th class=" + """" + "sortable_header" + """" + ">", " | ");
обрТекст = СтрЗаменить(обрТекст,"</th> <th >", " | ");
обрТекст = СтрЗаменить(обрТекст,"</th><th>", " | ");
обрТекст = СтрЗаменить(обрТекст,"</td><td>", " | ");
обрТекст = СтрЗаменить(обрТекст," >", ">");
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.IgnoreCase = Ложь;
RegExp.Global = Истина;
RegExp.MultiLine = Истина;
RegExp.Pattern = "<[^>]*>"; //Ищем теги HTML
обрТекст=RegExp.Replace(обрТекст, "");
//Сообщить(обрТекст);
Если СокрЛП(обрТекст) = "Ни одной позиции не найдено." Тогда
Сообщить(Строка(Строка.Наименование)+ " = Ни одной позиции не найдено! Строка " + Строка.Наименование);
Возврат тзДанных;
КонецЕсли;
Если Найти(обрТекст, "Страница не найдена") > 0 Тогда
Сообщить(Строка(ТекАдрес)+" = Страница не найдена, строка " + Строка.Наименование);
Возврат тзДанных;
КонецЕсли;
//Преобразуем полученный текст в таблицу
Для н=1 По СтрЧислоСтрок(обрТекст)Цикл
СтрТекста=СтрПолучитьСтроку(обрТекст,н);
Если Найти(СтрТекста, "Длина Цена") > 0 Тогда
СтрТекста = СтрЗаменить(СтрТекста, "Длина Цена", "Длина | Цена");
КонецЕсли;
Если Найти(СтрТекста, "Марка стали Цена") > 0 Тогда
СтрТекста = СтрЗаменить(СтрТекста, "Марка стали Цена", "Марка стали | Цена");
КонецЕсли;
Если Найти(СтрТекста, ", Поставщик") > 0 Тогда
СтрТекста = СтрЗаменить(СтрТекста, ", Поставщик", " | Поставщик");
КонецЕсли;
//Выводим текст страницы построчно
мсДанных = ПолучитьМассивИзСтрокиСРазделителем(СтрТекста, "|", Истина);
Если н=1 Тогда
Для Каждого ткЗнач из мсДанных Цикл
СтрЗапрещСимволов = " .,<>""\/-";
ИмяКолонки = ткЗнач;
Для сч33 = 1 по СтрДлина(СтрЗапрещСимволов) Цикл
ЗапрещСимв = Сред(СтрЗапрещСимволов, сч33, 1);
ИмяКолонки = СтрЗаменить(ИмяКолонки, ЗапрещСимв, "_");
КонецЦикла;
// добавим нужное количество колонок- если перед колонкой Поставщик не хватает
// бывает, что в шапке определяется меньше колонок, чем реально в таблице
Если НРег(ИмяКолонки) = "поставщик" Тогда
Для Сч_дк = (Строка.Наименование.Родитель.Поставшик - 2) по тзДанных.Колонки.Количество() Цикл
тзДанных.Колонки.Добавить("Колонка_" + (тзДанных.Колонки.Количество() + 1));
КонецЦикла;
КонецЕсли;
тзДанных.Колонки.Добавить(ИмяКолонки);
КонецЦикла;
тзДанных.Колонки.Добавить("ном", , , 7);
Иначе
НовСтр = тзДанных.Добавить(); нмас=0;
Для Каждого ткЗнач из мсДанных Цикл
НовСтр[нмас] = ткЗнач;
нмас=нмас+1;
КонецЦикла;
НовСтр.ном = н;
КонецЕсли;
//Сообщить(стр);
КонецЦикла;
тзДанных.Колонки.Добавить("ЕстьСоответствие", Новый ОписаниеТипов("Булево"));
тзДанных.Колонки.Добавить("СпрPr_Поставщики", Новый ОписаниеТипов("СправочникСсылка.Pr_Поставщики"));
Для каждого стр из тзДанных Цикл
текПоставщик = Справочники.Pr_Поставщики.НайтиПоНаименованию(стр[Строка.Наименование.родитель.Поставшик-1]);
Если текПоставщик = Справочники.Pr_Поставщики.ПустаяСсылка() Тогда
НовЭлем = Справочники.Pr_Поставщики.СоздатьЭлемент();
НовЭлем.Наименование = СокрЛП(стр[Строка.Наименование.родитель.Поставшик-1]);
НовЭлем.Записать();
текПоставщик = НовЭлем.Ссылка;
КонецЕсли;
стр.СпрPr_Поставщики = текПоставщик;
КонецЦикла;
Иначе
тзДанных.Колонки.Добавить("ЕстьСоответствие", Новый ОписаниеТипов("Булево"));
тзДанных.Колонки.Добавить("СпрPr_Поставщики", Новый ОписаниеТипов("СправочникСсылка.Pr_Поставщики"));
Сообщить("Ошибка получения данных для строки " + Строка.Наименование);
КонецЕсли;
Возврат тзДанных;
КонецФункции
В коде используется вспомогательная функция ПолучитьМассивИзСтрокиСРазделителем
Код 1C v 8.2 УП // Функция разбивает строку разделителем.
//
// Параметры:
// пСтрока - Строка - которую разбиваем;
// *пРазделитель - Строка, "." - символ-разделитель;
// *ОбрезатьНепечатныеСимволы - Булево, *Ложь.
//
// Возвращаемое значение:
// Массив - фрагментов.
//
Функция ПолучитьМассивИзСтрокиСРазделителем(Знач Стр, Разделитель = ".", ОбрезатьНепечатныеСимволы = Ложь) Экспорт
МассивСтрок = Новый Массив;
Если Разделитель = " " Тогда
Стр = СокрЛП(Стр);
Пока 1=1 Цикл
Поз = Найти(Стр,Разделитель);
Если Поз=0 Тогда
МассивСтрок.Добавить(Стр);
Возврат МассивСтрок;
КонецЕсли;
МассивСтрок.Добавить(Лев(Стр,Поз-1));
Стр = СокрЛ(Сред(Стр,Поз));
КонецЦикла;
Иначе
ДлинаРазделителя = СтрДлина(Разделитель);
Пока 1=1 Цикл
Поз = Найти(Стр,Разделитель);
Если Поз=0 Тогда
Фрагмент = Стр;
Если ОбрезатьНепечатныеСимволы Тогда
Фрагмент = СокрЛП(Фрагмент);
КонецЕсли;
МассивСтрок.Добавить(Фрагмент);
Возврат МассивСтрок;
КонецЕсли;
Фрагмент = Лев(Стр,Поз-1);
Если ОбрезатьНепечатныеСимволы Тогда
Фрагмент = СокрЛП(Фрагмент);
КонецЕсли;
МассивСтрок.Добавить(Фрагмент);
Стр = Сред(Стр,Поз+ДлинаРазделителя);
КонецЦикла;
КонецЕсли;
Возврат МассивСтрок;
КонецФункции // ПолучитьМассивИзСтрокиСРазделителем()
Конечно, перед тем как мы начали это делать - прошерстили интернет и нашли несколько решений , вот они:
Код 1C v 8.х Соединение = ПолучитьCOMОбъект("","Microsoft.XMLHTTP");
ИмяВременногоФайла=ПолучитьИмяВременногоФайла("htm");
Соединение.open("GET", "http://mamba.ru/my", 0);
Соединение.send();
//status: //404 - Not Found //200 - Ok
ТаймАут = 200;
Начало=ТекущаяДата();
Пока Соединение.readyState <> 4 И (ТаймАут=0 ИЛИ ТекущаяДата()-Начало<ТаймАут) Цикл
бфДиалоги.ксОбработкаПрерыванияПользователя();
КонецЦикла;
//Сохраняем во временный файл
обСохранитьДвоичныйБуферВФайл(Соединение.responseBody, ИмяВременногоФайла);
Соединение.open("POST", "http://mamba.ru/my");
Соединение.send("login=xxx&password=&&&");
Функция обСохранитьДвоичныйБуферВФайл(Буфер, ИмяФайла) Экспорт
Поток = Новый COMОбъект("ADODB.Stream");
Поток.Type = 1; //Бинарный
Поток.Mode = 3;
Поток.Open();
Поток.Write(Буфер);
Поток.SaveToFile(ИмяФайла);
Поток.Close();
КонецФункции
Код 1C v 8.х НТТР = ПолучитьCOMОбъект("","Microsoft.XMLHTTP");
ИмяФайлаОтвета = КаталогВременныхФайлов() + "filename.tmp";
НТТР.open("GET", "www.google.com",0,,);
НТТР.send();
StreamTypeEnum = Новый Структура("adTypeBinary, adTypeText", 1, 2);
ConnectModeEnum = Новый Структура(
"adModeRead, adModeReadWrite, adModeRecursive, adModeShareDenyNone,
|adModeShareDenyRead, adModeShareDenyWrite, adModeShareExclusive,
|adModeUnknown, adModeWrite", 1, 3, 4194304, 16, 4, 8, 12, 0, 2);
SaveOptionsEnum = Новый Структура("adSaveCreateNotExist, adSaveCreateOverWrite", 1, 2);
StreamOut = Новый COMОбъект("ADODB.Stream");
StreamOut.Type = StreamTypeEnum.adTypeBinary;
StreamOut.Mode = ConnectModeEnum.adModeReadWrite; //Нужны и чтение и запись
StreamOut.Open(); //Открыли на чтение и запись
StreamOut.Write(НТТР.responseBody);
StreamOut.SaveToFile(ИмяФайлаОтвета, SaveOptionsEnum.adSaveCreateOverWrite); //"2" - перезапись файла
StreamOut.Close();
И даже не этом сайте есть статья : Парсер сайта связного на 1С
Нужен парсер сайта в 1С!? - Обращайтесь, контакты в
профиле Категория:
Работа с Интернет, Почтой (Mail), FTP Как преобразовать таблицу значений в массив для передачи с сервера на клиента Данная процедура Преобразует таблицу значений в массив.
Может использоваться для передачи на клиента данных, полученных на сервере в виде таблицы значений в том случае, если таблица значений содержит только такие значения, которые могут быть переданы на клиента
Полученный массив содержит структуры, каждая из которых повторяет структуру колонок таблицы значений.
Не рекомендуется использовать для преобразования таблиц значений с большим количеством строк.
Код 1C v 8.3
//
// Параметры: ТаблицаЗначений
// Возвращаемое значение: Массив
//
Функция ТаблицаЗначенийВМассив(ТаблицаЗначений) Экспорт
Массив = Новый Массив();
СтруктураСтрокой = "";
НужнаЗапятая = Ложь;
Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл
Если НужнаЗапятая Тогда
СтруктураСтрокой = СтруктураСтрокой + ",";
КонецЕсли;
СтруктураСтрокой = СтруктураСтрокой + Колонка.Имя;
НужнаЗапятая = Истина;
КонецЦикла;
Для Каждого Строка Из ТаблицаЗначений Цикл
НоваяСтрока = Новый Структура(СтруктураСтрокой);
ЗаполнитьЗначенияСвойств(НоваяСтрока, Строка);
Массив.Добавить(НоваяСтрока);
КонецЦикла;
Возврат Массив;
КонецФункции
Подробнее мы писали об этом в статье: Как передать таблицу значений с сервера на клиент?
вот еще пример:
Код 1C v 8.2 УП &НаКлиенте
Процедура ПолучитьТаблицуНаСервер(Команда)
ТЗ = ПолучитьТЗНаСервере();
КонецПроцедуры
// Функция получает данные на сервере
&НаСервере
Функция ПолучитьТЗНаСервере()
// Для примера сформируем ТЗ с данными
ТЗ = ЗаполнитьТЗДанными();
МассивЗнч = Новый Массив;
Для Каждого СтрТЗ ИЗ ТЗ Цикл
СтруктураВМассив = Новый Структура;
СтруктураВМассив.Вставить("Поле1" , СтрТЗ.Поле1);
СтруктураВМассив.Вставить("Поле2" , СтрТЗ.Поле2);
СтруктураВМассив.Вставить("Поле3" , СтрТЗ.Поле3);
СтруктураВМассив.Вставить("Поле4" , СтрТЗ.Поле4);
СтруктураВМассив.Вставить("Поле5" , СтрТЗ.Поле5);
МассивЗнч.Добавить(СтруктураВМассив);
КонецЦикла;
Возврат МассивЗнч;
КонецФункции
//Функция заполняет ТЗ
&НаСервере
Функция ЗаполнитьТЗДанными()
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Поле1");
ТЗ.Колонки.Добавить("Поле2");
ТЗ.Колонки.Добавить("Поле3");
ТЗ.Колонки.Добавить("Поле4");
ТЗ.Колонки.Добавить("Поле5");
Для i = 1 По 3 Цикл
НоваяСтр = ТЗ.Добавить();
НоваяСтр.Поле1 = i;
НоваяСтр.Поле2 = 2*i;
НоваяСтр.Поле3 = 3*i;
НоваяСтр.Поле4 = 4*i;
НоваяСтр.Поле5 = 5*i;
КонецЦикла;
Возврат ТЗ;
КонецФункции
Категория:
Управляемое приложение, Тонкий клиент Функция проверяет наличие в строке только цифр Необходимо быть уверенными, что в строке только цифры - используйте функцию
Код 1C v 8.х // Функция проверяет наличие в строке только цифр
//
// Параметры
// СтрокаПроверки - Строка для проверки только цифр
//
// Возвращаемое значение:
// Булево
//
Функция ЕстьНеЦифры(Знач СтрокаПроверки) Экспорт
Если ТипЗнч(СтрокаПроверки) <> Тип("Строка") Тогда
Возврат Истина;
КонецЕсли;
СтрокаПроверки = СокрЛП(СтрокаПроверки);
Длина = СтрДлина(СтрокаПроверки);
Для а = 1 По Длина Цикл
Если Найти("0123456789", Сред(СтрокаПроверки, а, 1)) = 0 Тогда
Возврат Истина;
КонецЕсли;
КонецЦикла;
Возврат Ложь;
КонецФункции
Категория:
Работа с Числами Обход метаданных (полезные функции) При написании небольших автоматизированных тестов часто надо обойти всю конфигурацию и проверить, например, для всех форм какое-нибудь свойство. Это всё легко делается через свойство глобального контекста "Метаданные", но чтоб дорбаться до обхода реквизитов надо написать кучу вложенных циклов. При этом код становится слабочитаемым и слабомодифицируемым.
Ниже приведен небольшой модуль, который решает задачу легко и удобно. Создана специальная функция РазвернутьСтрокуОбходаМетаданных, которая может по строке типа "Метаданные.Справочники.*.Реквизиты.*" построить массив строк с перечислением всех реквизитов всех справочников. При помощи этой и нескольких других функций в экспортных функциях модуля реализованы вполне прикладные задачи - получение всех реквизитов, всех макетов, всех форм конфигурации и построение таблицы всех составных типов.
Код 1C v 8.х // Автор: Alexander Speshilov
// Рекрсивная функция, которая разворачивает строку вида "Метаданные.Справочники.*[Имя].Реквизиты.*.Тип"
// в массив строк, заменяя "*" или другой символ, задаваемый параметрами обходом всех элементов
// коллекции. Допускает выполнение функций встроенного языка (не стоит отдавать ввод параметров
// пользователям). При этом выражение, используемое для получения по умолчанию может быть задано в
// квадратных скобках или параметром функции.
//
// Параметры
// СтрокаОбхода - Строка - Разворачиваемая строка
// ЗаменяемоеЗначение - Строка - заменяемое значение
// ПредставлениеПоУмолчанию - Строка - выражение для получения представления
//
// Возвращаемое значение:
// Массив строк
//
Функция РазвернутьСтрокуОбходаМетаданных(СтрокаОбхода, ЗаменяемоеЗначение = "*", ПредставлениеПоУмолчанию = "")
Рез = Новый Массив;
ЧастиСтрокиОбхода = РазобратьСтрокуОбхода(СтрокаОбхода, ЗаменяемоеЗначение, ПредставлениеПоУмолчанию);
Если ЧастиСтрокиОбхода = Неопределено тогда
Рез.Добавить(СтрокаОбхода); //фактически это ограничение рекурсии.
Иначе
ОбъектКоллекции = Вычислить(ЧастиСтрокиОбхода.СтрокаКоллекции);
РазвернутаяКоллекция = РазвернутьКоллекциюВПредставления(ОбъектКоллекции, ЧастиСтрокиОбхода.СтрокаПредставление);
Для каждого ЭлементРазвернутойКоллекции Из РазвернутаяКоллекция Цикл
// рекурсивный вызов
ТекущаяСтрокаОбхода = ЧастиСтрокиОбхода.СтрокаНачало + ЭлементРазвернутойКоллекции + ЧастиСтрокиОбхода.СтрокаКонец;
МассивЭлемента = РазвернутьСтрокуОбходаМетаданных(ТекущаяСтрокаОбхода, ЗаменяемоеЗначение, ПредставлениеПоУмолчанию);
Для каждого ПримитивныйЭлементОбхода Из МассивЭлемента Цикл
Рез.Добавить(ПримитивныйЭлементОбхода);
КонецЦикла;
КонецЦикла;
КонецЕсли;
Возврат Рез;
КонецФункции // РазвернутьСтрокуОбходаМетаданных()
// Разбирает строку обхода на удобные для работы поля
//
// Параметры
// СтрокаОбхода - Строка - Разворачиваемая строка
// ЗаменяемоеЗначение - Строка - заменяемое значение
// ПредставлениеПоУмолчанию - Строка - выражение для получения представления
//
// Возвращаемое значение:
// Структура с полями ПозицияЗамены, СтрокаНачало, СтрокаКоллекции, СтрокаПредставление, СтрокаКонец
// или Неопределено (если строка не содержит ЗаменяемоеЗначение)
//
Функция РазобратьСтрокуОбхода(СтрокаОбхода, ЗаменяемоеЗначение, ПредставлениеПоУмолчанию)
Если ПустаяСтрока(ЗаменяемоеЗначение) Тогда
ВызватьИсключение "Некорректное выражение заменяемого значения";
КонецЕсли;
ПозицияЗамены = Найти(СтрокаОбхода, ЗаменяемоеЗначение);
// Если не найдена строка - возвращаем неопределено, как индикатор
Если ПозицияЗамены = 0 Тогда
Возврат Неопределено;
КонецЕсли;
СтрокаНачало = Лев(СтрокаОбхода,ПозицияЗамены - 1);
//Получение строки для выражения-коллекции
СтрокаКоллекции = СтрокаНачало;
Если Прав(СтрокаКоллекции, 1) = "." Тогда
СтрокаКоллекции = Лев(СтрокаКоллекции,СтрДлина(СтрокаКоллекции) - 1);
КонецЕсли;
ПозицияОкончанияЗамены = ПозицияЗамены + СтрДлина(ЗаменяемоеЗначение);
ОстатокВыражения = Сред(СтрокаОбхода, ПозицияОкончанияЗамены);
//Обработка явного задания представления
ОткрывающаяСкобка = "[";
ЗакрывающаяСкобка = "]";
Если Найти(ОстатокВыражения, ОткрывающаяСкобка) = 1 Тогда
ОстатокВыражения = Сред(ОстатокВыражения, СтрДлина(ОткрывающаяСкобка) + 1);
ПозицияЗакрывающейСкобки = Найти(ОстатокВыражения, ЗакрывающаяСкобка);
Если ПозицияЗакрывающейСкобки = 0 Тогда
ВызватьИсключение "Синтаксическая ошибка разбора выражения";
КонецЕсли;
СтрокаПредставление = Лев(ОстатокВыражения, ПозицияЗакрывающейСкобки - 1);
ОстатокВыражения = Сред(ОстатокВыражения, ПозицияЗакрывающейСкобки + СтрДлина(ЗакрывающаяСкобка));
Иначе
СтрокаПредставление = ПредставлениеПоУмолчанию;
КонецЕсли;
СтрокаКонец = ОстатокВыражения;
Рез = Новый Структура("ПозицияЗамены, СтрокаНачало, СтрокаКоллекции, СтрокаПредставление, СтрокаКонец",
ПозицияЗамены, СтрокаНачало, СтрокаКоллекции, СтрокаПредставление, СтрокаКонец);
Возврат Рез;
КонецФункции // РазобратьСтрокуОбхода()
// Разворачивает объект коллекции в массив представления элементов
//
// Параметры
// Коллекция - Произвольный - Коллекция, которую можно обойти через "Для каждого"
// ПредставлениеЭлемента - Строка - необяз., свойство элементов коллекции, которое
// используется для получения представления.
//
// Возвращаемое значение:
// Массив - Массив представлений коллекции
//
Функция РазвернутьКоллекциюВПредставления(Коллекция, Знач ПредставлениеЭлемента = "")
//Проверка и подгонка параметров
Если не ПустаяСтрока(ПредставлениеЭлемента) Тогда
Если Найти(ПредставлениеЭлемента, ";")>0 Тогда
ВызватьИсключение "Некорректное выражение представления";
КонецЕсли;
ПредставлениеЭлемента = "." + ПредставлениеЭлемента;
КонецЕсли;
Рез = Новый Массив;
Для каждого ЭлементКоллекции Из Коллекция Цикл
ТекПредставление = Строка(Вычислить("ЭлементКоллекции" + ПредставлениеЭлемента));
Рез.Добавить(ТекПредставление);
КонецЦикла;
Возврат Рез;
КонецФункции // РазвернутьКоллекцию()
// Разворачивает массив строк через РазвернутьСтрокуОбходаМетаданных
//
// Параметры
// МассивСтрокОбхода - Массив - Массив разворачиваемых строк
// ЗаменяемоеЗначение - Строка - заменяемое значение
// ПредставлениеПоУмолчанию - Строка - выражение для получения представления
//
// Возвращаемое значение:
// Массив строк
//
Функция РазвернутьМассивСтрокОбходаМетаданных(МассивСтрокОбхода, ЗаменяемоеЗначение = "*", ПредставлениеПоУмолчанию = "Имя")
Рез = Новый Массив;
Для каждого СтрокаОбхода Из МассивСтрокОбхода Цикл
ДополнениеРезультата = РазвернутьСтрокуОбходаМетаданных(СтрокаОбхода, ЗаменяемоеЗначение, ПредставлениеПоУмолчанию);
Для каждого ТекСтрока Из ДополнениеРезультата Цикл
Рез.Добавить(ТекСтрока);
КонецЦикла;
КонецЦикла;
Возврат Рез;
КонецФункции // РазвернутьМассивСтрокОбходаМетаданных()
// Преобразует строку в массив одиночных строк по разделителю Символы.ПС
//
// Параметры
// ПреобразуемаяСтрока - строка для преобразования
// ИгнорироватьПустые - Булево - Пропускать пустые строки
// СокращатьПробелы - Использовать СокрЛП
//
// Возвращаемое значение:
// Массив строк
//
Функция ПолучитьМассивСтрокМногострочнойСтроки(ПреобразуемаяСтрока, ИгнорироватьПустые = Истина, СокращатьПробелы = Истина)
Рез = Новый Массив;
ЧислоСтрок = СтрЧислоСтрок(ПреобразуемаяСтрока);
Для Сч = 1 По ЧислоСтрок Цикл
ТекСтрока = СтрПолучитьСтроку(ПреобразуемаяСтрока, Сч);
Если ИгнорироватьПустые и ПустаяСтрока(ТекСтрока) Тогда
Продолжить;
КонецЕсли;
Если СокращатьПробелы Тогда
ТекСтрока = СокрЛП(ТекСтрока);
КонецЕсли;
Рез.Добавить(ТекСтрока);
КонецЦикла;
Возврат Рез;
КонецФункции // ПолучитьМассивСтрокМногострочнойСтроки()
// Возвращает все реквизиты конфигурации, которые сохраняются в ИБ
//
// Параметры - Нет
//
// Возвращаемое значение:
// Массив объектов метаданных
//
Функция ПолучитьВсеХранимыеРеквизитыКонфигурации() Экспорт
СтрокаВсехРеквизитов =
"
|Метаданные.Константы.*
|Метаданные.ПланыОбмена.*.Реквизиты.*
|Метаданные.ПланыОбмена.*.ТабличныеЧасти.*.Реквизиты.*
|Метаданные.Справочники.*.Реквизиты.*
|Метаданные.Справочники.*.ТабличныеЧасти.*.Реквизиты.*
|Метаданные.Документы.*.Реквизиты.*
|Метаданные.Документы.*.ТабличныеЧасти.*.Реквизиты.*
|Метаданные.Последовательности.*.Измерения.*
|Метаданные.ПланыВидовХарактеристик.*.Реквизиты.*
|Метаданные.ПланыВидовХарактеристик.*.ТабличныеЧасти.*.Реквизиты.*
|Метаданные.ПланыСчетов.*.Реквизиты.*
|Метаданные.ПланыСчетов.*.ПризнакиУчета.*
|Метаданные.ПланыСчетов.*.ПризнакиУчетаСубконто.*
|Метаданные.ПланыСчетов.*.ТабличныеЧасти.*.Реквизиты.*
|Метаданные.ПланыВидовРасчета.*.Реквизиты.*
|Метаданные.ПланыВидовРасчета.*.ТабличныеЧасти.*.Реквизиты.*
|Метаданные.РегистрыСведений.*.Измерения.*
|Метаданные.РегистрыСведений.*.Ресурсы.*
|Метаданные.РегистрыСведений.*.Реквизиты.*
|Метаданные.РегистрыНакопления.*.Измерения.*
|Метаданные.РегистрыНакопления.*.Ресурсы.*
|Метаданные.РегистрыНакопления.*.Реквизиты.*
|Метаданные.РегистрыБухгалтерии.*.Измерения.*
|Метаданные.РегистрыБухгалтерии.*.Ресурсы.*
|Метаданные.РегистрыБухгалтерии.*.Реквизиты.*
|Метаданные.РегистрыРасчета.*.Измерения.*
|Метаданные.РегистрыРасчета.*.Ресурсы.*
|Метаданные.РегистрыРасчета.*.Реквизиты.*
|Метаданные.БизнесПроцессы.*.Реквизиты.*
|Метаданные.БизнесПроцессы.*.ТабличныеЧасти.*.Реквизиты.*
|Метаданные.Задачи.*.Реквизиты.*
|Метаданные.Задачи.*.РеквизитыАдресации.*
|Метаданные.Задачи.*.ТабличныеЧасти.*.Реквизиты.*
|";
ВсеХранимыеРеквизитыКонфигурации = РазвернутьМассивСтрокОбходаМетаданных(ПолучитьМассивСтрокМногострочнойСтроки(СтрокаВсехРеквизитов));
Возврат ВсеХранимыеРеквизитыКонфигурации;
КонецФункции // ПолучитьВсеХранимыеРеквизитыКонфигурации()
// Возвращает все реквизиты конфигурации составного типа, которые сохраняются в ИБ
//
// Параметры - Нет
//
// Возвращаемое значение:
// ТаблицаЗначений
//
Функция ПолучитьВсеХранимыеРеквизитыКонфигурацииСоставногоТипа() Экспорт
ВсеХранимыеРеквизитыКонфигурации = ПолучитьВсеХранимыеРеквизитыКонфигурации();
Рез = Новый ТаблицаЗначений;
Рез.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка"));
Рез.Колонки.Добавить("Тип", Новый ОписаниеТипов("ОписаниеТипов"));
Рез.Колонки.Добавить("КоличествоПростыхТипов", Новый ОписаниеТипов("Число"));
Для каждого ТекРеквизит Из ВсеХранимыеРеквизитыКонфигурации Цикл
Реквизит = Вычислить(ТекРеквизит);
Тип = Реквизит.Тип;
КоличествоПростыхТипов = Тип.Типы().Количество();
Если КоличествоПростыхТипов<>1 Тогда
ТекСтрока = Рез.Добавить();
ТекСтрока.Имя = ТекРеквизит;
ТекСтрока.Тип = Тип;
ТекСтрока.КоличествоПростыхТипов = КоличествоПростыхТипов;
КонецЕсли;
КонецЦикла;
Возврат Рез;
КонецФункции // ПолучитьВсеХранимыеРеквизитыКонфигурации()
// Возвращает все формы конфигурации
//
// Параметры - Нет
//
// Возвращаемое значение:
// Массив объектов метаданных
//
Функция ПолучитьВсеФормыКонфигурации() Экспорт
СтрокаВсехРеквизитов =
"
|Метаданные.ПланыОбмена.*.Формы.*
|Метаданные.КритерииОтбора.*.Формы.*
|Метаданные.ОбщиеФормы.*
|Метаданные.Справочники.*.Формы.*
|Метаданные.Документы.*.Формы.*
|Метаданные.ЖурналыДокументов.*.Формы.*
|Метаданные.Перечисления.*.Формы.*
|Метаданные.Отчеты.*.Формы.*
|Метаданные.Обработки.*.Формы.*
|Метаданные.ПланыВидовХарактеристик.*.Формы.*
|Метаданные.ПланыСчетов.*.Формы.*
|Метаданные.ПланыВидовРасчета.*.Формы.*
|Метаданные.РегистрыСведений.*.Формы.*
|Метаданные.РегистрыНакопления.*.Формы.*
|Метаданные.РегистрыБухгалтерии.*.Формы.*
|Метаданные.РегистрыРасчета.*.Формы.*
|Метаданные.БизнесПроцессы.*.Формы.*
|Метаданные.Задачи.*.Формы.*
|";
ВсеФормыКонфигурации = РазвернутьМассивСтрокОбходаМетаданных(ПолучитьМассивСтрокМногострочнойСтроки(СтрокаВсехРеквизитов));
Возврат ВсеФормыКонфигурации;
КонецФункции // ПолучитьВсеФормыКонфигурации()
// Возвращает все макеты конфигурации
//
// Параметры - Нет
//
// Возвращаемое значение:
// Массив объектов метаданных
//
Функция ПолучитьВсеМакетыКонфигурации() Экспорт
СтрокаВсехРеквизитов =
"
|Метаданные.ПланыОбмена.*.Макеты.*
|Метаданные.ОбщиеМакеты.*
|Метаданные.Справочники.*.Макеты.*
|Метаданные.Документы.*.Макеты.*
|Метаданные.ЖурналыДокументов.*.Макеты.*
|Метаданные.Перечисления.*.Макеты.*
|Метаданные.Отчеты.*.Макеты.*
|Метаданные.Обработки.*.Макеты.*
|Метаданные.ПланыВидовХарактеристик.*.Макеты.*
|Метаданные.ПланыСчетов.*.Макеты.*
|Метаданные.ПланыВидовРасчета.*.Макеты.*
|Метаданные.РегистрыСведений.*.Макеты.*
|Метаданные.РегистрыНакопления.*.Макеты.*
|Метаданные.РегистрыБухгалтерии.*.Макеты.*
|Метаданные.РегистрыРасчета.*.Макеты.*
|Метаданные.БизнесПроцессы.*.Макеты.*
|Метаданные.Задачи.*.Макеты.*
|";
ВсеМакетыКонфигурации = РазвернутьМассивСтрокОбходаМетаданных(ПолучитьМассивСтрокМногострочнойСтроки(СтрокаВсехРеквизитов));
Возврат ВсеМакетыКонфигурации;
КонецФункции // ПолучитьВсеМакетыКонфигурации()
Категория:
Метаданные Управляем 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-пакеты Яндекс, Google, Рамблер Карты и 1С Обработка демонстрирует возможности интеграции 1С с картографическими сервисами, в ней поддерживается работа трех поставщиков услуг / карт — Яндекс, Google. Рамблер.
Автор: Діма Головаченко - http://smaylukk.com.ua
но так вот сама обработка + еще 2 :
Скачивать файлы может только зарегистрированный пользователь!
Код Модуля Обработки:
Код 1C v 8.х Перем СтруктураПоставщиковКарт Экспорт;
Перем СтруктураЧисел;
/////////////////////////РАБОТА С JSON //////////////////////////////////////////
Функция СформироватьСтрокуJSONИзМассива(Объект)
СтрокаJSON = "[";
Для каждого Элемент Из Объект Цикл
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON(Элемент) + ",";
КонецЦикла;
Если Прав(СтрокаJSON, 1) = "," Тогда
СтрокаJSON = Лев(СтрокаJSON, СтрДлина(СтрокаJSON)-1);
КонецЕсли;
Возврат СтрокаJSON + "]";
КонецФункции
Функция СформироватьСтрокуJSONИзСтруктуры(Объект)
СтрокаJSON = "{";
Для каждого Элемент Из Объект Цикл
Если Элемент.Значение = "" Тогда
Продолжить;
КонецЕсли;
СтрокаJSON = СтрокаJSON + """" + Элемент.Ключ + """" + ":";
Если ТипЗнч(Элемент.Значение) = Тип("Строка") Тогда
СтрокаJSON = СтрокаJSON + """" + URLEncode(Элемент.Значение) + """";
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("Число") Тогда
СтрокаJSON = СтрокаJSON + СтрЗаменить(Строка(Элемент.Значение), Символы.НПП, "");
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("Булево") Тогда
СтрокаJSON = СтрокаJSON + Формат(Элемент.Значение, "БЛ=false; БИ=true");
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("Дата") Тогда
// преобразование в unixtime
СтрокаJSON = СтрокаJSON + Формат(ТекущаяДата() - Дата(1970,1,1,1,0,0), "ЧГ=0");
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("Массив") Тогда
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON(Элемент.Значение);
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("Структура") Тогда
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON(Элемент.Значение);
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("ТаблицаЗначений") Тогда
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON(Элемент.Значение);
Иначе
СтрокаJSON = СтрокаJSON + """" + URLEncode(Строка(Элемент.Значение)) + """";
КонецЕсли;
СтрокаJSON = СтрокаJSON + ",";
КонецЦикла;
Если Прав(СтрокаJSON, 1) = "," Тогда
СтрокаJSON = Лев(СтрокаJSON, СтрДлина(СтрокаJSON)-1);
КонецЕсли;
Возврат СтрокаJSON + "}";
КонецФункции
Функция СформироватьСтрокуJSON(Объект) Экспорт
СтрокаJSON = "";
Если ТипЗнч(Объект) = Тип("Массив") Тогда
СтрокаJSON = СформироватьСтрокуJSONИзМассива(Объект);
ИначеЕсли ТипЗнч(Объект) = Тип("Структура") Тогда
СтрокаJSON = СформироватьСтрокуJSONИзСтруктуры(Объект);
ИначеЕсли ТипЗнч(Объект) = Тип("ТаблицаЗначений") Тогда
// преобразуем таблицу значений в массив структур - работает дольше, но кода меньше
// если нужна скорость, то нужно отдельно обработать таблицу значений
СоставСтруктуры = "";
Для каждого Колонка Из Объект.Колонки Цикл
СоставСтруктуры = СоставСтруктуры + ?(ЗначениеЗаполнено(СоставСтруктуры), ",", "") + Колонка.Имя;
КонецЦикла;
МассивСтрок = Новый Массив;
Для каждого Строка Из Объект Цикл
СтруктураКолонок = Новый Структура(СоставСтруктуры);
ЗаполнитьЗначенияСвойств(СтруктураКолонок, Строка);
МассивСтрок.Добавить(СтруктураКолонок);
КонецЦикла;
СтрокаJSON = СформироватьСтрокуJSONИзМассива(МассивСтрок);
КонецЕсли;
Возврат СтрокаJSON;
КонецФункции
Процедура ЗаполнитьДанныеИзОтветаJSON(Результат, ТекстJSON, ТипДанных)
ТекстJSON = СокрЛП(Сред(ТекстJSON, 2)); // удалим открывающий символ структуры(массива)
НомерЗначения = 0;
Пока ТекстJSON <> "" Цикл
ПервыйСимвол = Лев(ТекстJSON, 1);
Если ПервыйСимвол = "{" Тогда
// вложенная структура
Значение = Новый Структура;
ЗаполнитьДанныеИзОтветаJSON(Значение, ТекстJSON, "Структура");
Если ТипДанных = "Структура" Тогда
Результат.Вставить("Значение" + ?(НомерЗначения = 0, "", НомерЗначения), Значение);
НомерЗначения = НомерЗначения + 1;
ИначеЕсли ТипДанных = "Массив" Тогда
Результат.Добавить(Значение);
КонецЕсли;
ИначеЕсли ПервыйСимвол = "[" Тогда
// вложенный массив
Значение = Новый Массив;
ЗаполнитьДанныеИзОтветаJSON(Значение, ТекстJSON, "Массив");
Если ТипДанных = "Структура" Тогда
Результат.Вставить("Значение" + ?(НомерЗначения = 0, "", НомерЗначения), Значение);
НомерЗначения = НомерЗначения + 1;
Иначе
Результат.Добавить(Значение);
КонецЕсли;
ИначеЕсли ПервыйСимвол = "}" И ТипДанных = "Структура" Тогда
// структура закончилась
ТекстJSON = СокрЛП(Сред(ТекстJSON, 2));
Если Лев(ТекстJSON, 1) = "," Тогда
ТекстJSON = СокрЛП(Сред(ТекстJSON, 2));
КонецЕсли;
Возврат;
ИначеЕсли ПервыйСимвол = "]" И ТипДанных = "Массив" Тогда
// массив закончился
ТекстJSON = СокрЛП(Сред(ТекстJSON, 2));
Если Лев(ТекстJSON, 1) = "," Тогда
ТекстJSON = СокрЛП(Сред(ТекстJSON, 2));
КонецЕсли;
Возврат;
Иначе
Если ТипДанных = "Структура" Тогда
//ПервыйКавычка = Ложь;
//Если Лев(ТекстJSON, 1) = """" Тогда
// ПервыйКавычка = Истина;
//КонецЕсли;
Поз = Найти(ТекстJSON, ":");
Если Поз = 0 Тогда
// неверный формат, прервемся
Прервать;
КонецЕсли;
//ПредпоследнийКавычка = Ложь;
//Если Сред(ТекстJSON, Поз - 1, 1) = """" Тогда
// ПредпоследнийКавычка = Истина;
//КонецЕсли;
ИмяЗначения = СокрЛП(Лев(ТекстJSON, Поз - 1));
ИмяЗначения = СтрЗаменить(ИмяЗначения, """", "");
ТекстJSON = СокрЛП(Сред(ТекстJSON, Поз+1));
Если Лев(ТекстJSON, 1) = "{" Тогда
// значение является структурой
Значение = Новый Структура;
ЗаполнитьДанныеИзОтветаJSON(Значение, ТекстJSON, "Структура");
ИначеЕсли Лев(ТекстJSON, 1) = "[" Тогда
// значение является массивом
Значение = Новый Массив;
ЗаполнитьДанныеИзОтветаJSON(Значение, ТекстJSON, "Массив");
Иначе
// обычное значение
ПервыйКавычка = Ложь;
ПредпоследнийКавычка = Ложь;
Поз = 0;
Для Сч = 1 По СтрДлина(ТекстJSON) Цикл
Символ = Сред(ТекстJSON, Сч, 1);
Если Символ = """" Тогда
Если ПервыйКавычка Тогда
ПредпоследнийКавычка = Истина;
Иначе
ПервыйКавычка = Истина;
КонецЕсли;
КонецЕсли;
Если (Символ = "," И ((ПервыйКавычка И ПредпоследнийКавычка) Или (Не ПервыйКавычка И Не ПредпоследнийКавычка))) ИЛИ Символ = "]" ИЛИ Символ = "}" Тогда
Поз = Сч;
Прервать;
КонецЕсли;
КонецЦикла;
//ПредпоследнийКавычка = Ложь;
//Если Сред(ТекстJSON, Поз - 1, 1) = """" Тогда
// ПредпоследнийКавычка = Истина;
//КонецЕсли;
Если Поз = 0 Тогда
Значение = ТекстJSON;
ТекстJSON = "";
Иначе
Значение = Лев(ТекстJSON, Поз - 1);
Значение = СтрЗаменить(Значение, """", "");
ТекстJSON = СокрЛП(Сред(ТекстJSON, Поз + ?(Сред(ТекстJSON, Поз, 1) = ",", 1, 0)));
КонецЕсли;
Значение = СокрЛП(Значение);
КонецЕсли;
Результат.Вставить(ИмяЗначения, Значение);
ИначеЕсли ТипДанных = "Массив" Тогда
// обычное значение
Поз = 0;
Для Сч = 1 По СтрДлина(ТекстJSON) Цикл
Символ = Сред(ТекстJSON, Сч, 1);
Если Символ = "," ИЛИ Символ = "]" ИЛИ Символ = "}" Тогда
Поз = Сч;
Прервать;
КонецЕсли;
КонецЦикла;
//ПредпоследнийКавычка = Ложь;
//Если Сред(ТекстJSON, Поз - 1, 1) = """" Тогда
// ПредпоследнийКавычка = Истина;
//КонецЕсли;
Если Поз = 0 Тогда
Значение = ТекстJSON;
ТекстJSON = "";
Иначе
Значение = Лев(ТекстJSON, Поз - 1);
Значение = СтрЗаменить(Значение, """", "");
ТекстJSON = СокрЛП(Сред(ТекстJSON, Поз + ?(Сред(ТекстJSON, Поз, 1) = ",", 1, 0)));
КонецЕсли;
Значение = СокрЛП(Значение);
Результат.Добавить(Значение);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция ЗаполнитьСтруктуруИзОтветаJSON(Знач ТекстJSON) Экспорт
Результат = Новый Структура;
ТекстJSON = СтрЗаменить(ТекстJSON, "\""", """"); // заменим последовательность \" на "
//ТекстJSON = СтрЗаменить(ТекстJSON, """", ""); // а теперь удалим все кавычки
Если Лев(ТекстJSON, 1) = "{" Тогда
// начало структуры
ЗаполнитьДанныеИзОтветаJSON(Результат, ТекстJSON, "Структура");
ИначеЕсли Лев(ТекстJSON, 1) = "[" Тогда
// начало массива
МассивДанных = Новый Массив;
ЗаполнитьДанныеИзОтветаJSON(МассивДанных, ТекстJSON, "Массив");
Результат.Вставить("Значение", МассивДанных);
КонецЕсли;
Возврат Результат;
КонецФункции
Функция КодСимволаASCII(Символ)
КодUNICODE = КодСимвола(Символ);
Если ((КодUNICODE > 1039) И (КодUNICODE < 1104)) Тогда
Возврат (КодUNICODE - 848);
ИначеЕсли КодUNICODE = 8470 Тогда
Возврат 185;
ИначеЕсли КодUNICODE = 1105 Тогда
Возврат 184;
ИначеЕсли КодUNICODE = 1025 Тогда
Возврат 168;
Иначе
Возврат КодUNICODE;
КонецЕсли;
КонецФункции
Функция URLEncode(value)
table = "%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14" +
"%15%16%17%18%19%1A%1B%1C%1D%1E%1F%20%21%22%23%24%25%26%27%28" +
"%29%2A%2B%2C%2D%2E%2F%30%31%32%33%34%35%36%37%38%39%3A%3B%3C" +
"%3D%3E%3F%40%41%42%43%44%45%46%47%48%49%4A%4B%4C%4D%4E%4F%50" +
"%51%52%53%54%55%56%57%58%59%5A%5B%5C%5D%5E%5F%60%61%62%63%64" +
"%65%66%67%68%69%6A%6B%6C%6D%6E%6F%70%71%72%73%74%75%76%77%78" +
"%79%7A%7B%7C%7D%7E%7F%80%81%82%83%84%85%86%87%88%89%8A%8B%8C" +
"%8D%8E%8F%90%91%92%93%94%95%96%97%98%99%9A%9B%9C%9D%9E%9F%A0" +
"%A1%A2%A3%A4%A5%A6%A7%A8%A9%AA%AB%AC%AD%AE%AF%B0%B1%B2%B3%B4" +
"%B5%B6%B7%B8%B9%BA%BB%BC%BD%BE%BF%C0%C1%C2%C3%C4%C5%C6%C7%C8" +
"%C9%CA%CB%CC%CD%CE%CF%D0%D1%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC" +
"%DD%DE%DF%E0%E1%E2%E3%E4%E5%E6%E7%E8%E9%EA%EB%EC%ED%EE%EF%F0" +
"%F1%F2%F3%F4%F5%F6%F7%F8%F9%FA%FB%FC%FD%FE%FF";
result = "";
length = СтрДлина( value );
Для i = 1 По length Цикл
symbol = Сред( value, i, 1 );
//code = КодСимвола( symbol );
code = КодСимволаASCII( symbol );
result = result + Сред( table, code*3 + 1, 3 );
КонецЦикла;
Возврат result;
КонецФункции
/////////////////////////РАБОТА С JSON //////////////////////////////////////////
//Функция декодирует полученный unicod текст - из ответа геокодера Рамблера
// в привычный нам
//Параметры:
// Строка
//Возвращаемое значение:
// Строка
Функция UnicodeEncode(Строка) Экспорт
Результат = Истина;
Попытка
//регулярное выражение
Рег = Новый COMОбъект("VBScript.RegExp");
Рег.IgnoreCase = Истина;
Рег.Global = Истина;
Рег.Multiline = Ложь;
Рег.Pattern = "u[0-9a-f]+";
Колекция = Рег.Execute(Строка);
Для Каждого Элемент Из Колекция Цикл
Если СтрДЛина(Элемент.value) = 1 Тогда
Продолжить;
КонецЕсли;
КодСимвола = ПереводЧислаИз16в10(Сред(ВРег(Элемент.value), 2));
Символ = Символ(КодСимвола);
Строка = СтрЗаменить(Строка, "\" + Элемент.value, Символ);
КонецЦикла;
Исключение
Результат = Ложь;
Сообщить("Ошибка преобразования из Unicode", СтатусСообщения.Информация);
КонецПопытки;
Возврат Результат;
КонецФункции
Функция ПереводЧислаИз16в10(Знач Значение)
Результат = 0;
//перевод значения в строку
Если ТипЗнч(Значение) <> Тип("Строка") Тогда
Значение = СокрЛП(Строка(Значение));
КонецЕсли;
МаксРазрядЦелых = 0;
МаксРазрядЦелых = СтрДлина(Значение) - 1;
н = МаксРазрядЦелых;
Ин = 1;
Пока н >= 0 Цикл
ТекЗначение = СтруктураЧисел.Получить(Сред(Значение, Ин, 1)) * Pow(16, н);
Результат = Результат + ТекЗначение;
н = н - 1;
Ин = Ин + 1;
КонецЦикла;
Возврат Результат;
КонецФункции
///////////////////////////
СтруктураПоставщиковКарт = Новый Соответствие;
СтруктураПоставщиковКарт.Вставить(0, "Яндекс");
СтруктураПоставщиковКарт.Вставить(1, "Гугл");
СтруктураПоставщиковКарт.Вставить(2, "2ГИС");
СтруктураПоставщиковКарт.Вставить(3, "Рамблер");
СтруктураЧисел = Новый Соответствие;
СтруктураЧисел.Вставить("0", 0);
СтруктураЧисел.Вставить("1", 1);
СтруктураЧисел.Вставить("2", 2);
СтруктураЧисел.Вставить("3", 3);
СтруктураЧисел.Вставить("4", 4);
СтруктураЧисел.Вставить("5", 5);
СтруктураЧисел.Вставить("6", 6);
СтруктураЧисел.Вставить("7", 7);
СтруктураЧисел.Вставить("8", 8);
СтруктураЧисел.Вставить("9", 9);
СтруктураЧисел.Вставить("A", 10);
СтруктураЧисел.Вставить("B", 11);
СтруктураЧисел.Вставить("C", 12);
СтруктураЧисел.Вставить("D", 13);
СтруктураЧисел.Вставить("E", 14);
СтруктураЧисел.Вставить("F", 15);
Код Формы Управляемой:
Код 1C v 8.2 УП
&НаКлиенте
Процедура НайтиАдрес(Команда)
НайтиАдресНаКарте(ТекАдрес);
КонецПроцедуры
&НаКлиенте
Процедура ИнициализацияКарты(Команда)
ИнициализироватьКарту();
КонецПроцедуры
&НаКлиенте
Процедура СправочнаяИнформация(Команда)
Элементы.ГруппаСправка.Видимость = Не Элементы.ГруппаСправка.Видимость;
КонецПроцедуры
&НаКлиенте
Процедура Разработчик(Команда)
ЗапуститьПриложение("http://smaylukk.com.ua/?lang=Ru");
КонецПроцедуры
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Объект.ТипКарты = Параметры.ТипКарты;
ТекОбъект = РеквизитФормыВЗначение("Объект");
Поставщик = ТекОбъект.СтруктураПоставщиковКарт.Получить(Объект.ТипКарты);
Макет = ТекОбъект.ПолучитьМакет("Справка");
ТекстСправки = Макет.ПолучитьОбласть("Справка" + Поставщик).Область().Текст;
Справка = ТекстСправки;
КонецПроцедуры
&НаКлиенте
Процедура ПриОткрытии(Отказ)
Элементы.ГруппаСправка.Видимость = Ложь;
Заголовок = "Работа с картами. Поставщик - " + Поставщик;
ИнициализироватьКарту();
КонецПроцедуры
&НаКлиенте
Процедура ПриЗакрытии()
//удаление временных файлов
Для Каждого ТекЭлемент Из МассивВременныхФайлов Цикл
УдалитьФайлы(ТекЭлемент.Значение);
КонецЦикла;
КонецПроцедуры
&НаКлиенте
//Процедура составляет имя процедуры поставщика
// и запускает ее на исполнение
//Параметры:
// НачалоИмени - Строка
Процедура ВыполнитьПроцедуруПоставщика(ИмяПроцедуры)
Выполнить ИмяПроцедуры;
КонецПроцедуры
&НаКлиенте
//процедура инициализирует карту постащика из макета
Процедура ИнициализироватьКарту()
Текст = ПолучитьТекстМакета("Макет" + Поставщик);
Эксплорер = Текст;
КонецПроцедуры
&НаСервере
Функция ПолучитьТекстМакета(ИмяМакета)
Макет = РеквизитФормыВЗначение("Объект").ПолучитьМакет(ИмяМакета);
Результат = Макет.ПолучитьТекст();
Возврат Результат;
КонецФункции
&НаКлиенте
Процедура ОчисткаКарты()
Элементы.Эксплорер.document.getElementById("WebClientOperation").value = "Reset()";
Элементы.Эксплорер.document.getElementById("WebClient").click();
КонецПроцедуры
///////////////////////////////////////////////////////////////////////
///////////////////ГЕОКОДИРОВАНИЕ И ПОИСК АДРЕСА///////////////////////
///////////////////////////////////////////////////////////////////////
&НаКлиенте
Процедура НайтиАдресНаКарте(Адрес = "")
//поиск адреса
Если Адрес = "" Тогда
Адрес = "Москва";
КонецЕсли;
// дальше пробуем с помощью геокодинга вывести данные поиска в таблицу
ТаблицаАдресов.Очистить();
ПоискАдреса(Адрес);
Если Поставщик = "Яндекс" Тогда
ПроизвестиГеокодинг_Яндекс();
ИначеЕсли Поставщик = "Гугл" Тогда
ПроизвестиГеокодинг_Гугл();
ИначеЕсли Поставщик = "Рамблер" Тогда
ПроизвестиГеокодинг_Рамблер();
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПоискАдреса(Адрес)
Элементы.Эксплорер.document.getElementById("WebClientOperation").value = "FindAdres(""" + Адрес + """);";
Элементы.Эксплорер.document.getElementById("WebClient").click();
КонецПроцедуры
&НаСервере
//Процедура выводит в таблицу данные геокдинга Яндекса
//
//Параметры:
// ТекАдрес - Строка
Процедура ПроизвестиГеокодинг_Яндекс()
Яндекс = Новый HTTPСоединение("geocode-maps.yandex.ru");
ВременныйФайл = КаталогВременныхФайлов() + "Yandex_geocode_" + СокрЛП(Новый УникальныйИдентификатор);
Попытка
Яндекс.Получить("/1.x/?geocode=" + ТекАдрес + "&results=10", ВременныйФайл);
Исключение
Сообщить("Ошибка при попытке геокодировать по яндексу адрес: " + ТекАдрес);
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ВременныйФайл);
ПостроительDOM = Новый ПостроительDOM;
ДокументДОМ = ПостроительDOM.Прочитать(ЧтениеXML);
СписокText = ДокументДОМ.ПолучитьЭлементыПоИмени("text");
СписокPos = ДокументДОМ.ПолучитьЭлементыПоИмени("pos");
Если (СписокText.Количество() = 0) ИЛИ (СписокPos.Количество() = 0) Тогда
Возврат;
КонецЕсли;
Для ъ = 0 по СписокText.Количество()-1 Цикл
Координаты = СписокPos[Ъ].ТекстовоеСодержимое;
Разделитель = Найти(Координаты," ");
Широта = Число(Сред(Координаты, Разделитель + 1));
Долгота = Число(Лев(Координаты, Разделитель - 1));
Если Широта = 0 ИЛИ Долгота = 0 Тогда
Продолжить;
КонецЕсли;
стрАдрес = ТаблицаАдресов.Добавить();
Если СписокText.Количество() > ъ Тогда
стрАдрес.Адрес = СписокText[Ъ].ТекстовоеСодержимое;
стрАдрес.Широта = Широта;
стрАдрес.Долгота = Долгота;
КонецЕсли;
КонецЦикла;
МассивВременныхФайлов.Добавить(ВременныйФайл);
КонецПроцедуры
&НаСервере
//Процедура выводит в таблицу данные геокдинга Гугл
//
//Параметры:
// ТекАдрес - Строка
Процедура ПроизвестиГеокодинг_Гугл()
Гугл = Новый HTTPСоединение("maps.googleapis.com");
ВременныйФайл = КаталогВременныхФайлов() + "Google_geocode_" + СокрЛП(Новый УникальныйИдентификатор);
Попытка
Гугл.Получить("/maps/api/geocode/xml?address=" + ТекАдрес + "&language=ru&sensor=false", ВременныйФайл);
Исключение
Сообщить("Ошибка при попытке геокодировать по Google адрес: " + ТекАдрес);
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ВременныйФайл);
ПостроительDOM = Новый ПостроительDOM;
ДокументДОМ = ПостроительDOM.Прочитать(ЧтениеXML);
ТаблицаРезультатов = ДокументДОМ.ПолучитьЭлементыПоИмени("result");
Если ДокументДОМ.ПолучитьЭлементыПоИмени("status")[0].ТекстовоеСодержимое <> "OK" ИЛИ ТаблицаРезультатов.Количество() = 0 Тогда
Возврат;
КонецЕсли;
Для ТекРезультат = 0 по ТаблицаРезультатов.Количество() -1 Цикл
СписокText = ТаблицаРезультатов[ТекРезультат].ПолучитьЭлементыПоИмени("formatted_address");
ЭлементыШиротаДолгота = ТаблицаРезультатов[ТекРезультат].ПолучитьЭлементыПоИмени("location");
Широта = ЭлементыШиротаДолгота[0].ПолучитьЭлементыПоИмени("lat")[0].ТекстовоеСодержимое;
Долгота = ЭлементыШиротаДолгота[0].ПолучитьЭлементыПоИмени("lng")[0].ТекстовоеСодержимое;
Если Широта = 0 ИЛИ Долгота = 0 Тогда
Продолжить;
КонецЕсли;
стрАдрес = ТаблицаАдресов.Добавить();
стрАдрес.Широта = Широта;
стрАдрес.Долгота = Долгота;
стрАдрес.Адрес = СписокText[0].ТекстовоеСодержимое;
КонецЦикла;
МассивВременныхФайлов.Добавить(ВременныйФайл);
КонецПроцедуры
&НаСервере
//Процедура выводит в таблицу данные геокдинга Рамблер
//
//Параметры:
// ТекАдрес - Строка
Процедура ПроизвестиГеокодинг_Рамблер()
ТемпАдрес = СтрЗаменить(ТекАдрес, " ", "+");
Рамблер = Новый HTTPСоединение("maps.rambler.ru");
ВременныйФайл = КаталогВременныхФайлов() + "Рамблер_geocode_" + СокрЛП(Новый УникальныйИдентификатор);
Попытка
Рамблер.Получить("/search/?&a=search&q=" + ТемпАдрес + "&n=10", ВременныйФайл);
Исключение
Сообщить("Ошибка при попытке геокодировать по Рамблер адрес: " + ТекАдрес);
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
а = 1;
Т = Новый ТекстовыйДокумент;
Т.Прочитать(ВременныйФайл);
СтрокаОтвет = Т.ПолучитьТекст();
Результат = РеквизитФормыВЗначение("Объект").UnicodeEncode(СтрокаОтвет);
Если Результат Тогда
СтруктураJSON = РеквизитФормыВЗначение("Объект").ЗаполнитьСтруктуруИзОтветаJSON(СтрокаОтвет);
КонецЕсли;
МассивРезультатов = СтруктураJSON.res;
//обрабатываем элементы массива - только адреса. POI можно обработать отдельно пожеланию
Для Каждого Результат Из МассивРезультатов Цикл
Для Каждого ТекРезультат Из Результат.matches Цикл
стрАдрес = ТаблицаАдресов.Добавить();
стрАдрес.Долгота = Число(ТекРезультат.x);
стрАдрес.Широта = Число(ТекРезультат.y);
Если Результат.type = "addr" Тогда //Результат.type = "poi" - содержит в себе список точек интереса
стрАдрес.Адрес = ТекРезультат.addr;
Иначе
стрАдрес.Адрес = ТекРезультат.name + " - " + ТекРезультат.addr;
КонецЕсли;
КонецЦикла;
КонецЦикла;
МассивВременныхФайлов.Добавить(ВременныйФайл);
КонецПроцедуры
&НаКлиенте
Процедура ОбратнПоискАдреса(Широта, Долгота, Адрес)
Элементы.Эксплорер.document.getElementById("WebClientOperation").value = "ReverseSearchAdres(" + Широта + "," + Долгота + ", """ + Адрес + """);";
Элементы.Эксплорер.document.getElementById("WebClient").click();
КонецПроцедуры
&НаКлиенте
Процедура ТаблицаАдресовВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
Если ЗначениеЗаполнено(ТаблицаАдресов[ВыбраннаяСтрока].Широта) И ЗначениеЗаполнено(ТаблицаАдресов[ВыбраннаяСтрока].Долгота) Тогда
СтандартнаяОбработка = Ложь;
КонецЕсли;
Широта = Формат(ТаблицаАдресов[ВыбраннаяСтрока].Широта, "ЧЦ=10; ЧДЦ=7; ЧРД=.; ЧРГ=");
Долгота = Формат(ТаблицаАдресов[ВыбраннаяСтрока].Долгота, "ЧЦ=10; ЧДЦ=7; ЧРД=.; ЧРГ=");
ОбратнПоискАдреса(Широта, Долгота, ТаблицаАдресов[ВыбраннаяСтрока].Адрес);
КонецПроцедуры
&НаКлиенте
Процедура ТекАдресПриИзменении(Элемент)
НайтиАдресНаКарте(ТекАдрес);
КонецПроцедуры
///////////////////////////////////////////////////////////////////////
///////////////////МАРШРУТИЗАЦИЯ, КЛАСТЕРА И ПОЛИГОН///////////////////////////////////////
///////////////////////////////////////////////////////////////////////
&НаКлиенте
Процедура ЭксплорерПриНажатии(Элемент, ДанныеСобытия, СтандартнаяОбработка)
ПолучитьКоординаты();
КонецПроцедуры
&НаКлиенте
Процедура ПостроитьМаршрут(Команда)
Если ТаблицаТочек.Количество() <= 1 Тогда
Предупреждение("Недостаточно точек для построение маршрута!");
Возврат;
КонецЕсли;
Если Поставщик = "Яндекс" Тогда
ПостроитьМаршрут_Яндекс();
ИначеЕсли Поставщик = "Гугл" Тогда
ПостроитьМаршрут_Гугл();
ИначеЕсли Поставщик = "Рамблер" Тогда
ПостроитьМаршрут_Рамблер();
КонецЕсли;
КонецПроцедуры
&НаКлиенте
//Процедура выстраивает маршрут для Яндекса
//
//Параметры:
//
Процедура ПостроитьМаршрут_Яндекс()
ПараметрыМаршрута = ПолучитьПараметрыМаршрутаЯндекс();
ОчисткаКарты();
Элементы.Эксплорер.document.getElementById("WebClientOperation").value = "calcRoute(" + ПараметрыМаршрута + ")";
Элементы.Эксплорер.document.getElementById("WebClient").click();
КонецПроцедуры
&НаКлиенте
//Функция получает массив точек, для передачи параметров в Яндекс
//
//Параметры:
//
//Возвращаемое значение:
// Строка
Функция ПолучитьПараметрыМаршрутаЯндекс()
Результат = "";
Результат = Результат + "[[" + СтрЗаменить(Строка(ТаблицаТочек[0].Широта), ",", ".") + "," + СтрЗаменить(Строка(ТаблицаТочек[0].Долгота), ",", ".") + "],";
Для Ин = 1 По ТаблицаТочек.Количество() - 2 Цикл
Результат = Результат + "[" + СтрЗаменить(Строка(ТаблицаТочек[ин].Широта), ",", ".") + "," + СтрЗаменить(Строка(ТаблицаТочек[ин].Долгота), ",", ".") + "],";
КонецЦикла;
Результат = Результат + "[" + СтрЗаменить(Строка(ТаблицаТочек[ТаблицаТочек.Количество() - 1].Широта), ",", ".") + "," + СтрЗаменить(Строка(ТаблицаТочек[ТаблицаТочек.Количество() - 1].Долгота), ",", ".") + "]]";
Возврат Результат;
КонецФункции
&НаКлиенте
//Процедура выстраивает маршрут для Гугл
//
//Параметры:
//
Процедура ПостроитьМаршрут_Гугл()
ПараметрыМаршрута = ПолучитьПараметрыМаршрутаГугл();
ОчисткаКарты();
Элементы.Эксплорер.document.getElementById("WebClientOperation").value = "calcRoute(" + ПараметрыМаршрута + ")";
Элементы.Эксплорер.document.getElementById("WebClient").click();
КонецПроцедуры
&НаКлиенте
//Функция получает массив точек, для передачи параметров в Гугл
//
//Параметры:
//
//Возвращаемое значение:
// Строка
Функция ПолучитьПараметрыМаршрутаГугл()
Результат = "";
ВнутрМассив = "";
Результат = Результат + "[[" + СтрЗаменить(Строка(ТаблицаТочек[0].Широта), ",", ".") + "," + СтрЗаменить(Строка(ТаблицаТочек[0].Долгота), ",", ".") + "],";
Если ТаблицаТочек.Количество() = 2 Тогда
Результат = Результат + "[],";
Иначе
Для Ин = 1 По ТаблицаТочек.Количество() - 2 Цикл
ВнутрМассив = ВнутрМассив + "[" + СтрЗаменить(Строка(ТаблицаТочек[ин].Широта), ",", ".") + "," + СтрЗаменить(Строка(ТаблицаТочек[ин].Долгота), ",", ".") + "],";
КонецЦикла;
Результат = Результат + "[" + Сред(ВнутрМассив, 1, СтрДлина(ВнутрМассив) - 1) + "],";
КонецЕсли;
Результат = Результат + "[" + СтрЗаменить(Строка(ТаблицаТочек[ТаблицаТочек.Количество() - 1].Широта), ",", ".") + "," + СтрЗаменить(Строка(ТаблицаТочек[ТаблицаТочек.Количество() - 1].Долгота), ",", ".") + "]]";
Возврат Результат;
КонецФункции
&НаКлиенте
//Процедура выстраивает маршрут для Рамблера
//
//Параметры:
//
Процедура ПостроитьМаршрут_Рамблер()
ПараметрыМаршрута = ПолучитьПараметрыМаршрутаРамблер();
ОчисткаКарты();
Элементы.Эксплорер.document.getElementById("WebClientOperation").value = "calcRoute(" + ПараметрыМаршрута + ")";
Элементы.Эксплорер.document.getElementById("WebClient").click();
КонецПроцедуры
&НаКлиенте
//Функция получает массив точек, для передачи параметров в Рамблер
//
//Параметры:
//
//Возвращаемое значение:
// Строка
Функция ПолучитьПараметрыМаршрутаРамблер()
Результат = "";
Результат = Результат + "[[" + СтрЗаменить(Строка(ТаблицаТочек[0].Широта), ",", ".") + "," + СтрЗаменить(Строка(ТаблицаТочек[0].Долгота), ",", ".") + "],";
Для Ин = 1 По ТаблицаТочек.Количество() - 2 Цикл
Результат = Результат + "[" + СтрЗаменить(Строка(ТаблицаТочек[ин].Широта), ",", ".") + "," + СтрЗаменить(Строка(ТаблицаТочек[ин].Долгота), ",", ".") + "],";
КонецЦикла;
Результат = Результат + "[" + СтрЗаменить(Строка(ТаблицаТочек[ТаблицаТочек.Количество() - 1].Широта), ",", ".") + "," + СтрЗаменить(Строка(ТаблицаТочек[ТаблицаТочек.Количество() - 1].Долгота), ",", ".") + "]]";
Возврат Результат;
КонецФункции
&НаКлиенте
Процедура СоздатьКластер(Команда)
Если ТаблицаТочек.Количество() <= 1 Тогда
Предупреждение("Недостаточно точек для построение кластера!");
Возврат;
КонецЕсли;
ОчисткаКарты();
ПостроитьКластера();
КонецПроцедуры
&НаКлиенте
Процедура ПостроитьКластера()
Кол = ТаблицаТочек.Количество();
Индекс = 1;
Для Каждого ТекСтрока Из ТаблицаТочек Цикл
Широта = формат(ТекСтрока.Широта, "ЧРД=.");
Долгота = формат(ТекСтрока.Долгота, "ЧРД=.");
СодержимоеТочки = "Содерижмое точки"; //опять же можно вставить свое название
Элементы.Эксплорер.document.getElementById("WebClientOperation").value = "addToPointArray(" + Широта + "," + Долгота + ", '" + ТекСтрока.Точка + "', """ + СодержимоеТочки + """);";
Элементы.Эксплорер.document.getElementById("WebClient").click();
Состояние("Обработан " + Индекс + " из " + кол);
Индекс = Индекс + 1;
КонецЦикла;
Элементы.Эксплорер.document.getElementById("WebClientOperation").value = "drawCluster();";
Элементы.Эксплорер.document.getElementById("WebClient").click();
КонецПроцедуры
&НаКлиенте
Процедура ОчиститьВсе(Команда)
ОчисткаКарты();
ТаблицаТочек.Очистить();
КонецПроцедуры
&НаКлиенте
Процедура ОчиститьКарту(Команда)
ОчисткаКарты();
КонецПроцедуры
&НаКлиенте
Процедура ОчиститьТаблицу(Команда)
ТаблицаТочек.Очистить();
КонецПроцедуры
&НаКлиенте
//Процедура получает координаты установленной точки
Процедура ПолучитьКоординаты()
Попытка
ЧислоТип = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 12));
КоординатаX = Элементы.Эксплорер.document.getElementById("CoordX").value;
КоординатаX = ЧислоТип.ПривестиЗначение(КоординатаX);
КоординатаY = Элементы.Эксплорер.document.getElementById("CoordY").value;
КоординатаY = ЧислоТип.ПривестиЗначение(КоординатаY);
Кол = ТаблицаТочек.Количество();
Если КоординатаX > 0 И КоординатаY > 0 И (Кол = 0 Или КоординатаX <> ТаблицаТочек[Кол - 1].Широта И КоординатаY <> ТаблицаТочек[Кол - 1].Долгота) Тогда
НоваяСтрока = ТаблицаТочек.Добавить();
НоваяСтрока.Точка = "Точка" + ТаблицаТочек.Количество();
НоваяСтрока.Широта = КоординатаX;
НоваяСтрока.Долгота = КоординатаY;
КонецЕсли;
Исключение
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура ПострениеПолигона(Команда)
Если ТаблицаТочек.Количество() <= 1 Тогда
Предупреждение("Недостаточно точек для построение полигона!");
Возврат;
КонецЕсли;
ОчисткаКарты();
ПостроитьПолигон();
КонецПроцедуры
&НаКлиенте
//Процедура выстраивает маршрут для Рамблера
//
//Параметры:
//
Процедура ПостроитьПолигон()
МассивТочек = "[";
Для Каждого ТекТочка Из ТаблицаТочек Цикл
Широта = формат(ТекТочка.Широта, "ЧРД=.");
Долгота = формат(ТекТочка.Долгота, "ЧРД=.");
МассивТочек = МассивТочек + "[" + Широта + "," + Долгота + "],";
КонецЦикла;
МассивТочек = Сред(МассивТочек, 1, СтрДлина(МассивТочек) - 1) + "]";
Цвет16 = Получить16Цвет();
Название = "Полигон";//вставить свое
Элементы.Эксплорер.document.getElementById("WebClientOperation").value = "createPolygon(" + МассивТочек + ", '" + Название + "', '" + Цвет16 + "');";
Элементы.Эксплорер.document.getElementById("WebClient").click();
КонецПроцедуры
&НаСервере
//Функция возвращает значение случайного цвета в 16-ричном формате
//
//Параметры:
// нет
//Возвращаемое значение:
// Строка
Функция Получить16Цвет()
Результат = "";
Строка16 = "0123456789ABCDEF";
ГСЧ = Новый ГенераторСлучайныхЧисел;
Результат = "#";
Для н = 1 По 6 Цикл
м = ГСЧ.СлучайноеЧисло(1, 16);
Результат = Результат + Сред(Строка16, м, 1);
КонецЦикла;
Возврат Результат;
КонецФункции
Категория:
COM-объекты, WMI, WSH