Функции сохранения таблицы значений в файл и чтения из файла В данном примере хочу привести несколько универсальных функций по выгрузке таблицы значений в файл и дальнейшего чтения из файла:
П орядок программных действий при выгрузке в файл выглядит так:
Подготавливаем таблицу значений (выгружаем из табличной части, выбираем колонки); Конвертируем таблицу значений в табличный документ; Сохраняем табличный документ в 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","Администратор","Администратор");
Источник
Категория:
Администрирование Яндекс карта : вывод точек на карту Пример о том,как вывести яндекс карту на форму и далее работать с ней:
Основной HTML код карты хранится в макете:
Код VBS <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Примеры. Геокодирование.</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="http://api-maps.yandex.ru/1.1/index.xml?key=ANpUFEkFAAAAf7jmJwMAHGZHrcLKDsbEqEVjEUtCmufxQMwAAAAAAAAAAAAvVrubVT4btztbduoIgTLAeFILaQ==" type="text/javascript"></script>
<script type="text/javascript">
var router;
var myPoints = new Array();
var myRouts = new Array();
var strOpen = "OPEN";
var strKontr = "Kontragent";
var t = new YMaps.Template('<b>$[name]</b><div id="descrID" >$[description]</div>');
YMaps.Templates.add("my#template", t);
var KopdinatShirota = 0;
var KopdinatDolgota = 0;
var UID_Zakaza = "";
/*vstavkaStiley;
var map, geoResult;
YMaps.jQuery(function () {
map = new YMaps.Map(YMaps.jQuery("#YMapsID")[0]);
map.setCenter(new YMaps.GeoPoint(37.62, 55.75), 12);
});
function showAddress (value, contrag, Styles, UID) {
var geocoder = new YMaps.Geocoder(value, {results: 1, boundedBy: map.getBounds()});
YMaps.Events.observe(geocoder, geocoder.Events.Load, function () {
if (this.length()) {
geoResult = this.get(0);
var point = new YMaps.GeoPoint(geoResult._point.__lng, geoResult._point.__lat);
var placemark = new YMaps.Placemark(point, {style: Styles});
placemark.name = UID;
placemark.description = contrag;
myPoints.push(placemark);
map.addOverlay(placemark);
return placemark;
}else {
}
});
YMaps.Events.observe(geocoder, geocoder.Events.Fault, function (geocoder, error) {
alert("Произошла ошибка: " + error);
return null;
})
}
function showAddressCoord (shirota, dolgota, contrag, Styles, UID) {
var point = new YMaps.GeoPoint(dolgota, shirota);
var placemark = new YMaps.Placemark(point, {style: Styles});
placemark.name = UID;
placemark.description = contrag;
myPoints.push(placemark);
map.addOverlay(placemark);
return placemark;
}
function removeAllOverlays (map) {
map.removeAllOverlays();
}
function AddRoute(wayPoint1, wayPoint2) {
if (myRouts.length>0) {lastRouter = myRouts[myRouts.length-1]; map.removeOverlay(lastRouter)};
var myRouter = new YMaps.Router([wayPoint1, wayPoint2], [], {viewAutoApply: true});
map.addOverlay(myRouter);
YMaps.Events.observe(myRouter, myRouter.Events.Success, function (myRouter) {
myRouter.getWayPoint(0).setIconContent('Начало маршрута');
myRouter.getWayPoint(1).setIconContent('Конец маршрута');
dlMar = myRouter.getDistance()/1000;
document.title = 'Дистанция: '+ dlMar.toFixed(2);
});
myRouts.push(myRouter);
return true;
}
function mapRazmer(map, SentrSh, SentrDlg, razmer) {
map.setCenter(new YMaps.GeoPoint(SentrSh, SentrDlg), razmer);
}
function changeStyle(numTochki, imStyle){
var restoreDefault = true;
tochka = myPoints[numTochki];
tochka.setOptions({style: imStyle}, restoreDefault);
point = tochka.getCoordPoint();
map.setCenter(new YMaps.GeoPoint(point.__lng, point.__lat), 12);
map.redraw();
return tochka.description;
}
</script>
</head>
<body //~~onload~~>
<div id="YMapsID" style="width:100%;height:100%"></div>
</form>
</body>
</html>
Код вывода карты:
Код 1C v 8.х //берем HTML-текст из макета и доделываем его
//создаем столько стилей, сколько есть различных картинок в папке "icons_"
//Загружаем в поле HTML-документа
//и позиционируем центр карты на Москву
Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)
Макет = ПолучитьМакет("Макет");
КодХТМЛ = Макет.ПолучитьТекст();
СтрокаСтиляНачальная = "var BurG = new YMaps.Style();
|BurG.iconStyle = new YMaps.IconStyle();
|BurG.iconStyle.offset = new YMaps.Point(-12, -12);
|BurG.iconStyle.href = ""http://www.burgerking.ru/favicon.ico"";
|BurG.iconStyle.size = new YMaps.Point(20, 20);
|BurG.hideIcon = false;
|BurG.balloonContentStyle = new YMaps.BalloonContentStyle(""my#template"");";
СтрокаСтиляИтоговая = "";
//
//имяКаталогаКартинок = "D:\!1C\MAPS\icons_";
//КаталогКартинок = Новый Файл(имяКаталогаКартинок);
//Если КаталогКартинок.ЭтоКаталог() тогда
// списокИменКартинок = новый таблицаЗначений;
// списокИменКартинок.Колонки.Добавить("ИмяСтиля");
// списокИменКартинок.Колонки.Добавить("ИмяФайлаКартинки");
// МассивНайденных = НайтиФайлы(имяКаталогаКартинок, "*.gif");
// Для Каждого Файл из МассивНайденных Цикл
//
// времСтрокаСтиля = СтрокаСтиляНачальная;
// времСтрокаСтиля = стрЗаменить(времСтрокаСтиля, "BurG", сокрЛП(Файл.ИмяБезРасширения));
// времСтрокаСтиля = стрЗаменить(времСтрокаСтиля, "C:/icons_/kv2_5_x.gif", "C:/icons_/" + сокрЛП(Файл.Имя));
//
// СтрокаСтиляИтоговая = СтрокаСтиляИтоговая + времСтрокаСтиля + символы.ПС;
//
// КонецЦикла;
//конецЕсли;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВидыОбъектов.Ссылка,
| ВидыОбъектов.ПутьКИконке,
| ВидыОбъектов.Код
|ИЗ
| Справочник.ВидыОбъектов КАК ВидыОбъектов
|ГДЕ
| ВидыОбъектов.ПометкаУдаления = ЛОЖЬ";
Результат = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = Результат.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
времСтрокаСтиля = СтрокаСтиляНачальная;
времСтрокаСтиля = стрЗаменить(времСтрокаСтиля, "BurG", "s"+Строка(ВыборкаДетальныеЗаписи.код));
времСтрокаСтиля = стрЗаменить(времСтрокаСтиля, "http://www.burgerking.ru/favicon.ico", сокрЛП(ВыборкаДетальныеЗаписи.ПутьКИконке));
СтрокаСтиляИтоговая = СтрокаСтиляИтоговая + времСтрокаСтиля + символы.ПС;
КонецЦикла;
СтрокаСтиляИтоговая = СтрокаСтиляИтоговая + СтрокаСтиляНачальная + символы.ПС;
КодХТМЛ = стрЗаменить(КодХТМЛ, "/*vstavkaStiley;", СтрокаСтиляИтоговая);
путьККаталогуКартинок = СтрЗаменить(КаталогПрограммы(), "\", "/");
КодХТМЛ = СтрЗаменить(КодХТМЛ,"C:/",путьККаталогуКартинок);
ЭлементыФормы.Карта.УстановитьТекст(КодХТМЛ);
табАдресов = получитьтабАдресов();
табУникальныхАдресов = табАдресов.скопировать();
табУникальныхАдресов.свернуть("Уник");
тзДанных = табАдресов.скопировать();
табАдресов.очистить();
Для Каждого стр из табУникальныхАдресов Цикл
Отбор = Новый Структура();
Отбор.Вставить("Уник",стр.Уник);
Строки = тзДанных.НайтиСтроки(Отбор);
НовСтр = табАдресов.добавить();
НовСтр.уник = стр.уник;
Если Строки.Количество() > 0 Тогда
для Каждого тздстр из Строки Цикл
НовСтр.Адрес = тздстр.Адрес;
НовСтр.КД = тздстр.КД;
НовСтр.КШ = тздстр.КШ;
НовСтр.ВидОбъекта = тздстр.ВидОбъекта;
НовСтр.Наименование=Строка(НовСтр.Наименование)+Строка(тздстр.Наименование)+"; ";
КонецЦикла;
КонецЕсли;
КонецЦикла;
ЭлементыФормы.табАдресов.СоздатьКолонки();
ВыборМасштаба = "50%";
ВыборРегиона = "Москва";
ЭлементыФормы.Надпись24.Заголовок = "Точек: "+Строка(табАдресов.количество());
КонецПроцедуры
// Вывод точек на карту
Процедура ОсновныеДействияФормыОсновныеДействияФормыВыполнить(Кнопка)
//имя стиля совпадает с именем картинки без расширения
Всего=Строка(табАдресов.Количество()); н=0;
Для каждого строкаАдреса Из табАдресов Цикл
н=н+1; Состояние("Вывод "+Строка(н)+" из "+Всего);
////ЭТО ПРИМЕР ВЫВОДА ТОГО ИЛИ ИНОГО МАРКЕРА В ЗАВИСИМОСТИ ОТ НЕКОЕГО ПАРАМЕТРА
//Если строкаАдреса.ДокументПродажи.суммаДокумента <1000 тогда
// имяСтиля = "BurG";
//ИначеЕсли строкаАдреса.ДокументПродажи.суммаДокумента <10000 тогда
// имяСтиля = "tr2_3_x";
//ИначеЕсли строкаАдреса.ДокументПродажи.суммаДокумента <20000 тогда
// имяСтиля = "kv3_4_x";
//ИначеЕсли строкаАдреса.ДокументПродажи.суммаДокумента <50000 тогда
// имяСтиля = "tr4_1_x";
//ИначеЕсли строкаАдреса.ДокументПродажи.суммаДокумента <100000 тогда
// имяСтиля = "kv5_2_x";
//Иначе
// имяСтиля = "cr6_3_x";
//конецЕсли;
УИД_Дока = Строка(н);
имяСтиля = "s"+Строка(строкаАдреса.ВидОбъекта.код);
Попытка
Если ЗначениеЗаполнено(строкаАдреса.КД) Тогда
ВызовФункции = "showAddressCoord(" + сокрЛП(строкаАдреса.КШ) + ", " + сокрЛП(строкаАдреса.КД) + ", '"+ сокрЛП(строкаАдреса.адрес) + "', " + имяСтиля + ", '" + сокрЛП(строкаАдреса.ВидОбъекта.наименование) + "')";
Иначе
ВызовФункции = "showAddress('" + сокрЛП(строкаАдреса.адрес) + "', '" + сокрЛП(строкаАдреса.адрес) + "', " + имяСтиля + ", '" + сокрЛП(строкаАдреса.ВидОбъекта.наименование) + "')";
КонецЕсли;
ЭлементыФормы.Карта.Document.parentWindow.eval(ВызовФункции);
исключение
Сообщить("Точка с адресом " + сокрЛП(строкаАдреса.адрес) + " не может быть отбражена на карте!" );
конецПопытки
КонецЦикла;
ТочкиНеСозданы = Ложь;
ЭлементыФормы.Карта.ПолучитьТекст();
КонецПроцедуры
//Изменение масштаба
Процедура Кнопка1Нажатие(Элемент)
если ЭлементыФормы.ВыборРегиона.значение = "Москва" Тогда
СтрокаКоординат = "37.64, 55.76, ";
ИначеЕсли ЭлементыФормы.ВыборРегиона.значение = "Тверь" Тогда
СтрокаКоординат = "35.90, 56.83, ";
ИначеЕсли ЭлементыФормы.ВыборРегиона.значение = "Балашиха" Тогда
СтрокаКоординат = "37.97, 55.82, ";
Иначе
СтрокаКоординат = "37.64, 55.76, ";
конецесли;
Если ВыборМасштаба = "" тогда
возврат;
конецесли;
числоМасштаба = Число(Лев(ВыборМасштаба, стрдлина(ВыборМасштаба)-1));
числоМасштаба = числоМасштаба + 5;
ВыборМасштаба = строка(числоМасштаба) + "%";
ТекущийМасштаб = Строка(Цел((числоМасштаба/125)*(20)+4));
если стрДлина(ТекущийМасштаб) =1 тогда
ТекущийМасштаб = "0" + ТекущийМасштаб;
конецесли;
ЭлементыФормы.Карта.Document.parentWindow.eval("mapRazmer(map," + СтрокаКоординат + ТекущийМасштаб + ")");
КонецПроцедуры
Пример обратного геокодирования - получение координат по адресу:
Код 1C v 8.х Процедура ПолучитьКоординаты() Экспорт
Яндекс = Новый HTTPСоединение("geocode-maps.yandex.ru",,,,,Истина);
ВременныйФайл = КаталогВременныхФайлов() + "Yandex_geocode_" + СокрЛП(Новый УникальныйИдентификатор);
Попытка
Яндекс.Получить("/1.x/?geocode=" + Адрес + "&results=1", ВременныйФайл);
Исключение
Сообщить("Ошибка при попытке геокодировать по яндексу адрес: " + Адрес);
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ВременныйФайл);
ПостроительDOM = Новый ПостроительDOM;
ДокументДОМ = ПостроительDOM.Прочитать(ЧтениеXML);
СписокText = ДокументДОМ.ПолучитьЭлементыПоИмени("text");
СписокPos = ДокументДОМ.ПолучитьЭлементыПоИмени("pos");
Если (СписокText.Количество() = 0) ИЛИ (СписокPos.Количество() = 0) Тогда
Возврат;
КонецЕсли;
Для ъ = 0 по СписокText.Количество()-1 Цикл
Координаты = СписокPos[Ъ].ТекстовоеСодержимое;
Разделитель = Найти(Координаты," ");
Широта = Число(Сред(Координаты, Разделитель + 1));
Долгота = Число(Лев(Координаты, Разделитель - 1));
Если Широта = 0 ИЛИ Долгота = 0 Тогда
Продолжить;
КонецЕсли;
КД = Долгота;
КШ = Широта;
КонецЦикла;
КонецПроцедуры
Обработка вырванная из конфигурации: YandexMap.rar
Можно ее использовать как макет для создания обработки под свои требования.
Пример автоматизации в котором это использовалось.
Категория:
Географическая схема Функции для работы с 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);
КонецЕсли;
Возврат Результат;
КонецФункции
Категория:
Работа с Файлами и Каталогами Обмен данными с сайтом используя формат JSON в 1С Формат JSON в 1С до версии 8.3.6 не реализован, но нижет я приведу примеры функций которые можно использовать для полноценной работы JSON в 1С предыдущий версий.
JSON (JavaScript Object Notation) это текстовый формат обмена данными, широко используемый в веб-приложениях. По сравнению с XML он является более лаконичным и занимает меньше места. Кроме этого все браузеры имеют встроенные средства для работы с JSON.
Необходимость работы с этим форматом на уровне платформы обусловлена не только тем, что это «модный современный» формат, который прикладные решения 1С:Предприятия сами по себе могут использовать для интеграции со сторонними приложениями. Другая причина заключается ещё и в том, что JSON активно используется в HTTP интерфейсах. А в 1С:Предприятии как раз есть такие механизмы, в которых хочется использовать этот формат. Это REST интерфейс приложения, автоматически генерируемый платформой, и HTTP-сервисы, которые вы можете создавать самостоятельно.
В платформе с версии 8.3.6: Потоковое чтение и запись JSON:
Объекты потоковой работы - это общие объекты ЧтениеJSON и ЗаписьJSON. Они последовательно читают JSON из файла или строки, или последовательно записывают JSON в файл или строку. Таким образом, чтение и запись JSON происходят без формирования всего документа в памяти.
В качестве иллюстрации потокового чтения JSON можно привести следующий пример:
Код 1C v 8.3 // Пример чтения JSON.
ЧтениеJSON = Новый ЧтениеJSON;
// Либо открыть файл, из которого будет выполняться чтение, // либо установить строку, из которой будет выполняться чтение.
ЧтениеJSON.ОткрытьФайл("ИмяФайла");
//ЧтениеJSON.УстановитьСтроку("СтрокаJSON");
Пока ЧтениеJSON.Прочитать() Цикл
TипJSON = ЧтениеJSON.ТипТекущегоЗначения;
Если TипJSON = ТипЗначенияJSON.Число ИЛИ TипJSON = ТипЗначенияJSON.Строка ИЛИ TипJSON = ТипЗначенияJSON.Булево ИЛИ TипJSON = ТипЗначенияJSON.Null Тогда
// Обработать значение
Значение = ЧтениеJSON.ТекущееЗначение;
ИначеЕсли ТипJSON = ТипЗначенияJSON.Комментарий Тогда
// Обработать комментарий
Комментарий = ЧтениеJSON.ТекущееЗначение;
ИначеЕсли TипJSON = ТипЗначенияJSON.ИмяСвойства Тогда
// Обработать имя свойства
ИмяСвойства = ЧтениеJSON.ТекущееЗначение;
ИначеЕсли TипJSON = ТипЗначенияJSON.НачалоМассива ИЛИ TипJSON = ТипЗначенияJSON.КонецМассива ИЛИ TипJSON = ТипЗначенияJSON.НачалоОбъекта ИЛИ TипJSON = ТипЗначенияJSON.КонецОбъекта ИЛИ TипJSON = ТипЗначенияJSON.Ничего Тогда
// Обработать начало/коней массива/объекта или отсутствие данных, // ТекущееЗначение читать не нужно.
КонеиЕсли;
КокецЦикла;
ЧтениеJSON.Закрыть();
// При записи JSON вы самостоятельно формируете его структуру. Чтобы «подстраховать» вас от ошибок, объект ЗаписьJSON автоматически проверяет правильность записываемой структуры.
// Для увеличения скорости работы эту проверку можно отключить. В примере ниже это строка:
ЗаписьJSON.ПроверятьСтруктуру = Ложь;
// Также при записи вы можете управлять некоторыми параметрами формируемого текста, например использованием двойных кавычек, переносом строк, символами отступа и экранированием символов.
// В примере ниже для форматирования текста используется символ табуляции:
ПараметрыЗаписиJSON = Новый ПараметрыЗаписиJSON( , Символы.Таб) ;
ЗаписьJSON.ОткрытьФайл("ИмяФайла", , , ПараметрыЗаписиJSON);
// Потоковая запись JSON может выглядеть следующим образом. Записывается массив из четырёх элементов. Три из них примитивного типа, а четвёртый элемент - это объект с двумя свойствами:
// Пример записи JSON. ЗаписьJSON = Новый ЗаписьJSON;
// Для увеличения скорости работы можно отключить автоматическую проверку // правильности структуры записываемого документа JSON. ЗаписьиЗСЖ.ПроверятьСтруктуру = Ложь;
// Для красоты результирующего текста можно увеличить "лесенку".
// Стандартный отступ - 1 пробел.
ПараметрыЗаписиJSON = Новый ПараметрыЗаписиJSON( , Символы.Таб);
// Либо открыть файл, в который будет выполнена запись,
// либо указать, что запись будет выполнена в строку, которую вернет метод Закрыть().
ЗаписьJSON.ОткрытьФайл("ИмяФайла", , , ПараметрыЗаписиJSON);
//ЗаписьJSON.УстановитьСтроку(ПараметрыЗаписиJSON);
// Записать массив.
ЗаписьJSON.ЗаписатьНачалоОбъекта();
ЗаписьJSON.ЗаписатьИмяСвойства("СвойствоТипаМассив");
ЗаписьJSON.ЗаписатьНачалоМассива();
// Первый элемент массива - Строка. ЗаписьJSON.ЗаписатьЗначение("Значение строка");
// Второй элемент массива - Число. ЗаписьJSON.ЗаписатьЗначение(12.345, Истина);
// Третий элемент массива - Булево. ЗаписьJSON-ЗаписатьЗначение(Истина);
// Четвертый элемент массива - объект с двумя свойствами. ЗаписьJSON.ЗаписатьНачалоОбъекта();
// Первое свойство объекта - Строка
ЗаписьJSON.ЗаписатьИмяСвойства("СвойствоТипаСтрока");
ЗаписьJSON.ЗаписатьЗначение("Значение строка");
// Второе свойство объекта - Неопределено
ЗаписьJSON.ЗаписатьИмяСвойства("СвойствоТипаНеопределено");
ЗаписьJSON.ЗаписатьЗначение(Неопределено);
ЗаписьJSON.ЗаписатьКонецОбъекта();
Запись JSON. ЗаписатьКонецМассива () ;
ЗаписьJSON.ЗаписатьКонецОбъекта();
ЗаписьJSON.Закрыть();
//CTpoKaJSON = ЗаписьJSON.Закрыть();
Результат такой записи:
Код 1C v 8.х
{
"СвойствоТипаМассив": [
"Значение строка",
1.2345E1,
true,
{
"СвойствоТипаСтрока": "Значение строка",
"СвойствоТипаНеопределено": null
}
]
}
Сериализация примитивных типов и коллекций в JSON
Вторая группа средств работы с JSON хороша тем, что избавляет вас от рутинной работы по чтению/записи каждого отдельного значения или свойства. При чтении документы JSON отображаются в фиксированный набор типов платформы: Строка, Число, Булево, Неопределено, Массив, ФиксированныйМассив, Структура, ФиксированнаяСтруктура, Соответствие, Дата. Соответственно, в обратную сторону, композиция объектов этих типов позволяет сформировать в памяти и быстро записать в файл структуру JSON. Таким образом, чтение и запись небольшого объема JSON заранее известной структуры можно производить немногими строчками кода.
Основное назначение этих средств мы видим в обмене информацией с внешними системами, чтении конфигурационных файлов в формате JSON.
Сериализацию вы можете выполнять с помощью методов глобального контекста ПрочитатьJSON() и ЗаписатьJSON(). Они работают в связке с объектами ЧтениеJSON и ЗаписьJSON.
В качестве примера десериализации JSON можно рассмотреть чтение массива из двух объектов:
Код 1C v 8.3 // В качестве примера десериализации JSON можно рассмотреть чтение массива из двух объектов:
[
{
"имя": "Anton",
"фамилия": "Иванов",
"возраст": 25
},
{
"имя": "Ирина",
"фамилия": "Иванова",
"возраст": 20
}
]
// Код 1С:Предприятия, выполняющий десериализацию, может выглядеть следующим образом:
// Пример чтения JSON.
ЧтениеJSON = Новый ЧтениеJSON();
ЧтениеJSON.ОткрытьФайл("ИмяФайла");
Сотрудники = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
Для каждого Сотрудник из Сотрудники Цикл
// Обработать данные сотрудника.
ИмяСотрудника = Сотрудник.имя; ФамилияСотрудника = Сотрудник.фамилия; ВозрастСотрудника = Сотрудник.возраст;
КонецЦикла;
// А пример сериализации (записи) в JSON может выглядеть так:
// Пример записи JSON
Структура = Новый Структура;
Вставить("Фамилия","Иванов");
Зставить("Имя", "Иван");
Вставить("Отчество", "Иванович");
Зставить("Возраст", 40) ;
Зставить("Женат", Истина);
Телефоны = Новый Массив;
Телефоны.Добавить("8-999-999-99-90") ;
Телефоны.Добавить("8-999-999-99-91") ;
Структура.Вставить("Телефоны", Телефены);
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.ОткрытьФайл("ИмяФайла", , , Новый ПapaмeтpыЗaпиcиJS0N( , Символы.Таб) ) ;
ЗаписатьJSON(ЗаписьJSON, Структура);
ЗаписьJSON.Закрыть();
// Результат записи:
{
"Фамилия": "Иванов",
"Имя": "Иван",
"Отчество": "Иванович",
"Возраст": 40,
"Женат": true,
"Телефоны": [
"8-999-999-99-90",
"8-999-999-99-91"
]
}
Подробнее вы можете посмотреть здесь
В платформе с версии 8.3.7: Полностью автоматизировали работу с JSON и реализовали в платформе третью группу средств. Они позволяют сериализовать в JSON прикладные типы 1С:Предприятия: ссылки, объекты, наборы записей и вообще любые типы, для которых поддерживается XDTO сериализация. Конечно же, мы обеспечили и обратную операцию - десериализацию. Зачем это нужно!?
Прежде всего, и в основном, XDTO сериализацию в JSON мы рекомендуем использовать при обмене данными между двумя прикладными решениями 1С:Предприятия. По сравнению с XML формат JSON более компактный, сериализация/десериализация в/из JSON выполняется быстрее. Кроме этого мы предприняли дополнительные меры для того, чтобы сократить объём передаваемых данных.
Кроме обмена между приложениями 1С:Предприятия этот механизм можно использовать и для обмена с внешними системами, готовыми принимать типы данных 1С:Предприятия. Например, XDTO сериализацию в JSON можно использовать для организации собственного HTTP интерфейса прикладного решения. Сервис на платформе 1С:Предприятия будет формировать ответ в памяти в виде строки JSON. А затем передавать её при помощи объекта HTTPСервисОтвет. Реализованный нами механизм сериализации полностью соответствует стандарту JSON. Поэтому внешняя система не должна испытывать каких-либо трудностей с десериализацией.
Использование XDTO сериализации в JSON для других задач видится нам маловероятным. Потому что если внешняя система не готова работать с прикладными типами 1С:Предприятия, то зачем их ей передавать? А если предполагается обмениваться только примитивными типами и коллекциями, то для этой задачи хорошо подходят методы ПрочитатьJSON() и ЗаписатьJSON(). Подробнее здесь
ДО платформы версии 8.3.6, т.е. 8.3.5 и ниже: На HelpF уже есть статья где описан пример: Работа с форматом JSON в 1С но не приведены функции, вот они:
Код 1C v 8.х Функция ПреобразоватьвСистему(Число10,система) Экспорт
Если система > 36 или система < 2 тогда
Сообщить("Выбранная система исчисления не поддерживается");
Возврат -1;
КонецЕсли;
СтрокаЗначений = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
СтрокаСистема = "";
Пока Число10 > 0 цикл
РезДеления = Число10/система;
ЧислоСистема = цел(РезДеления);
остатокОтДеления = Число10 - система*(ЧислоСистема);
СтрокаСистема = сред(СтрокаЗначений,остатокОтДеления+1,1)+ СтрокаСистема;
Число10 = ?(ЧислоСистема=0,0,РезДеления);
КонецЦикла;
Нечётное = стрДлина(СтрокаСистема) - цел(стрДлина(СтрокаСистема)/2)*2;
Если Нечётное тогда
СтрокаСистема = "0"+СтрокаСистема;
КонецЕсли;
Возврат СтрокаСистема;
КонецФункции
Функция URLEncode(стр) Экспорт
Длина=СтрДлина(Стр);
Итог="";
Для Н=1 По Длина Цикл
Знак=Сред(Стр,Н,1);
Код=КодСимвола(Знак);
если ((Знак>="a")и(Знак<="z")) или
((Знак>="A")и(Знак<="Z")) или
((Знак>="0")и(Знак<="9")) тогда
Итог=Итог+Знак;
Иначе
Если (Код>=КодСимвола("А"))И(Код<=КодСимвола("п")) Тогда
Итог=Итог+"%"+ПреобразоватьвСистему(208,16)+"%"+ПреобразоватьвСистему(144+Код-КодСимвола("А"),16);
ИначеЕсли (Код>=КодСимвола("р"))И(Код<=КодСимвола("я")) Тогда
Итог=Итог+"%"+ПреобразоватьвСистему(209,16)+"%"+ПреобразоватьвСистему(128+Код-КодСимвола("р"),16);
ИначеЕсли (Знак="ё") Тогда
Итог=Итог+"%"+ПреобразоватьвСистему(209,16)+"%"+ПреобразоватьвСистему(145,16);
ИначеЕсли (Знак="Ё") Тогда
Итог=Итог+"%"+ПреобразоватьвСистему(208,16)+"%"+ПреобразоватьвСистему(129,16);
Иначе
Итог=Итог+"%"+ПреобразоватьвСистему(Код,16);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат Итог;
КонецФункции
Функция СформироватьСтрокуJSONИзМассива(Объект)
СтрокаJSON = "[";
Для каждого Элемент Из Объект Цикл
Если ТипЗнч(Элемент) = Тип("Строка") Тогда
СтрокаJSON = СтрокаJSON + """" + Элемент + """";
ИначеЕсли ТипЗнч(Элемент) = Тип("Число") Тогда
СтрокаJSON = СтрокаJSON + СтрЗаменить(Строка(Элемент), Символы.НПП, "");
ИначеЕсли ТипЗнч(Элемент) = Тип("Булево") Тогда
СтрокаJSON = СтрокаJSON + Формат(Элемент, "БЛ=false; БИ=true");
ИначеЕсли ТипЗнч(Элемент) = Тип("Дата") Тогда
СтрокаJSON = СтрокаJSON + Формат(Элемент - Дата(1970,1,1,1,0,0), "ЧГ=0");
ИначеЕсли ТипЗнч(Элемент) = Тип("Массив") Тогда
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON(Элемент);
ИначеЕсли ТипЗнч(Элемент) = Тип("Структура") Тогда
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON(Элемент);
ИначеЕсли ТипЗнч(Элемент) = Тип("ТаблицаЗначений") Тогда
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON(Элемент);
Иначе
СтрокаJSON = СтрокаJSON + """" + URLEncode(Строка(Элемент)) + """";
КонецЕсли;
СтрокаJSON = СтрокаJSON + ",";
КонецЦикла;
Если Прав(СтрокаJSON, 1) = "," Тогда
СтрокаJSON = Лев(СтрокаJSON, СтрДлина(СтрокаJSON)-1);
КонецЕсли;
Возврат СтрокаJSON + "]";
КонецФункции
Функция СформироватьСтрокуJSONИзСтруктуры(Объект)
СтрокаJSON = "{";
Для каждого Элемент Из Объект Цикл
Если Элемент.Значение = "" Тогда
Продолжить;
КонецЕсли;
СтрокаJSON = СтрокаJSON + """" + Элемент.Ключ + """" + ":";
Если ТипЗнч(Элемент.Значение) = Тип("Строка") Тогда
СтрокаJSON = СтрокаJSON + """" + Элемент.Значение + """";
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("Число") Тогда
СтрокаJSON = СтрокаJSON + СтрЗаменить(Строка(Элемент.Значение), Символы.НПП, "");
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("Булево") Тогда
СтрокаJSON = СтрокаJSON + Формат(Элемент.Значение, "БЛ=false; БИ=true");
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("Дата") Тогда
СтрокаJSON = СтрокаJSON + Формат(Элемент.Значение - Дата(1970,1,1,1,0,0), "ЧГ=0");
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("Массив") Тогда
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON(Элемент.Значение);
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("Структура") Тогда
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON(Элемент.Значение);
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("ТаблицаЗначений") Тогда
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON(Элемент.Значение);
Иначе
СтрокаJSON = СтрокаJSON + """" + URLEncode(Строка(Элемент.Значение)) + """";
КонецЕсли;
СтрокаJSON = СтрокаJSON + ",";
КонецЦикла;
Если Прав(СтрокаJSON, 1) = "," Тогда
СтрокаJSON = Лев(СтрокаJSON, СтрДлина(СтрокаJSON)-1);
КонецЕсли;
Возврат СтрокаJSON + "}";
КонецФункции
Функция СформироватьСтрокуJSON(Объект) Экспорт
СтрокаJSON = "";
Если ТипЗнч(Объект) = Тип("Массив") Тогда
СтрокаJSON = СформироватьСтрокуJSONИзМассива(Объект);
ИначеЕсли ТипЗнч(Объект) = Тип("Структура") Тогда
СтрокаJSON = СформироватьСтрокуJSONИзСтруктуры(Объект);
ИначеЕсли ТипЗнч(Объект) = Тип("ТаблицаЗначений") Тогда
СоставСтруктуры = "";
Для каждого Колонка Из Объект.Колонки Цикл
СоставСтруктуры = СоставСтруктуры + ?(ЗначениеЗаполнено(СоставСтруктуры), ",", "") + Колонка.Имя;
КонецЦикла;
МассивСтрок = Новый Массив;
Для каждого Строка Из Объект Цикл
СтруктураКолонок = Новый Структура(СоставСтруктуры);
ЗаполнитьЗначенияСвойств(СтруктураКолонок, Строка);
МассивСтрок.Добавить(СтруктураКолонок);
КонецЦикла;
СтрокаJSON = СформироватьСтрокуJSONИзМассива(МассивСтрок);
КонецЕсли;
Возврат СтрокаJSON;
КонецФункции
Процедура ЗаполнитьДанныеИзОтветаJSON(Результат, ТекстJSON, ТипДанных)
ТекстJSON = СокрЛП(Сред(ТекстJSON, 2));
НомерЗначения = 0;
Пока ТекстJSON <> "" Цикл
ПервыйСимвол = Лев(ТекстJSON, 1);
Если ПервыйСимвол = "{" Тогда
Значение = Новый Структура;
ЗаполнитьДанныеИзОтветаJSON(Значение, ТекстJSON, "Структура");
Если ТипДанных = "Структура" Тогда
Результат.Вставить("Значение" + ?(НомерЗначения = 0, "", НомерЗначения), Значение);
НомерЗначения = НомерЗначения + 1;
ИначеЕсли ТипДанных = "Массив" Тогда
Результат.Добавить(Значение);
КонецЕсли;
ИначеЕсли ПервыйСимвол = "[" Тогда
Значение = Новый Массив;
ЗаполнитьДанныеИзОтветаJSON(Значение, ТекстJSON, "Массив");
Если ТипДанных = "Структура" Тогда
Результат.Вставить("Значение" + ?(НомерЗначения = 0, "", НомерЗначения), Значение);
НомерЗначения = НомерЗначения + 1;
Иначе
Результат.Добавить(Значение);
КонецЕсли;
ИначеЕсли ПервыйСимвол = "}" И ТипДанных = "Структура" Тогда
ТекстJSON = СокрЛП(Сред(ТекстJSON, 2));
Если Лев(ТекстJSON, 1) = "," Тогда
ТекстJSON = СокрЛП(Сред(ТекстJSON, 2));
КонецЕсли;
Возврат;
ИначеЕсли ПервыйСимвол = "]" И ТипДанных = "Массив" Тогда
ТекстJSON = СокрЛП(Сред(ТекстJSON, 2));
Если Лев(ТекстJSON, 1) = "," Тогда
ТекстJSON = СокрЛП(Сред(ТекстJSON, 2));
КонецЕсли;
Возврат;
Иначе
Если ТипДанных = "Структура" Тогда
Поз = Найти(ТекстJSON, ":");
Если Поз = 0 Тогда
Прервать;
КонецЕсли;
ИмяЗначения = СокрЛП(Лев(ТекстJSON, Поз-1));
ТекстJSON = СокрЛП(Сред(ТекстJSON, Поз+1));
Если Лев(ТекстJSON, 1) = "{" Тогда
Значение = Новый Структура;
ЗаполнитьДанныеИзОтветаJSON(Значение, ТекстJSON, "Структура");
ИначеЕсли Лев(ТекстJSON, 1) = "[" Тогда
Значение = Новый Массив;
ЗаполнитьДанныеИзОтветаJSON(Значение, ТекстJSON, "Массив");
Иначе
Поз = 0;
Для Сч = 1 По СтрДлина(ТекстJSON) Цикл
Символ = Сред(ТекстJSON, Сч, 1);
Если Символ = "," ИЛИ Символ = "]" ИЛИ Символ = "}" Тогда
Поз = Сч;
Прервать;
КонецЕсли;
КонецЦикла;
Если Поз = 0 Тогда
Значение = ТекстJSON;
ТекстJSON = "";
Иначе
Значение = Лев(ТекстJSON, Поз-1);
ТекстJSON = СокрЛП(Сред(ТекстJSON, Поз + ?(Сред(ТекстJSON, Поз, 1) = ",", 1, 0)));
КонецЕсли;
Значение = СокрЛП(Значение);
КонецЕсли;
Результат.Вставить(ИмяЗначения, Значение);
ИначеЕсли ТипДанных = "Массив" Тогда
Поз = 0;
Для Сч = 1 По СтрДлина(ТекстJSON) Цикл
Символ = Сред(ТекстJSON, Сч, 1);
Если Символ = "," ИЛИ Символ = "]" ИЛИ Символ = "}" Тогда
Поз = Сч;
Прервать;
КонецЕсли;
КонецЦикла;
Если Поз = 0 Тогда
Значение = ТекстJSON;
ТекстJSON = "";
Иначе
Значение = Лев(ТекстJSON, Поз-1);
ТекстJSON = СокрЛП(Сред(ТекстJSON, Поз + ?(Сред(ТекстJSON, Поз, 1) = ",", 1, 0)));
КонецЕсли;
Значение = СокрЛП(Значение);
Результат.Добавить(Значение);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция ЗаполнитьСтруктуруИзОтветаJSON(Знач ТекстJSON) Экспорт
Результат = Новый Структура;
ТекстJSON = СтрЗаменить(ТекстJSON, "\""", """");
ТекстJSON = СтрЗаменить(ТекстJSON, """", "");
Если Лев(ТекстJSON, 1) = "{" Тогда
ЗаполнитьДанныеИзОтветаJSON(Результат, ТекстJSON, "Структура");
ИначеЕсли Лев(ТекстJSON, 1) = "[" Тогда
МассивДанных = Новый Массив;
ЗаполнитьДанныеИзОтветаJSON(МассивДанных, ТекстJSON, "Массив");
Результат.Вставить("Значение", МассивДанных);
КонецЕсли;
Возврат Результат;
КонецФункции
Примеры их использования:
Код 1C v 8.х ////////////////////////////////////////////////////////
// преобразование простой структуры
Данные = Новый Структура("server,user,hash",
10234, 3745, "8263ad83ce");
СтрокаJSON = СформироватьСтрокуJSONИзСтруктуры(Данные);
// результатом будет строка
// {"server":"10234","user":"3745","hash":"8263ad83ce"}
////////////////////////////////////////////////////////
// преобразования массива
Данные = Новый Массив;
Данные.Добавить("Nissan");
Данные.Добавить("Ford");
Данные.Добавить("Audi");
СтрокаJSON = СформироватьСтрокуJSONИзСтруктуры(Данные);
// результатом будет строка
// ["Nissan","Ford","Audi"]
////////////////////////////////////////////////////////
// преобразование сложной структуры
Данные = Новый Структура;
Данные.Добавить("server", 10234);
Данные.Добавить("users", Новый Массив);
Данные.Добавить("hash", "8263ad83ce");
Данные.users.Добавить(3745);
Данные.users.Добавить(7462);
Данные.users.Добавить(2374);
СтрокаJSON = СформироватьСтрокуJSONИзСтруктуры(Данные);
// результатом будет строка
// {"server":"10234","users":["3745","7462","2374"],"hash":"8263ad83ce"}
////////////////////////////////////////////////////////
// еще один пример массива
Данные = Новый Структура;
Данные.Вставить("server", 10234);
Данные.Вставить("users", Новый Массив);
Данные.users.Добавить(Новый Структура("id,name", 3745, "Jack"));
Данные.users.Добавить(Новый Структура("id,name", 7246, "Nick"));
СтрокаJSON = СформироватьСтрокуJSONИзСтруктуры(Данные);
// результатом будет строка
// {"server":"10234","users":[{"id":"3745","name":"Jack"},{"id":"7462","name":"Nick"}>
////////////////////////////////////////////////////////
// преобразование таблицы значений
ТаблПользователей = Новый ТаблицаЗначений;
ТаблПользователей.Колонки.Добавить("id");
ТаблПользователей.Колонки.Добавить("name");
НоваяСтрока = ТаблПользователей.Добавить();
НоваяСтрока.id = 3276;
НоваяСтрока.name = "Jack";
НоваяСтрока = ТаблПользователей.Добавить();
НоваяСтрока.id = 3276;
НоваяСтрока.name = "Nick";
СтрокаJSON = СформироватьСтрокуJSONИзСтруктуры(Данные);
// результатом будет строка
// [{"id":"3745","name":"Jack"},{"id":"7462","name":"Nick"}]
Пишите комменты
Категория:
Работа с Интернет, Почтой (Mail), FTP Как мы писали парсер сайта с ценами для 1С Недавно, мой постоянный клиент решил проводить маркетинговые исследования по изменению цен на товары у конкурентов... и эти данные захотел использовать в 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 Загрузка данных в 1С из PDF В данной статье описан пример реализации загрузки данных накладных из PDF файлов для одного крупного Ритейла...
И так у Нас есть несколько файлов в формате pdf, которые нам необходимо загрузить в 1С.
Чтение PDF файлов из 1С
Первым дело я стал искать, как напрямую можно прочитать данные из 1С в PDF файлах - было найдено много информации и вариантов решений, но к сожалению большинство из них не правильно работали с кодировкой В результате банальный текст вида Красный стул превращался в страшную кракозябру.
Далее после долгих поисков был найден конвертер PDF в TXT - pdf2txt
Поддержка командной строки:
PDF2TXT <input PDF file> [output TXT file] [-logfile] [-open] [-space] [-html] [-format] [-silent] [-blankline] [-summary] [-zoom <num>] [-?] [-h]
<input PDF file> : Open an existing PDF file to convert.
[output TXT file] : Write to TEXT file, the default is same filename of input PDF file.
[-first <page number>]: Specify the first page number.
[-last <page number>]: Specify the last page number.
[-logfile] : Write log to "C:\pdf2txt.log" file.
[-open] : Auto open the text file after it be created.
[-space] : Auto insert spaces into text file.
[-html] : Output to a HTML file, not a text file.
[-format] : Keep the page layout in the generated TXT file.
[-silent] : Disable error and warning messages.
[-blankline] : Auto delete blank line in the generated TXT file.
[-summary] : Get PDF document summary.
[-zoom <num>] : Set zoom ratio, the range is from 50 to 200.
[-unicode] : Create UTF-8 encoding text file.
Примеры:
Код Batch File (DOS, CMD, BAT) C:\>PDF2TXT C:\input.pdf
C:\>PDF2TXT C:\input.pdf -unicode
C:\>PDF2TXT C:\input.pdf -first 10 -last 12
C:\>PDF2TXT C:\input.pdf C:\output.txt
C:\>PDF2TXT C:\input.pdf -open -silent -logfile -zoom 150
C:\>PDF2TXT C:\input.pdf C:\output.txt -open -silent
C:\>PDF2TXT C:\*.pdf
C:\>PDF2TXT C:\*.pdf C:\*.txt
C:\>PDF2TXT C:\test\*.pdf C:\test\*.txt
В архиве (Скачать Вы можете из статьи по ссылке ) заготовка 1С обработки для частного случая, если она Вам подойдет - Хорошо
Если же нет, то Мы можем для Вас быстро доработать загрузку PDF в 1С !
Код на 1С для конфигурации УТ 10.3:
Код 1C v 8.х Функция РазложитьСтрокуВМассивПодстрок(Знач Стр, Разделитель = ",") Экспорт
МассивСтрок = Новый Массив();
Если Разделитель = " " Тогда
Стр = СокрЛП(Стр);
Пока 1=1 Цикл
Поз = Найти(Стр,Разделитель);
Если Поз=0 Тогда
МассивСтрок.Добавить(Стр);
Возврат МассивСтрок;
КонецЕсли;
МассивСтрок.Добавить(Лев(Стр,Поз-1));
Стр = СокрЛ(Сред(Стр,Поз));
КонецЦикла;
Иначе
ДлинаРазделителя = СтрДлина(Разделитель);
Пока 1=1 Цикл
Поз = Найти(Стр,Разделитель);
Если Поз=0 Тогда
МассивСтрок.Добавить(Стр);
Возврат МассивСтрок;
КонецЕсли;
ТекЗнч = СокрЛП(Лев(Стр,Поз-1));
Если ЗначениеЗаполнено(ТекЗнч) Тогда
МассивСтрок.Добавить(ТекЗнч);
КонецЕсли;
Стр = Сред(Стр,Поз+ДлинаРазделителя);
КонецЦикла;
КонецЕсли;
КонецФункции
Процедура КнопкаВыполнитьНажатие(Кнопка)
//Ищем Файлы
тч.Очистить();
НайденныеФайлы = НайтиФайлы(ПутьКPDF,"*.pdf",ложь);
Для каждого стр Из НайденныеФайлы Цикл
Нстр = ТЧ.Добавить();
Нстр.ФайлPDF = стр.Имя;
КонецЦикла;
ЭтаФорма.Обновить();
//Преобразуем PDF в TXT
Для каждого стр Из ТЧ Цикл
Попытка
pdf = СокрЛП(ПутьКPDF+"\"+стр.ФайлPDF);
txt = СтрЗаменить(pdf,"pdf","txt");
Команд = ПутьКPDF2TXT+"\pdf2txt.exe "+pdf+" "+txt;
ЗапуститьПриложение(Команд,ПутьКPDF,Истина);
стр.ФайлTXT = txt;
Исключение
стр.ФайлTXT = "!!!_ОШИБКА";
КонецПопытки;
ЭлементыФормы.ТЧ.ТекущаяСтрока = стр;
ЭлементыФормы.ТЧ.ОбновитьСтроки(стр);
КонецЦикла;
мТекущийПользователь = глЗначениеПеременной("глТекущийПользователь");
мСкладПоУмолчанию = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(мТекущийПользователь, "ОсновнойСклад");
мОсновноеПодразделение = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(мТекущийПользователь, "ОсновноеПодразделение");
мОсновнаяВалютаВзаиморасчетов = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(мТекущийПользователь, "ОсновнаяВалютаВзаиморасчетов");
мОсновноеВедениеВзаиморасчетовПоДоговорам = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(мТекущийПользователь, "ОсновноеВедениеВзаиморасчетовПоДоговорам");
мВидНоменклатурыПоУмолчанию = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(мТекущийПользователь, "ОсновнойВидНоменклатуры");
мОтражатьВРеглУчете = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(мТекущийПользователь, "ОтражатьДокументыВУправленческомУчете");
мОтражатьВБухУчета = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(мТекущийПользователь, "ОтражатьДокументыВБухгалтерскомУчете");
мОтражатьВНалУчете = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(мТекущийПользователь, "ОтражатьДокументыВНалоговомУчете");
//Создаем Документ
Для каждого стр Из ТЧ Цикл
Состояние("Загружаю: "+стр.ФайлTXT);
текдок=Новый ТекстовыйДокумент;
текдок.Прочитать(стр.ФайлTXT,"UTF-8");
ЗагрузкаТЧ=Ложь;
ДокВозвратТоваровОтПокупателя = Документы.ВозвратТоваровОтПокупателя.СоздатьДокумент();
ДокВозвратТоваровОтПокупателя.Ответственный = мТекущийПользователь;
ДокВозвратТоваровОтПокупателя.Дата = ОбщегоНазначения.ПолучитьРабочуюДату();
ДокВозвратТоваровОтПокупателя.УстановитьНовыйНомер();
ДокВозвратТоваровОтПокупателя.ВидПоступления = Перечисления.ВидыПоступленияТоваров.НаСклад;
ДокВозвратТоваровОтПокупателя.СкладОрдер = Склад;
ДокВозвратТоваровОтПокупателя.Подразделение = мОсновноеПодразделение;
ДокВозвратТоваровОтПокупателя.ВалютаДокумента = Справочники.Валюты.НайтиПоКоду("643");
ДокВозвратТоваровОтПокупателя.УчитыватьНДС = ИСТИНА;
ДокВозвратТоваровОтПокупателя.СуммаВключаетНДС = ИСТИНА;
Для Ном=1 по текдок.КоличествоСтрок() цикл
ТСтр = текдок.ПолучитьСтроку(Ном);
ТекСтр = СокрЛП(ТСтр);
Если Найти(ТекСтр, "Всего по накладной")>0 Тогда
ЗагрузкаТЧ=Ложь;
//делаем пересчеты сумм, количества мест и НДС по строкам
Для Каждого СтрокаТабличнойЧасти Из ДокВозвратТоваровОтПокупателя.Товары Цикл
ОбработкаТабличныхЧастей.РассчитатьКоличествоМестТабЧасти(СтрокаТабличнойЧасти, ДокВозвратТоваровОтПокупателя);
ОбработкаТабличныхЧастей.РассчитатьСуммуТабЧасти(СтрокаТабличнойЧасти, ДокВозвратТоваровОтПокупателя);
ОбработкаТабличныхЧастей.РассчитатьСуммуНДСТабЧасти(СтрокаТабличнойЧасти, ДокВозвратТоваровОтПокупателя);
КонецЦикла;
Попытка
ДокВозвратТоваровОтПокупателя.Записать(РежимЗаписиДокумента.Проведение);
Исключение
ДокВозвратТоваровОтПокупателя.Записать(РежимЗаписиДокумента.Запись);
КонецПопытки;
стр.Документ = ДокВозвратТоваровОтПокупателя.Ссылка;
стр.Инфо = "Все ОК";
ЭлементыФормы.ТЧ.ТекущаяСтрока = стр;
ЭлементыФормы.ТЧ.ОбновитьСтроки(стр);
//ВСЕ
Прервать;
КонецЕсли;
Если ЗагрузкаТЧ Тогда
ТекСтр = СтрЗаменить(ТекСтр, "подложке ","подложке");
ТекСтр = СтрЗаменить(ТекСтр, " ","|");
СтрМ=РазложитьСтрокуВМассивПодстрок(ТекСтр,"|");
Если СтрМ.Количество()>2 Тогда
//Сообщить(СтрМ);
Попытка
НоваяСтрока = ДокВозвратТоваровОтПокупателя.Товары.Добавить();
НоваяСтрока.Номенклатура = Справочники.Номенклатура.НайтиПоКоду(СтрМ[2]);
//НоваяСтрока.ХарактеристикаНоменклатуры = СтрокаТаблицы.ХарактеристикаНоменклатуры;
//УстановитьСтавкуНДСВТабЧасти(НоваяСтрока, СтрокаТаблицы);
//ПроверитьНаличиеСерииНоменклатуры(НоваяСтрока, СтрокаТаблицы);
//УстановитьПризнакВеденияПоСериямНоменклатуры(НоваяСтрока);
НоваяСтрока.ЕдиницаИзмерения = НоваяСтрока.Номенклатура.БазоваяЕдиницаИзмерения;
НоваяСтрока.Коэффициент = 1;
НоваяСтрока.Количество = Число(СтрМ[6]);
НоваяСтрока.Цена = Число(СтрМ[7]);
НоваяСтрока.Сумма = Число(СтрМ[8]);
НоваяСтрока.СуммаНДС = Число(СтрМ[11]);
НоваяСтрока.Качество = Справочники.Качество.Новый;
Попытка
НоваяСтрока.СтавкаНДС = Перечисления.СтавкиНДС["НДС"+Лев(СокрЛП(СтрМ[9]),2)];
Исключение
НоваяСтрока.СтавкаНДС = НоваяСтрока.Номенклатура.СтавкаНДС;
КонецПопытки;
Исключение
Сообщить("Не загружено: "+ТекСтр);
КонецПопытки;
Иначе
Продолжить;
КонецЕсли;
Иначе
// Возможно что-то будет
КонецЕсли;
//Сообщить(ТекСтр);
Если Найти(ТекСтр, "Товарная накладная")>0 Тогда
ТекСтр = СтрЗаменить(ТекСтр, " ","|");
СтрМ=РазложитьСтрокуВМассивПодстрок(ТекСтр,"|");
Если СтрМ.Количество()>1 Тогда
//Сообщить(СтрМ);
ДокВозвратТоваровОтПокупателя.НомерВходящегоДокументаЭлектронногоОбмена = СтрМ[1];
ТекДата = СтрМ[2];
ДокВозвратТоваровОтПокупателя.ДатаВходящегоДокументаЭлектронногоОбмена = Дата(Прав(ТекДата,4)+Сред(ТекДата,4,2)+Лев(ТекДата,2));
КонецЕсли;
КонецЕсли;
Если Найти(ТекСтр, "Грузополучатель:")>0 Тогда
//Сообщить(ТекСтр);
//Получим ИНН
ГдеИНН = Найти(ТекСтр, "ИНН");
Если ГдеИНН>0 Тогда
ГдеИННвр= лев(ТекСтр,ГдеИНН+15);
текИНН = Прав(гдеИННвр, СтрДлина(ГдеИННвр)-(ГдеИНН+3));
текИНН = СокрЛП(СтрЗаменить(текИНН,".","")); текИНН = СокрЛП(СтрЗаменить(текИНН,",",""));
ТекОрганизация = Справочники.Организации.НайтиПоРеквизиту("ИНН",текИНН);
Если ТекОрганизация=Справочники.Организации.ПустаяСсылка() Тогда
ДокВозвратТоваровОтПокупателя.Организация = Организация;
Иначе
ДокВозвратТоваровОтПокупателя.Организация = ТекОрганизация;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Найти(ТекСтр, "Поставщик:")>0 Тогда
//Сообщить(ТекСтр);
//Получим ИНН
ГдеИНН = Найти(ТекСтр, "ИНН");
Если ГдеИНН>0 Тогда
ГдеИННвр= лев(ТекСтр,ГдеИНН+15);
текИНН = Прав(гдеИННвр, СтрДлина(ГдеИННвр)-(ГдеИНН+3));
текИНН = СокрЛП(СтрЗаменить(текИНН,".","")); текИНН = СокрЛП(СтрЗаменить(текИНН,",",""));
ТекПоставщик = Справочники.Контрагенты.НайтиПоРеквизиту("ИНН",текИНН);
ДокВозвратТоваровОтПокупателя.Контрагент = ТекПоставщик;
ДокВозвратТоваровОтПокупателя.ДоговорКонтрагента = ТекПоставщик.ОсновнойДоговорКонтрагента;
КонецЕсли;
КонецЕсли;
Если Найти(ТекСтр, "Плательщик:")>0 Тогда
//Сообщить(ТекСтр);
//Получим ИНН
ГдеИНН = Найти(ТекСтр, "ИНН");
Если ГдеИНН>0 Тогда
ГдеИННвр= лев(ТекСтр,ГдеИНН+15);
текИНН = Прав(гдеИННвр, СтрДлина(ГдеИННвр)-(ГдеИНН+3));
текИНН = СокрЛП(СтрЗаменить(текИНН,".","")); текИНН = СокрЛП(СтрЗаменить(текИНН,",",""));
ТекПлательщик = Справочники.Контрагенты.НайтиПоРеквизиту("ИНН",текИНН);
КонецЕсли;
КонецЕсли;
Если текстр="1 2 3 4 5 6 7 8 9 10 11 12 13 14 15" Тогда
ЗагрузкаТЧ=Истина;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Процедура ПутьКPDF2TXTОткрытие(Элемент, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
Режим = РежимДиалогаВыбораФайла.ВыборКаталога;
ДиалогОткрытия = Новый ДиалогВыбораФайла(Режим);
ДиалогОткрытия.Каталог = "";
ДиалогОткрытия.МножественныйВыбор = Ложь;
ДиалогОткрытия.Заголовок = "Выберите каталог с PDF2TXT";
Если ДиалогОткрытия.Выбрать() Тогда
ПутьКPDF2TXT = ДиалогОткрытия.Каталог;
ПутьКPDF = ДиалогОткрытия.Каталог;
КонецЕсли;
КонецПроцедуры
Процедура ПутьКPDFОткрытие(Элемент, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
Режим = РежимДиалогаВыбораФайла.ВыборКаталога;
ДиалогОткрытия = Новый ДиалогВыбораФайла(Режим);
ДиалогОткрытия.Каталог = "";
ДиалогОткрытия.МножественныйВыбор = Ложь;
ДиалогОткрытия.Заголовок = "Выберите каталог с PDF2TXT";
Если ДиалогОткрытия.Выбрать() Тогда
ПутьКPDF = ДиалогОткрытия.Каталог;
КонецЕсли;
КонецПроцедуры
Категория:
Загрузка данных в 1С Работа с бинарными файлами, Двоичные данные и кодировка Base64 Считать данные из двоичного файла можно при помощи функции ДвоичныеДанные(ИмяФайла). Например:
Код 1C v 8.2 УП ДД = ДвоичныеДанные(ИмяФайла);
или через ADODB.Stream
Код 1C v 8.х Процедура Пример(ИмяФайла)
// Перечисления из библиотеки ADO
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);
StreamIn = Новый COMОбъект("ADODB.Stream"); //Для создания этого объекта требуется MDAC 2.5 и выше
StreamIn.Type = StreamTypeEnum.adTypeBinary;
StreamIn.Open(); //По умолчанию открывается на чтение
StreamIn.LoadFromFile(ИмяФайла); //Очевидно, что для больших файлов так поступать нехорошо.
Data = StreamIn.Read(); //у переменной Data тип COMSafeArray, это массив байтов
StreamIn.Close(); //Больше нам этот поток не нужен - закрываем.
//Конечно, манипуляция в памяти приемлима только для небольших файлов!
СодержимоеМассив = Data.Выгрузить();
//...
//...
//тут можно по-всякому поиздеваться над массивом
//...
//...
//Запихиваем массив 1С в COMSafeArray. VT_UI1 - обозначение однобайтного беззнакового целого.
Data = Новый COMSafeArray(СодержимоеМассив, "VT_UI1", СодержимоеМассив.Количество());
StreamOut = Новый COMОбъект("ADODB.Stream");
StreamOut.Type = StreamTypeEnum.adTypeBinary;
StreamOut.Mode = ConnectModeEnum.adModeReadWrite; //Нужны и чтение и запись.
StreamOut.Open(); //Открыли на чтение и запись
StreamOut.Write(Data);
StreamOut.SaveToFile(ИмяФайла, SaveOptionsEnum.adSaveCreateOverWrite); //"2" - перезапись файла
StreamOut.Close();
КонецПроцедуры
Двоичные данные и кодировка Base64 в 1С 8.Х
Считать данные из двоичного файла можно при помощи функции
ДвоичныеДанные(ИмяФайла). Например:
Код 1C v 8.2 УП ДД = ДвоичныеДанные(ИмяФайла);
Здесть ДД - специальный объект, который называется "двоичные данные".
В языке 1С есть функция, которая преобразует двоичные данные в строку
Base64Строка(ДвоичныеДанные). Например:
Код 1C v 8.2 УП Строка64 = Base64Строка(ДвоичныеДанные);
Здесть Строка64 - обычная строка, с которой можно делать все, что угодно.
В конце статьи приведена функция
Преобразовать64(Строка64 = неопределено, Массив64 = неопределено) , которая преобразовывает строку в массив байтов, и обратно.
Для того, чтобы получить массив байтов из строки, вызываем ее так:
Код 1C v 8.2 УП Массив64 = Преобразовать64(Строка64 , );
Для обратного преобразования вызываем так:
Код 1C v 8.2 УП Строка64 = Преобразовать64( , Массив64 );
Преобразовать строку в двоичные данные можно при помощи функции Base64Значение(Строка64)
Все указанные функции, кроме Преобразовать64, являются встроенными функциям платформы.
Далее листинг функции Преобразовать64:
Код 1C v 8.2 УП //Автор: Гобсек
&НаСервере
Функция Преобразовать64(Строка64 = неопределено, Массив64 = неопределено)
Таб64 = Новый ТаблицаЗначений;
Таб64.Колонки.Добавить("Код");
Таб64.Колонки.Добавить("Символ");
Нпп = 0;
Для Код = КодСимвола("A") По КодСимвола("Z") Цикл
стр = Таб64.Добавить();
стр.Код = Нпп;
стр.Символ = Символ(Код);
Нпп = Нпп + 1;
КонецЦикла;
Для Код = КодСимвола("a") По КодСимвола("z") Цикл
стр = Таб64.Добавить();
стр.Код = Нпп;
стр.Символ = Символ(Код);
Нпп = Нпп + 1;
КонецЦикла;
стр = Таб64.Добавить();
стр.Код = Нпп;
стр.Символ = "0";
Нпп = Нпп + 1;
Для Код = 1 По 9 Цикл
стр = Таб64.Добавить();
стр.Код = Нпп;
стр.Символ = Формат(Код,"ЧЦ=1; ЧДЦ=0");
Нпп = Нпп + 1;
КонецЦикла;
стр = Таб64.Добавить();
стр.Код = Нпп;
стр.Символ = "+";
Нпп = Нпп + 1;
стр = Таб64.Добавить();
стр.Код = Нпп;
стр.Символ = "/";
Если Массив64 = неопределено Тогда
Если Строка64 = неопределено Тогда
Сообщить("неверный вызов функции");
Возврат неопределено;
КонецЕсли;
//Уберем переносы строк
Строка64 = СтрЗаменить(Строка64, Символ(10), "");
Строка64 = СтрЗаменить(Строка64, Символ(13), "");
//преобразовываем строку в массив
Если СтрДлина(Строка64) % 4 <> 0 Тогда
Сообщить("длина строки на входе должна быть кратна 4");
Сообщить(СтрДлина(Строка64));
Возврат неопределено;
КонецЕсли;
Кол4 = Цел(СтрДлина(Строка64) / 4);
РазмерМ = Кол4 * 3;
Если Прав(Строка64, 2) = "==" Тогда
РазмерМ = РазмерМ - 2;
ИначеЕсли Прав(Строка64, 1) = "=" Тогда
РазмерМ = РазмерМ - 1;
КонецЕсли;
Массив64 = Новый Массив(РазмерМ);
Для А = 1 По Кол4 Цикл
Число3 = 0;
Для Б = 1 По 4 Цикл
Буква1 = Сред(Строка64, (А-1)*4 + Б, 1);
Если Буква1 = "=" Тогда
Код4 = 0;
Иначе
стрН = Таб64.Найти(Буква1, "Символ");
Если стрН = Неопределено Тогда
Сообщить("ошибка при поиске "+ КодСимвола(Буква1));
Иначе
Код4 = стрН.Код;
КонецЕсли;
КонецЕсли;
Число3 = Число3 * 64 + Код4;
КонецЦикла;
Ост = Число3 % 256;
Индекс = (А-1)*3 + 2;
Если Индекс <= РазмерМ - 1 Тогда
Массив64[Индекс] = Ост;
КонецЕсли;
Число3 = (Число3 - Ост) / 256;
Ост = Число3 % 256;
Индекс = (А-1)*3 + 1;
Если Индекс <= РазмерМ - 1 Тогда
Массив64[Индекс] = Ост;
КонецЕсли;
Число3 = (Число3 - Ост) / 256;
Ост = Число3 % 256;
Массив64[(А-1)*3 + 0] = Ост;
КонецЦикла;
Возврат Массив64;
Иначе //Преобразовываем массив в строку
Строка64 = "";
Кол3 = Цел(Массив64.Количество() / 3);
Если Массив64.Количество() % 3 <> 0 Тогда
Кол3 = Кол3 + 1;
КонецЕсли;
Для А = 1 По Кол3 Цикл
Число3 = Массив64[(А-1)*3];
Если (А-1)*3+1 <= Массив64.ВГраница() Тогда
Код3 = Массив64[(А-1)*3+1];
Иначе
Код3 = 0;
КонецЕсли;
Число3 = Число3*256 + Код3;
Если (А-1)*3+2 <= Массив64.ВГраница() Тогда
Код3 = Массив64[(А-1)*3+2];
Иначе
Код3 = 0;
КонецЕсли;
Число3 = Число3*256 + Код3;
Ост4 = Число3 % 64;
Число3 = (Число3 - Ост4) / 64;
Ост3 = Число3 % 64;
Число3 = (Число3 - Ост3) / 64;
Ост2 = Число3 % 64;
Число3 = (Число3 - Ост2) / 64;
Ост1 = Число3 % 64;
Число3 = (Число3 - Ост1) / 64;
стрН = Таб64.Найти(Ост1, "Код");
Если стрН = неопределено Тогда
Сообщить("Ошибка при поиске");
Иначе
Строка64 = Строка64 + стрН.Символ;
КонецЕсли;
стрН = Таб64.Найти(Ост2, "Код");
Если стрН = неопределено Тогда
Сообщить("Ошибка при поиске");
Иначе
Строка64 = Строка64 + стрН.Символ;
КонецЕсли;
стрН = Таб64.Найти(Ост3, "Код");
Если стрН = неопределено Тогда
Сообщить("Ошибка при поиске");
Иначе
Строка64 = Строка64 + стрН.Символ;
КонецЕсли;
стрН = Таб64.Найти(Ост4, "Код");
Если стрН = неопределено Тогда
Сообщить("Ошибка при поиске");
Иначе
Строка64 = Строка64 + стрН.Символ;
КонецЕсли;
КонецЦикла;
//Если количество символов не делится на 3, то на конце должны быть
//знаки "="
Если Массив64.Количество() % 3 = 1 Тогда
Строка64 = Лев(Строка64, СтрДлина(Строка64)-2)+ "==";
ИначеЕсли Массив64.Количество() % 3 = 2 Тогда
Строка64 = Лев(Строка64, СтрДлина(Строка64)-1)+ "=";
КонецЕсли;
Возврат Строка64;
КонецЕсли;
КонецФункции
Категория:
OLE, ActiveX Импорт в 1С из текстовых файлов (TXT, CSV) Не редко возникает необходимость загрузить в справочники или документы 1С данные из текстового файла. Приведенный пример внешней обработки позволит преобразовать текстовый файл с известным разделителем данных в поле табличного документа для последующей обработки уже внутри 1С:Предприятия. Обработка содержит функцию разбора строки на массив данных, настраиваемый разделитель строки текста на "столбцы", процедуру чтения данных из текстового файла.
Разбор строки в массив с использованием функций из конфигурации 1С
Для разложения строки в массив в конфигурация 1С:Бухгалтерия, 1С:Торговля и 1С:УПП имеется замечательная функция - Функция РазложитьСтрокуВМассивПодстрок(Знач Стр, Разделитель = ",") Экспорт. Функция "расщепляет" строку на подстроки, используя заданный разделитель. Разделитель может иметь любую длину. Если в качестве разделителя задан пробел, рядом стоящие пробелы считаются одним разделителем, а ведущие и хвостовые пробелы параметра "Стр" игнорируются. Подробнее можно прочесть внутри конфигурации - "Общие модули" -> "Общего назначения". Функция возвращает массив значений, элементы которого - подстроки.
Чтение текстового файла (txt) в 1С
Операцию импорта - экспорта текстовых файлов (формат тхт или csv, а также htm, html) очень удобно реализовать при помощи конструкции следующего вида:
1. Функция ПолучитьПотокЧтенияСтрок(Файл) - Назначение: Проверить наличие файла (функция Файл()), Создать текстовый документ (Новый ТекстовыйДокумент()), вызвать метод "Прочитать" для открытия потока чтения файла. Возвращает поток, готовый для чтения.
2. Процедура ЧтениеТХТФайла(Элемент) - Назначение: В цикле произвести последовательное чтение строк файла текстового документа, разбирая на массив колонок данных и добавляя значения массива в табличное поле;
Исходный код 1С функции создания текстового потока чтения файла ТХТ:
Код 1C v 8.х Функция ПолучитьПотокЧтенияСтрок(Файл)
Попытка
// Используется для доступа к параметрам файлов или каталогов.
ТекстовыйФайл = Новый Файл(Файл);
Если ТекстовыйФайл.Существует() = Ложь Тогда
Сообщить("Файла "+Файл+" не существует!");
Возврат Неопределено;
КонецЕсли;
// Текстовый документ предназначен для работы с текстами.
// Объект позволяет получать и сохранять текст в файле,
// работать со строками
ПотокЧтенияСтрок = Новый ТекстовыйДокумент();
ПотокЧтенияСтрок.Прочитать(ТекстовыйФайл);
Исключение
Сообщить("Файл не прочитан.", СтатусСообщения.Внимание);
Сообщить(ОписаниеОшибки());
Возврат Неопределено;
КонецПопытки;
// Возвращает текст, извлеченный из файла
Возврат ПотокЧтенияСтрок;
КонецФункции // ПолучитьПотокЧтенияСтрок
// Исходный код функции загрузки строк в табличное поле:
Процедура ЧтениеТХТФайла(Элемент)
// Проверка на наличие имени файла
Если ПустаяСтрока(ИмяФайла) Тогда
Предупреждение("Для запуска обработки необходимо предварительно выбрать файл данных.");
Возврат;
КонецЕсли;
// Открыть файл, создать текстовый документ, прочитать
ПотокСтрок = ПолучитьПотокЧтенияСтрок(ИмяФайла);
// Очистить предыдущие значения
ТаблицаДокумента.Очистить();
ТаблицаДокумента.Колонки.Очистить();
// Создать колонки табличного документа
ТаблицаДокумента.Колонки.Добавить("Номер",,"Номер",5);
ТаблицаДокумента.Колонки.Добавить("Артикул",,"Артикул",11);
ТаблицаДокумента.Колонки.Добавить("Номенклатура",,"Номенклатура",25);
ТаблицаДокумента.Колонки.Добавить("Цена",,"Цена",6);
// Последовательное чтение строк текстового файла
КоличествоСтрок = ПотокСтрок.КоличествоСтрок();
Для Строка = 1 По КоличествоСтрок Цикл
// Обработка нажатия Ctrl + Break
ОбработкаПрерыванияПользователя();
// Чтение строки из файла тхт / csv
СтрокаИзФайла = ПотокСтрок.ПолучитьСтроку(Строка);
// Разбор строки в массив, используя в качествен символа-разделителя "|"
МассивСтрок = ОбщегоНазначения.РазложитьСтрокуВМассивПодстрок(СтрокаИзФайла,"|");
// Добавить данные в табличную часть экранной формы
Стр=ТаблицаДокумента.Добавить();
Стр.Номер = Строка;
Стр.Артикул = МассивСтрок[0];
Стр.Номенклатура = МассивСтрок[1];
Стр.Цена = МассивСтрок[2];
// Отобразить информацию о ходе выполнения обработки
Состояние("Обработка строки файла : "
+ "строка " + Строка + " из " + КоличествоСтрок);
КонецЦикла;
// Отобразить результаты загрузки в форме элемента
ЭлементыФормы.ТаблицаДокумента.Значение = ТаблицаДокумента;
ЭлементыФормы.ТаблицаДокумента.СоздатьКолонки();
КонецПроцедуры // ЧтениеTXTФайла(Элемент)
В данном примере была произведена загрузка из текстового файла в следующем формате:
Код 7754|Процессор Atom 1.7|10,00
5054|Процессор AMD x64|8,99
7546|Мышь Microsoft|45,88
Категория:
XML, DBF, TXT, CSV Яндекс, 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 Обмен между базами через XML (создается ФабрикаXDTO) В процедурах выгрузки/загрузки создается ФабрикаXDTO из схемы, которая хранится в макете как файл. Файл настроек схемы надо использовать один и тот же в обработках Загрузки/Выгрузки
Из Фабрики создается объект, его заполняю выгружаемыми данными
Фабрику сохраняю в XML. В процедуре загрузки из читаю фабрику из XML и пробегаю по объектам
Очень удобно!
Код 1C v 8.х Функция СоздатьФайлСхемы()
ФайлСхемы = Новый Файл(КаталогВременныхФайлов() + "schema.xsd");
Если ФайлСхемы.Существует() Тогда
УдалитьФайлы(ФайлСхемы.ПолноеИмя);
КонецЕсли;
Ссылка = ПолучитьМакет("schema_xsd");
Ссылка.Записать(ФайлСхемы.ПолноеИмя);
Возврат ФайлСхемы.ПолноеИмя;
КонецФункции
Функция ВыгрузитьДокументы()
ФайлыXSD = Новый Массив();
ФайлыXSD.Добавить(СоздатьФайлСхемы());
Фабрика = СоздатьФабрикуXDTO(ФайлыXSD);
ФайлОбмена = Фабрика.Создать(Фабрика.Тип("http://anton.fly7.ru", "ФайлОбмена"));
Пока Выборка.Следующий() Цикл
Документ = Фабрика.Создать(Фабрика.Тип("http://anton.fly7.ru", "Документ"));
Документ.ID = Строка(Док.УникальныйИдентификатор());
Документ.ВидДокумента = Док.Метаданные().Имя;
Документ.Дата = Док.Дата;
Документ.Номер = Док.Номер;
Документ.Статус = ?(Док.Проведен, "Проведен", ?(Док.ПометкаУдаления, "ПометкаУдаления", "НеПроведен"));
Документ.Комментарий = Док.Комментарий;
КонецЦикла
ПараметрыЗаписиXML = Новый ПараметрыЗаписиXML("UTF-8", "1.0", Ложь);
МойXML = Новый ЗаписьXML;
МойXML.ОткрытьФайл(ИмяФайла, ПараметрыЗаписиXML);
МойXML.ЗаписатьОбъявлениеXML();
Фабрика.ЗаписатьXML(МойXML, ФайлОбмена);
МойXML.Закрыть();
ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Создан файл обмена " + ИмяФайла);
КонецФункции
Процедура ЗагрузитьДокументы()
ФайлыXSD = Новый Массив();
ФайлыXSD.Добавить(СоздатьФайлСхемы());
Фабрика = СоздатьФабрикуXDTO(ФайлыXSD);
ФайлОбмена = Фабрика.Создать(Фабрика.Тип("http://anton.fly7.ru", "ФайлОбмена"));
ОбменXML = Новый ЧтениеXML;
ОбменXML.ОткрытьФайл(ИмяФайла);
ФайлОбмена = Фабрика.ПрочитатьXML(ОбменXML, Фабрика.Тип("http://anton.fly7.ru", "ФайлОбмена"));
Для Каждого Документ Из ФайлОбмена.Документ Цикл
ОбработкаПрерыванияПользователя();
Если Документ.ВидДокумента = "ПоступлениеТоваров" И
ЗначениеЗаполнено(Поставщик) И
Документ.Контрагент.ИНН Поставщик.ИНН Тогда
КонецЕсли;
КонецЦикла
ФайлОбмена = "";
ОбменXML.Закрыть();
УдалитьФайлы(ИмяФайла);
КонецПроцедуры
Файл схемы примерно такой (разукрашка съела скобки, но смысл должен быть понятен ))
Код xs:schema xmlns:tns="http://anton.fly7.ru" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://anton.fly7.ru" attributeFormDefault="unqualified" elementFormDefault="qualified">
xs:complexType name="ФайлОбмена">
xs:sequence>
xs:element name="Документ" type="tns:Документ" nillable="true" maxOccurs="unbounded"/>
xs:sequence>
xs:complexType>
xs:complexType name="Документ">
xs:sequence>
xs:element name="ID" type="xs:string"/>
xs:element name="ВидДокумента" type="xs:string"/>
xs:element name="Статус" type="xs:string"/>
xs:element name="Дата" type="xs:dateTime"/>
xs:element name="Номер" type="xs:string"/>
xs:element name="Контрагент" type="tns:Контрагент"/>
xs:element name="Свойства" type="tns:ТаблицаСвойства" nillable="true" minOccurs="0"/>
xs:sequence>
xs:complexType>
xs:complexType name="Контрагент">
xs:sequence>
xs:element name="ID" type="xs:string"/>
xs:element name="Наименование" type="xs:string"/>
xs:element name="ИНН" type="xs:string"/>
xs:sequence>
xs:complexType>
xs:complexType name="ТаблицаСвойства">
xs:sequence>
xs:element name="СтрокаСвойства" type="tns:СтрокаСвойство" nillable="true" maxOccurs="unbounded"/>
xs:sequence>
xs:complexType>
xs:complexType name="СтрокаСвойство">
xs:sequence>
xs:element name="Наименование" type="xs:string" nillable="true"/>
xs:element name="Значение" type="xs:string" nillable="true"/>
xs:sequence>
xs:complexType>
xs:schema>
Автор:
Абазин Антон Категория:
WEB-сервисы, WS-ссылки, XDTO-пакеты Передача файлов и данных на веб-сервер из 1С методами GET и POST При интеграции 1С с веб-сайтами всегда встает вопрос о передачи некоторых данных на веб-сервер. Будь то это передача параметров запроса для получения данных от веб-сервера в 1С или же передача данных из 1С, которые должны быть сохранены или каким-то образом обработаны на веб-сервере. Передаваться могут как простые данные в виде строк, чисел, так и целые файлы (изображения, XML-файлы и прочее). Для передачи и получения файлов и данных на веб-сервер в 1С используется объект HTTPСоединение .
Создание и инициализация HTTP соединения в 1С
Для инициализации HTTP соединения в 1С необходимо создать объект HTTPСоединение и в конструкторе указать параметры HTTP соединения.
Код 1C v 8.х Новый HTTPСоединение(<Сервер>, <Порт>, <ИмяПользователя>, <Пароль>, <Прокси>, <ЗащищенноеСоединение>)
<Сервер> (обязательный) - адрес сервера, с которым необходимо установить соединение.
<Порт> (необязательный) - порт сервера, с которым устанавливается соединение.
Значение по умолчанию зависит от защищенности соединения (80 для незащищенного и 443 для SSL-соединения).
<ИмяПользователя> (необязательный) - имя пользователя на указанном сервере.
<Пароль> (необязательный) - пароль пользователя на указанном сервере.
<Прокси> (необязательный). Тип - ИнтернетПрокси. Прокси, используемый для соединения с сервером.
<ЗащищенноеСоединение> (необязательный). Тип - Булево. Определяет используемый протокол -
http или https. По умолчанию Ложь.
Ниже приведен примеры создания HTTPСоединения с сайтом http://www.mysite.ru/.
Код 1C v 8.х // соединение с параметрами по умолчанию
Соединение = Новый HTTPСоединение("www.mysite.ru");
// сервер использует порт 8080
Соединение = Новый HTTPСоединение("www.mysite.ru", 8080);
// сервер использует защищенное соединение (https),
// для подключения к серверу используется прокси
ПроксиСервер = Новый интернетПрокси;
ПроксиСервер.Пользователь = имяПользователя;
ПроксиСервер.Пароль = парольПользователя;
Соединение = Новый HTTPСоединение("www.mysite.ru",,,, ПроксиСервер, Истина);
Передача данных на веб-сервер из 1С методом GET.
Для передачи данных на веб-сервер из 1С методом GET используется процедура Получить() объекта HTTPСоединение.
Код 1C v 8.х Получить(<Источник>, <ИмяВыходногоФайла>, <Заголовки>)
<Источник> (обязательный). Тип - Строка. Адрес ресурса на сервере.
<ИмяВыходногоФайла> (обязательный). Тип - Строка. Имя файла на диске, в который
помещаются данные, полученные от сервера (ответ сервера).
<Заголовки> (необязательный). Тип - Строка. Заголовки, добавляемые к запросу на сервер.
Текстовые пары вида <Заголовок>:<Значение>, разделенные комбинацией ВК + ПС.
(подробнее о заголовках будет сказано ниже).
Рассмотрим параметры процедуры Получить() более подробно:
В качестве источника указывается строка с адресом запроса, идущая после названия домена и символа "/". Так, если необходимо отправить данные на адрес https://www.mysite.com/getusers.php, то при создании HTTP соединения в конструкторе HTTPСоединение в поле "Сервер" указывается "www.mysite.com", признак защищенного соединения устанавливается в Истина, а в процедуре Получить() в параметре Источник указывается "getUsers.php".
В поле ИмяВыходногоФайла указывает имя файла на диске, в который будут сохранены данные, полученные от сервере в результате запроса. Так, например, если сервер возвращает список пользователей в формате XML, то на диск в указанный файл будет сохранен XML файл со списком пользователей.
О заголовках более подробно будет сказано ниже.
Так же, при запросе к веб-серверу зачастую передаются дополнительные данные (параметры) для этого запроса. Параметры от адреса источника отделяются символом "?". Каждый параметр задается в формате <Имя_Параметры>=<Значение_Параметры>. Параметры от адреса источника отделяются символом "?". Сами же параметры отделяются друг от друга символом "&". В результате строка адреса источника может выглядеть следующим образом: getUsers.php?owner_id=263544&count=100.
Ниже приведен пример, поясняющий все выше сказанное.
Код 1C v 8.х // необходимо выполнить запрос по адресу
// https://www.mysite.com/getUsers.php?owner_id=263544&count=100
// ответ от сервера приходит в виде XML файла
имяВыходногоФайла = ПолучитьимяВременногоФайла("xml");
Соединение = Новый HTTPСоединение("www.mysite.com",,,,, Истина);
Соединение.Получить("getUsers.php?owner_id=263544&count=100", имяВыходногоФайла);
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(имяВыходногоФайла);
Пока ЧтениеXML.Прочитать() Цикл
// чтение ответа в виде XML файла
...
КонецЦикла;
ЧтениеXML.Закрыть();
// удаляем файл после использования
УдалитьФайлы(имяВыходногоФайла);
Заголовки HTTP
Ниже приведена общая информация о HTTP заголовках из википедии.
Заголовки HTTP (англ. HTTP Headers) — это строки в HTTP-сообщении, содержащие разделённую двоеточием пару имя-значение. Формат заголовков соответствует общему формату заголовков текстовых сетевых сообщений ARPA. Заголовки должны отделяться от тела сообщения хотя бы одной пустой строкой.
Все заголовки разделяются на четыре основных группы:
General Headers (рус. Основные заголовки) — должны включаться в любое сообщение клиента и сервера.
Request Headers (рус. Заголовки запроса) — используются только в запросах клиента.
Response Headers (рус. Заголовки ответа) — только для ответов от сервера.
Entity Headers (рус. Заголовки сущности) — сопровождают каждую сущность сообщения.
Именно в таком порядке рекомендуется посылать заголовки получателю.
Более подробно о заголовках HTTP можно прочитать здесь. Так же можно ознакомится со списком заголовков HTTP.
От себя лишь добавлю, что, если это явно не указано в требованиях к отправке данных веб-серверу заголовки HTTP для метода GET можно не указывать. Для метода POST обычно нужно указать заголовки Content-Type (тип передаваемых данных, например: "Content-Type: text/html;charset=utf-8") и Content-Length (размер передаваемых данных в байтах, например: "Content-Length: 1348").
Напомню, что HTTP заголовки в 1С указываются строкой в виде текстовых пар "<Заголовок>:<Значение>", разделенных комбинацией символов ВК+ПС.
Также заголовки можно задать типом Соответствие, где в качестве ключа указывается заголовок, а в качестве значения - значение заголовка.
Ниже приведены поясняющие примеры:
Код 1C v 8.х источник = "owner=263544&count=100";
// Передача заголовков строкой
ЗаголовкиHTTP = "Content-Type:text/html;charset=utf-8" + Символ.ВК + Символ.ПС +
"Content-Length: "+СтрДлина(источник);
Соединение.Получить("", имяВыходногоФайла, ЗаголовкиHTTP);
// Вставить символы ВК+ПС можно и таким способом
ЗаголовкиHTTP = "Content-Type:text/html;charset=utf-8
|Content-Length: 1348";
Соединение.Получить("", имяВыходногоФайла, ЗаголовкиHTTP);
// Установка заголовков типом Соответствие
ЗаголовкиHTTP = Новый Соответствие;
ЗаголовкиHTTP.Вставить("Content-Type", "text/html;charset=utf-8");
ЗаголовкиHTTP.Вставить("Content-Length", СтрДлина(источник));
Соединение.Получить(источник, имяВыходногоФайла, ЗаголовкиHTTP);
Передача данных на веб-сервер из 1С методом POST.
Общие сведения.
Для передачи данных на веб-сервер из 1С методом POST используется процедура ОтправитьДляОбработки() объекта HTTPСоединение.
Код 1C v 8.х ОтправитьДляОбработки(<Источник>, <АдресРесурса>, <ИмяВыходногоФайла>, <Заголовки>)
<Источник> (обязательный) - Имя файла-источника, который будет отправлен
на сервер для обработки.
<АдресРесурса> (обязательный). Тип - строка. Адрес ресурса на сервере,
в который посылаются данные из источника.
<ИмяВыходногФайла> (обязательный) - Имя файла на диске, в который записываются
полученные с сервера данные.
<Заголовки> (необязательный). Тип - строка. Заголовки, добавляемые к запросу на сервер.
Текстовые пары вида <Заголовок>:<Значение>, разделенные комбинацией ВК + ПС.
(подробнее о заголовках будет сказано ниже).
Рассмотрим параметры процедуры ОтправитьДляОбработки() подробнее:
В качестве источника указывается файл, содержимое которого необходимо отправить на сервер для обработки. Подробнее о формировании содержимого файла-источника будет сказано ниже.
Поле АдресРесурса аналогично полю Источник процедуры Получить(), т.е. указывается строка с адресом запроса, идущая после имени домена и символа "/".
Поле ИмяВыходногоФайла также аналогично одноименному полю процедуры Получить(), т.е. содержит имя файла, в котором будут сохранены данные, полученные от сервера в результате обработки исходных данных.
О заголовках было упомянуто выше. Напомню лишь, что для метода POST обычно указываются заголовки Content-Type и Content-Length. В качестве параметра заголовка Content-Length указывается размер файла-источника, преобразованный с помощью функции XMLСтрока().
Ниже приведен пример, поясняющий все выше сказанное.
Код 1C v 8.х имяФайлаОтправки = "d:\data\request.txt"; // файл с отсылаемыми для обработки данными
// Определим размер файла-источника
// и установим HTTP заголовки
ФайлОтправки = Новый Файл(имяФайлаОтправки);
РазмерФайлаОтправки = XMLСтрока(ФайлОтправки.Размер());
Заголовки = Новый Соответствие();
Заголовки.Вставить("Content-Type", "text/html;charset=utf-8");
Заголовки.Вставить("Content-Lenght", РазмерФайлаОтправки);
имяВыходногоФайла = ПолучитьимяВременногоФайла("xml");
Соединение = Новый HTTPСоединение("www.mysite.com");
Соединение.ОтправитьДляОбработки(имяФайлОтправки, "addPost.php", имяВыходногоФайла, Заголовки);
Передача параметров методом POST.
Для передачи параметров, аналогично методу GET, можно сформировать строку параметров, записать их в текстовый файл и отправить этот файл на сервер для обработки. Ниже приведен пример аналогичный примеру отправки методом GET, но теперь те же данные отправляются методом POST.
Код 1C v 8.х // сформируем файл для отправки на сервер
имяФайлаОтправки = ПолучитьимяВременногоФайла("txt");
ЗаписьТекста = Новый ЗаписьТекста(имяФайлаОтправки);
ЗаписьТекста.Записать("owner=263544&count=100");
ЗаписьТекста.Закрыть();
// отправим файл на сервер для обработки
имяВыходногоФайла = ПолучитьимяВременногоФайла("xml"); // наш сервер возвращает ответы в виде XML
ФайлОтправки = Новый Файл(имяФайлаОтправки);
РазмерФайлаОтправки = XMLСтрока(ФайлОтправки.Размер());
Заголовки = Новый Соответствие();
Заголовки.Вставить("Content-Type", "text/html;charset=utf-8");
Заголовки.Вставить("Content-Lenght", РазмерФайлаОтправки);
Соединение = Новый HTTPСоединение("www.mysite.com");
Соединение.ОтправитьДляОбработки(имяФайлОтправки, "addPost.php", имяВыходногоФайла, Заголовки);
// удалим файл отправки - он больше не нужен
Попытка
УдалитьФайлы(имяФайлаОтправки);
Исключение
КонецПопытки;
// обработаем ответ сервера
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(имяВыходногоФайла);
Пока ЧтениеXML.Прочитать() Цикл
// чтение ответа в виде XML файла
...
КонецЦикла;
ЧтениеXML.Закрыть();
// удаляем файл после использования
Попытка
УдалитьФайлы(имяВыходногоФайла);
Исключение
КонецПопытки;
Передача файлов методом POST.
Зачастую данные для обработки задаются не виде строки параметров разделенных "&", как в рассматриваемых выше примерах, а виде файла определенного формата, например XML или JSON. Рассмотрим пример отправки данных на веб-сервер для обработки методом POST, которые задаются в формате XML. Например, сервер может добавить ваш комментарий к материалу. В описании процедуры добавлении сказано, что данные необходимо отправлять по адресу www.mysite.com/addComment.php. Сами данные должны быть переданы в следующем виде:
Код <?xml version="1.0" encoding="UTF-8"?>
<request>
<user_id>ID_Пользователя</user_id>
<post_id>ID_Материала</post_id>
<message>Текст_Комментария</message>
</request>
где:
<ID_Пользователя> - id пользователя на сайте, от имени которого добавляется комментарий;
<ID_Материала> - id материала на сайте, к которому добавляется комментарий;
<Текст_Комментария> - текст комментария.
Предположим, что нам уже известны id пользователя и материала и они хранятся в переменных user_id и post_id. Ниже приведен пример, решающий нашу задачу.
Код 1C v 8.х // подготовим файл с данными для отправки
имяФайлаОтправки = ПолучитьимяВременногоФайла("xml");
ОбъектXML = Новый ЗаписьXML;
ОбъектXML.ОткрытьФайл(имяФайлаОтправки, "UTF-8");
ОбъектXML.ЗаписатьОбъявлениеXML();
ОбъектXML.ЗаписатьБезОбработки(
"<request>
| <user_id>" + user_id + "</user_id>
| <post_id>" + post_id + "</post_id>
| <message>" + ТекстКомментария + "</message>
|</request>");
ОбъектXML.Закрыть();
// отправим файл на сервер для обработки
имяВыходногоФайла = ПолучитьимяВременногоФайла("xml"); // наш сервер возвращает ответы в виде XML
ФайлОтправки = Новый Файл(имяФайлаОтправки);
РазмерФайлаОтправки = XMLСтрока(ФайлОтправки.Размер());
Заголовки = Новый Соответствие();
Заголовки.Вставить("Content-Type", "text/html;charset=utf-8");
Заголовки.Вставить("Content-Lenght", РазмерФайлаОтправки);
Соединение = Новый HTTPСоединение("www.mysite.com");
Соединение.ОтправитьДляОбработки(имяФайлОтправки, "addComment.php", имяВыходногоФайла, Заголовки);
// удалим файл отправки - он больше не нужен
Попытка
УдалитьФайлы(имяФайлаОтправки);
Исключение
КонецПопытки;
// обработаем ответ сервера
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(имяВыходногоФайла);
Пока ЧтениеXML.Прочитать() Цикл
// чтение ответа в виде XML файла
...
КонецЦикла;
ЧтениеXML.Закрыть();
// удаляем файл после использования
Попытка
УдалитьФайлы(имяВыходногоФайла);
Исключение
КонецПопытки;
Загрузка файлов (изображений, документов и т.п.) на веб-сервер методом POST.
Зачастую возникает необходимость загрузки файлов на веб-сервер. Это может быть, например, изображение к статье на сайте, или фотография для альбома, или архив для файлообменника. Ранее мы рассматривали передачу методом POST параметров или просто файлов. Таким же образом можно и передавать двоичные файлы. Но как быть, если файлы необходимо отправлять вместе с параметрами? Для возможности отправки файлов в этом случае используется HTTP заголовок ContentType:multipart/form-data. Следует заметить, что обычно таким способом передаются файлы через веб-браузеры. Т.е. когда на сайте вы выбираете файл и нажимаете кнопку "Загрузить", то файл передается способом описанным ниже. При таком способе сам файл также задается как переменная, т.е., например, файл передается через параметр file или image. Однако, мы не можем просто передать file=<Двоичные_Данные>. А вот как все таки передать файл мы и рассмотрим ниже.
Для возможности вместе с параметрами передавать и двоичные данные (файлы) необходимо сформировать HTTP заголовок Content-Type следующим образом:
Content-Type: multipart/form-data, boundary=<уникальные_данные>
где <уникальные_данные> - это любой набор цифр и/или символов, который будет служить для отделения значений друг от друга. Значение boundary должно быть уникальным в пределах пересылаемой информации, т.е. таких символов не должно встречаться в пересылаемых файлах и переменных.
Bounday можно сформировать, например, таким образом
Код 1C v 8.х boundary = СтрЗаменить(Строка(Новый УникальныйИдентификатор()), "-", "");
Все данные отделяются друг от друга разделителем boundary. Начинать разделитель нужно с "--":
Код --<boundary>
Content-Disposition: form-data; name="<имя_переменной>"
<пустая_строка>
<значение_переменной>
Для отправки файла необходимо еще добавить тип и имя файла:
--<boundary>
Content-Disposition: form-data; name="<имя_переменной>"; filename="<имя_файла>"
Content-Type: <тип_файла> (например image/jpeg или text/plain)
<пустая_строка>
<данные_файла>
В конце данных нужно закрыть разделитель, добавили в конце разделителя "--", т.е. вид будет "--<boundary>--".
Итак, например, нам нужно передать на веб-сервер текстовый файл через параметр "text", его описание через параметр "desc" и id пользователя через параметр "uid", для которого будет загружен наш файл.
Предположим, что файл содержит следующий текст:
Мороз и солнце; день чудесный!
Еще ты дремлешь, друг прелестный -
Пора, красавица, проснись:
Открой сомкнуты негой взоры
Навстречу северной Авроры,
Звездою севера явись!
Описание должно содержать "Стих А.С. Пушкина", а id пользователя равно "0123456". Тогда файл должен быть сформирован следующим образом (для упрощения предположим, что bounday мы уже сформировали и он равен "ccf8111910")
Код --ccf8111910
Content-Disposition: form-data; name="uid"
0123456
--ccf8111910
Content-Disposition: form-data; name="desc"
Стих А.С. Пушкина
--ccf8111910
Content-Disposition: form-data; name="text"; filename="stih.txt"
Content-Type: text/plain
Мороз и солнце; день чудесный!
Еще ты дремлешь, друг прелестный -
Пора, красавица, проснись:
Открой сомкнуты негой взоры
Навстречу северной Авроры,
Звездою севера явись!
--ccf8111910--
А теперь перейдем непосредственно к 1С. Пусть у нас будет форма с реквизитами "Пользователь", "Описание" и "ИмяФайла". Реализуем отправку данных, описанным выше способом
Код 1C v 8.х // подготовим файл с данными для отправки
имяФайлаОтправки = ПолучитьимяВременногоФайла("txt");
Boundary = СтрЗаменить(Строка(Новый УникальныйИдентификатор()), "-", "");
ЗаписьТекста = Новый ЗаписьТекста(имяФайлаОтправки);
// параметр "uid"
ЗаписьТекста.ЗаписатьСтроку("--"+boundary);
ЗаписьТекста.ЗаписатьСтроку("Content-Disposition: form-data; name=""uid""");
ЗаписьТекста.ЗаписатьСтроку("");
ЗаписьТекста.ЗаписатьСтроку(Пользователь);
// параметр "desc"
ЗаписьТекста.ЗаписатьСтроку("--"+boundary);
ЗаписьТекста.ЗаписатьСтроку("Content-Disposition: form-data; name=""desc""");
ЗаписьТекста.ЗаписатьСтроку("");
ЗаписьТекста.ЗаписатьСтроку(Описание);
// параметр "text"
ФайлДляПередачи = Новый ТекстовыйДокумент;
ФайлДляПередачи.Прочитать(имяФайла);
ЗаписьТекста.ЗаписатьСтроку("--"+boundary);
ЗаписьТекста.ЗаписатьСтроку("Content-Disposition: form-data; name=""text""; filename=""stih.txt""");
ЗаписьТекста.ЗаписатьСтроку("Content-Type: text/plain");
ЗаписьТекста.ЗаписатьСтроку("");
ЗаписьТекста.Записать(ФайлДляПередачи.ПолучитьТекст());
ЗаписьТекста.ЗаписатьСтроку("");
// закроем разделитель
ЗаписьТекста.ЗаписатьСтроку("--"+boundary+"--");
ЗаписьТекста.Закрыть();
ФайлОтправки = Новый Файл(имяФайлаОтправки);
РазмерФайлаОтправки = XMLСтрока(ФайлОтправки.Размер());
// передадим данные на сервер
Заголовки = Новый Соответствие();
Заголовки.Вставить("Content-Type", "multipart/form-data, boundary="+boundary);
Заголовки.Вставить("Content-Lenght", РазмерФайлаОтправки);
Соединение = Новый HTTPСоединение("www.mysite.com");
Соединение.ОтправитьДляОбработки(имяФайлОтправки, "postFile.php", имяВыходногоФайла, Заголовки);
Передача текстовых файлов таким способом проблем не вызывает. Сложнее дело обстоит с файлами, содержащими двоичные данные (изображения, архивы и т.п.). Все дело в том, что в 1С просто нет методов для чтение двоичных файлов в строку. Если мы делаем обмен со своим сайтом, которые сами и разрабатывали, то можно просто преобразовать файл в строку Base64 при помощи процедуры Base64Строка(), а на стороне сервера преобразовать строку Base64 обратно.
Код 1C v 8.х // подготовим файл с данными для отправки
имяФайлаДанных = "d:\photo\birthday.jpg";
имяФайлаОтправки = ПолучитьимяВременногоФайла("txt");
Boundary = СтрЗаменить(Строка(Новый УникальныйИдентификатор()), "-", "");
ЗаписьТекста = Новый ЗаписьТекста(имяФайлаОтправки);
// параметр "file"
ЗаписьТекста.ЗаписатьСтроку("--"+boundary);
ЗаписьТекста.ЗаписатьСтроку("Content-Disposition: form-data; name=""file""; filename=""photo.jpg""");
ЗаписьТекста.ЗаписатьСтроку("Content-Type: image/jpeg");
ЗаписьТекста.ЗаписатьСтроку("");
ЗаписьТекста.Записать(Base64Строка(Новый ДвоичныеДанные(имяФайлаДанных)));
ЗаписьТекста.ЗаписатьСтроку("");
// закроем разделитель
ЗаписьТекста.ЗаписатьСтроку("--"+boundary+"--");
ЗаписьТекста.Закрыть();
ФайлОтправки = Новый Файл(имяФайлаОтправки);
РазмерФайлаОтправки = XMLСтрока(ФайлОтправки.Размер());
// передадим данные на сервер
Заголовки = Новый Соответствие();
Заголовки.Вставить("Content-Type", "multipart/form-data, boundary="+boundary);
Заголовки.Вставить("Content-Lenght", РазмерФайлаОтправки);
Соединение = Новый HTTPСоединение("www.mysite.com");
Соединение.ОтправитьДляОбработки(имяФайлОтправки, "uploadFile.php", имяВыходногоФайла, Заголовки);
А как же быть если мы загружаем файл на сторонний сервер, который принимает файл как есть без преобразование его в строку Base64(). В это случае можно пойти на хитрость. В 1С есть процедура ОбъединитьФайлы(), которая объединяет несколько файлов на диске в один результирующий файл
Код 1C v 8.х ОбъединитьФайлы(<ИменаЧастей>, <ИмяРезультирующегоФайла>)
<ИменаЧастей> (обязательный). Тип - Массив. Массив имен частей файлов, которые
требуется объединить. Объединение будет происходить в порядке, в котором заданы
имена файлов в массиве.
<ИмяРезультирующегоФайла> (обязательный). Тип - Строка. Имя файла, который будет
создан в результате объединения файлов.
Т.е. мы можем сформировать текстовый файл с запросом, объединить его с файлом(-ами), которые необходимо передать на веб-сервер и передать уже файл, получившийся в результате объединения исходных файлов. Ниже демонстрируется процесс передачи двух zip архивов на сервер с дополнительными параметрами user_id и post_id.
Код 1C v 8.х // подготовим файлы с данными для отправки
массивФайлов = Новый Массив;
Boundary = СтрЗаменить(Строка(Новый УникальныйИдентификатор()), "-", "");
имяФайлаСПараметрами = ПолучитьимяВременногоФайла("txt"); // первый файл, содержащий параметры
ЗаписьТекста = Новый ЗаписьТекста(имяФайлаСПараметрами);
// параметр "user_id"
ЗаписьТекста.ЗаписатьСтроку("--"+boundary);
ЗаписьТекста.ЗаписатьСтроку("Content-Disposition: form-data; name=""user_id""");
ЗаписьТекста.ЗаписатьСтроку("");
ЗаписьТекста.ЗаписатьСтроку(user_id);
// параметр "post_id"
ЗаписьТекста.ЗаписатьСтроку("--"+boundary);
ЗаписьТекста.ЗаписатьСтроку("Content-Disposition: form-data; name=""post_id""");
ЗаписьТекста.ЗаписатьСтроку("");
ЗаписьТекста.ЗаписатьСтроку(post_id);
// начало параметра "file1"
ЗаписьТекста.ЗаписатьСтроку("--"+boundary);
ЗаписьТекста.ЗаписатьСтроку("Content-Disposition: form-data; name=""file1""; filename=""archive1.zip""");
ЗаписьТекста.ЗаписатьСтроку("Content-Type: application/x-zip-compressed");
ЗаписьТекста.ЗаписатьСтроку("");
ЗаписьТекста.Закрыть(); // заканчиваем работу с файлом 1
массивФайлов.Добавить(имяФайлаСПараметрами); // добавляем 1-ый файл для объединения
массивФайлов.Добавить(имяФайлаАрхива1); // добавляем 1-ый архив для объединения
// второй файл параметров, содержаший начало параметра "file2"
имяФайлаСПараметрами = ПолучитьимяВременногоФайла("txt");
ЗаписьТекста = Новый ЗаписьТекста(имяФайлаСПараметрами);
// начало параметра "file2"
ЗаписьТекста.ЗаписатьСтроку("");
ЗаписьТекста.ЗаписатьСтроку("--"+boundary);
ЗаписьТекста.ЗаписатьСтроку("Content-Disposition: form-data; name=""file2""; filename=""archive2.zip""");
ЗаписьТекста.ЗаписатьСтроку("Content-Type: application/x-zip-compressed");
ЗаписьТекста.ЗаписатьСтроку("");
ЗаписьТекста.Закрыть(); // заканчиваем работу с файлом 2
массивФайлов.Добавить(имяФайлаСПараметрами); // добавляем 2-ой файл для объединения
массивФайлов.Добавить(имяФайлаАрхива2); // добавляем 2-ой архив для объединения
ЗаписьТекста.Записать(ФайлДляПередачи.ПолучитьТекст());
ЗаписьТекста.ЗаписатьСтроку("");
// третий файл, закрывающий параметры
имяФайлаСПараметрами = ПолучитьимяВременногоФайла("txt");
ЗаписьТекста = Новый ЗаписьТекста(имяФайлаСПараметрами);
ЗаписьТекста.ЗаписатьСтроку("");
ЗаписьТекста.ЗаписатьСтроку("--"+boundary+"--");
ЗаписьТекста.Закрыть(); // заканчиваем работу с файлом 3
массивФайлов.Добавить(имяФайлаСПараметрами); // добавляем 3-ий файл, закрывающий параметры
// результирующий файл, который и будет отправлен
имяФайлаОтправки = ПолучитимяВременногоФайла("out");
// объединим все файлы
ОбъединитьФайлы(массивФайлов, имяФайлаОтправки);
ФайлОтправки = Новый Файл(имяФайлаОтправки);
РазмерФайлаОтправки = XMLСтрока(ФайлОтправки.Размер());
// передадим данные на сервер
Заголовки = Новый Соответствие();
Заголовки.Вставить("Content-Type", "multipart/form-data, boundary="+boundary);
Заголовки.Вставить("Content-Lenght", РазмерФайлаОтправки);
Соединение = Новый HTTPСоединение("www.mysite.com");
Соединение.ОтправитьДляОбработки(имяФайлОтправки, "postFile.php", имяВыходногоФайла, Заголовки);
Ну вот, вроде бы, и все, что я хотел рассказать о способах передачи файлов и данных на веб-сервер из 1С. Если что-то не понятно, что-то хотите уточнить или нашли ошибки - пишите в комментариях.
Автор:
Павел Категория:
Работа с Интернет, Почтой (Mail), FTP Планы обмена и их использование Для того чтобы существовала возможность обмена какими-либо данными с кем-либо, необходимо некоторым образом идентифицировать тех, с кем мы будем обмениваться, и для каждого из них описать перечень обмена
Обе эти задачи позволяет решать прикладной объект конфигурации
План обмена .
При помощи планов обмена мы получаем информацию о том, какие элементы данных были изменены и в какой узел обмена их необходимо передать. Это возможно благодаря тому, что планы обмена содержат механизм регистрации изменений. Информация об измененных данных переносится с помощью сообщений, инфраструктура которых также поддерживается планами обмена.
Подобно тому, как элементами данных справочника являются элементы справочника, элементами данных плана обмена являются узлы плана обмена. Каждый узел идентифицирует участника обмена по данному плану обмена. Кроме этого в каждом плане обмена всегда существует один предопределенный узел, идентифицирующий данную информационную базу.
В состав данных, которыми может производиться обмен, входят элементы информационных структур базы данных, которые описываются следующими объектами встроенного языка:
Константа.МенеджерЗначения.<имя>;
СправочникОбъект.<имя>;
ДокументОбъект.<имя>;
ПоследовательностьНаборЗаписей.<имя>;
ПланВидовХарактеристикОбъект.<имя>;
ПланСчетовОбъект.<имя>;
ПланВидовРасчетаОбъект.<имя>;
РегистрСведенийНаборЗаписей.<имя>;
РегистрНакопленияНаборЗаписей.<имя>;
РегистрБухгалтерииНаборЗаписей.<имя>;
РегистрРасчетаНаборЗаписей.<имя>;
ПерерасчетНаборЗаписей.<имя>;
БизнесПроцессОбъект.<имя>;
ЗадачаОбъект.<имя>;
УдалениеОбъекта.
При описании состава данных плана обмена разработчик имеет возможность указать для каждого типа объектов признак Авторегистрация. Он определяет, каким образом план обмена будет отслеживать изменения этих данных.
Создание плана обмена Филиалы
Состав данных обмена должен выглядеть следующим образом:
Теперь с помощью конструктора создадим основную форму узла, чтобы описать в ней некоторые действия, которые должны выполняться при создании нового узла обмена.
Суть этих действий будет заключаться в том, что при создании нового узла обмена мы должны будем сформировать для него все необходимые записи регистрации изменений для всех объектов конфигурации, входящих в данный план обмена. Это будет своего рода начальная синхронизация узла обмена всеми данными обмена.
Прежде всего, опишем в модуле формы узла служебную переменную, которая будет хранить признак того, является ли записываемый узел новым или нет.
Перем РегистрацияВНовыйУзел;
Затем создадим обработчик события формы ПередЗаписью.
Код 1C v 8.х Процедура ПередЗаписью(Отказ)
РегистрацияВНовыйУзел = ЭтоНовый();
КонецПроцедуры
Этот обработчик и будет устанавливать значение нашей служебной переменной в Истина в случае записи нового узла плана обмена.
После этого создадим обработчик события формы ПриЗаписи.
Код 1C v 8.х Процедура ПриЗаписи(Отказ)
Если РегистрацияВНовыйУзел Тогда
// Регистрация изменений всех данных для узла
ПланыОбмена.ЗарегистрироватьИзменения(Ссылка);
КонецЕсли;
КонецПроцедуры
Создание обработки Обмен данными
Откроем конфигуратор и создадим новый объект конфигурации Обработка с именем ОбменДанными. Перейдем на закладку Прочее и откроем модуль объекта.
Создадим в нем процедуру ОбменСФилиалами.
Код 1C v 8.х Процедура ОбменСФилиалами() Экспорт
ВыборкаУзлов = ПланыОбмена.Филиалы.Выбрать();
Пока ВыборкаУзлов.Следующий() Цикл
// Произвести обмен данными со всеми узлами, кроме текущего (ЭтотУзел)
Если ВыборкаУзлов.Ссылка <> ПланыОбмена.Филиалы.ЭтотУзел() Тогда
УзелОбъект = ВыборкаУзлов.ПолучитьОбъект();
// Получить сообщение
УзелОбъект.ПрочитатьСообщениеСИзменениями();
// Сформировать сообщение
УзелОбъект.ЗаписатьСообщениеСИзменениями();
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Теперь создадим основную форму обработки и в обработчик события нажатия кнопки Выполнить – КнопкаВыполнитьНажатие вставим вызов процедуры ОбменСФилиалами().
Код 1C v 8.х Процедура КнопкаВыполнитьНажатие(Элемент)
ОбменСФилиалами();
КонецПроцедуры
Создание процедуры записи данных
Сами процедуры записи и чтения данных обмена мы разместим в модуле объекта План обмена Филиалы. Сначала создадим процедуру, которая используется нами при обмене данными, – ЗаписатьСообщениеСИзменениями.
Код 1C v 8.х Процедура ЗаписатьСообщениеСИзменениями() Экспорт
Сообщить("-------- Выгрузка в узел " + Строка(ЭтотОбъект) + " ---------");
Каталог = КаталогВременныхФайлов();
// Сформировать имя временного файла
ИмяФайла = Каталог +?(Прав(Каталог, 1) = "\","", "\") + "Message"
+ СокрЛП(ПланыОбмена.Филиалы.ЭтотУзел().Код) + "_" +
СокрЛП(Ссылка.Код) + ".xml";
// Создать объект записи XML
// *** Запись XML-документов
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл(ИмяФайла);
ЗаписьXML.ЗаписатьОбъявлениеXML();
// *** Инфраструктура сообщений
ЗаписьСообщения = ПланыОбмена.СоздатьЗаписьСообщения();
ЗаписьСообщения.НачатьЗапись(ЗаписьXML, Ссылка);
Сообщить("Номер сообщения: " + ЗаписьСообщения.НомерСообщения);
// Получить выборку измененных данных
// *** Механизм регистрации изменений
ВыборкаИзменений =ПланыОбмена.ВыбратьИзменения(ЗаписьСообщения.Получатель,
ЗаписьСообщения.НомерСообщения);
Пока ВыборкаИзменений.Следующий() Цикл
// Записать данные в сообщение
// *** XML-сериализация
ЗаписатьXML(ЗаписьXML, ВыборкаИзменений.Получить());
КонецЦикла;
ЗаписьСообщения.ЗакончитьЗапись();
ЗаписьXML.Закрыть();
Сообщить("-------- Конец выгрузки------------");
КонецПроцедуры
На этом создание процедуры записи данных обмена закончено.
Создание процедуры чтения данных
Код 1C v 8.х Процедура ПрочитатьСообщениеСИзменениями() Экспорт
Каталог = КаталогВременныхФайлов();
// Сформировать имя файла
ИмяФайла = Каталог +?(Прав(Каталог, 1) = "\", "", "\") + "Message"
+ СокрЛП(Ссылка.Код) + "_" +
СокрЛП(ПланыОбмена.Филиалы.ЭтотУзел().Код) + ".xml";
Файл = Новый Файл(ИмяФайла);
Если Не Файл.Существует() Тогда
Возврат;
КонецЕсли;
// *** Чтение документов XML
// Попытаться открыть файл
ЧтениеXML = Новый ЧтениеXML;
Попытка
ЧтениеXML.ОткрытьФайл(ИмяФайла);
Исключение
Сообщить("Невозможно открыть файл обмена данными.");
Возврат;
КонецПопытки;
Сообщить("-------- Загрузка из " + Строка(ЭтотОбъект) + "------------");
Сообщить(" - Считывается файл " + ИмяФайла);
// Загрузить из найденного файла
// *** Инфраструктура сообщений
ЧтениеСообщения = ПланыОбмена.СоздатьЧтениеСообщения();
// Читать заголовок сообщения обмена данными - файла XML
ЧтениеСообщения.НачатьЧтение(ЧтениеXML);
// Сообщение предназначено не для этого узла
Если ЧтениеСообщения.Отправитель <> Ссылка Тогда
ВызватьИсключение "Неверный узел";
КонецЕсли;
// Удаляем регистрацию изменений
// для узла отправителя сообщения
// *** Служба регистрации изменений
ПланыОбмена.УдалитьРегистрациюИзменений(ЧтениеСообщения.Отправитель,ЧтениеСообщения.НомерПринятого);
// Читаем данные из сообщения
// *** XML-сериализация
Пока ВозможностьЧтенияXML(ЧтениеXML) Цикл
// Читаем очередное значение
Данные = ПрочитатьXML(ЧтениеXML);
// Записать полученные данные
Данные.ОбменДанными.Отправитель = ЧтениеСообщения.Отправитель;
Данные.ОбменДанными.Загрузка = Истина;
Данные.Записать();
КонецЦикла;
ЧтениеСообщения.ЗакончитьЧтение();
ЧтениеXML.Закрыть();
УдалитьФайлы(ИмяФайла);
Сообщить("-------- Конец загрузки------------");
КонецПроцедуры
Категория:
Конвертация данных, Обмен, Перенос ZIP-архив Чтение Для того чтобы прочитать файлы из ZIP-архива необходимо выполнить несколько простых действий:
- Открыть необходимый архив
- Распаковать файлы
Создание объекта
ЧтениеZIPФайла можно осуществить двумя путями - создать инициализированный объект или создав неинициализированный объект вызвать у него метод Открыть(). В обоих случаях состав параметров является одинаковым. В самом простом случае требуется указать только имя архивного файла, с которым необходимо работать.
Для открытия архива требуется указать:
Имя файла, который требуется открыть. Этот параметр является обязательным.
Пароль доступа к архиву.
После того, как архив успешно открыт, можно получить информацию о файлах, хранящихся внутри него. Для этого у объекта ЧтениеZIPФайла предусмотрено свойство Элементы, которое предоставляет доступ к коллекции элементов ZIP файла.
Для каждого элемента можно получить разнообразную информацию о его имени, времени его модификации, его атрибутах, а также узнать является ли данный элемент зашифрованным.
После получения информации о элементах их можно распаковать на диск. Это возможно сделать двумя методами:
Воспользоваться методом ИзвлечьВсе().
Воспользоваться методом Извлечь().
Метод ИзвлечьВсе() распаковывает все файлы в архиву по указанному пути. Второй параметр данного метода определяет возможность восстановления исходных путей файлов.
Метод Извлечь() распаковывает указанный элемент коллекции из свойства Элементы по указанному пути. Второй параметр данного метода аналогичен тому же параметру метода ИзвлечьВсе(). Наибольший интерес представляет третий параметр данного метода - Пароль. В нем можно указать индивидуальный пароль для элемента архива, в случае если он зашифрован паролем отличным от других файлов.
После того, как архив нам больше не нужен можно завершить работу с ним вызвав метод Закрыть().
Код 1C v 8.х Сообщить("Распаковка файла - " + ИмяАрхивногоФайла);
Сейчас = ТекущаяДата();
// Откроем файл для чтения
ЧтениеZIP = Новый ЧтениеZipФайла(ИмяАрхивногоФайла,
ПарольАрхивногоФайла);
// Сообщим комментарий архива
Сообщить("Комментарий:");
Сообщить(ЧтениеZIP.Комментарий);
// Распакуем все файлы из архива
ЧтениеZIP.ИзвлечьВсе(ПапкаНазначения, РежимВосстановленияПутейФайловZIP.НеВосстанавливать);
// Распакуем файлы по одиночке
Для Каждого Элемент Из ЧтениеZIP.Элементы Цикл
Сообщить("Распаковка файла:" + Элемент.ПолноеИмя);
ЧтениеZIP.Извлечь(Элемент,
ПапкаНазначения,
РежимВосстановленияПутейФайловZIP.Восстанавливать,
? (Элемент.Зашифрован, ПарольАрхивногоФайла, ""));
КонецЦикла;
ЧтениеZIP.Закрыть();
// Сообщим время, потребовавшееся для работы
Сообщить("Распаковка заняла " + (ТекущаяДата() - Сейчас) + " секунд(ы)");
Категория:
Работа с Файлами и Каталогами Как удалить Файл, Каталог? Функция Удаляет указанные файлы.
УдалитьФайлы(<Путь>, <Маска>)
Параметры: <Путь> (обязательный) Тип: Строка. Путь к удаляемым файлам.
<Маска> (необязательный) Тип: Строка. Маска для выбора удаляемых файлов. В строке маски допускается использование символа "*" (звездочка), обозначающего любое число произвольных символов, и "?" (знак вопроса), обозначающего один произвольный символ.
!!! - Если <Маска> не указана, то удаляются все файлы и каталог <Путь>.
Для удаления одного файла, можно передать его полное имя через первый параметр, либо передать путь к нему через первый параметр, а его короткое имя - через второй.
Удаление файлов производится, если в указанных файлах не установлено свойство "Только чтение". В противном случае возникает сообщение об ошибке.
Допускается использование схем http, https и ftp для адресации файлов. При использовании этих схем в адресах необходимо указывать прямые слеши '/', а не обратные '\'.
Код 1C v 8.х // Удаление каталога и всех вложенных в него каталогов и файлов
Попытка
УдалитьФайлы("C:\temp\Works");
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
Код 1C v 8.2 УП // Удалим в каталоге все файлы CSV
Попытка
УдалитьФайлы(КаталогВыгрузкиДанных, "*.csv");
Исключение
#Если Клиент Тогда
Сообщить(ОписаниеОшибки());
#КонецЕсли
КонецПопытки;
В 7-рке для удаления используется
Код 1C v 7.x ФС.УдалитьКаталог(Стр);
//или
ФС.УдалитьФайл(Стр);
Как удалить каталог с файлами?
Код 1C v 7.x // пример привел smaharbA
//Данный пример не работает, если в папке есть файлы с атрибутами только для чтения и системные
Функция Рекурсия(Знач Путь,Сп)
Перем А;
ФСО=СоздатьОбъект("ФС");
Стр=ФСО.НайтиПервыйФайл(Путь+"\*.*");
Пока ПустоеЗначение(Стр)=0 Цикл
Если (Стр<>"..") и (Стр<>".") Тогда
Представление="";
Для к=1 По СтрЧислоВхождений(Путь+"\"+Стр,"\") Цикл
Представление=Представление+"\";
КонецЦикла;
Сп.ДобавитьЗначение(Путь+"\"+Стр,Представление+Стр);
ФСО.АтрибутыФайла(Путь+"\"+Стр,,А);
Если Сред(А,4,1)="1" Тогда
Рекурсия(Путь+"\"+Стр,Сп);
КонецЕсли;
КонецЕсли;
Стр=ФСО.НайтиСледующийФайл();
КонецЦикла;
КонецФункции // Рекурсия
//*******************************************
Процедура Сформировать()
Перем Каталог,А;
Если ФС.ВыбратьКаталог(Каталог,"")=0 Тогда
Возврат;
КонецЕсли;
Сп=СоздатьОбъект("СписокЗначений");
Рекурсия(Каталог,Сп);
Сп.СортироватьПоПредставлению(0);
Для к=1 По Сп.РазмерСписка() Цикл
Стр=Сп.ПолучитьЗначение(к);
ФС.АтрибутыФайла(Стр,,А);
Если Сред(А,4,1)="1" Тогда
ФС.УдалитьКаталог(Стр);
Иначе
ФС.УдалитьФайл(Стр);
КонецЕсли;
КонецЦикла;
ФС.УстТекКаталог(Каталог+"\..\");
ФС.УдалитьКаталог(Каталог);
КонецПроцедуры
Категория:
Работа с Файлами и Каталогами