Перем Л_Лев_Фиг_Скобка, Л_Прав_Фиг_Скобка, Л_Лев_Кв_Скобка, Л_Прав_Кв_Скобка, Л_Кавычка, Л_Экран, Л_Двоеточие, Л_Запятая, Л_Число, Л_Строка, Л_Константа, Л_Финиш; Перем Цифры1_9, Цифры0_9, ПервыеСимволыКонстант, ОдносимвольныеЛексемы; Перем НомЛексемы, ТекЛексема; Перем JSON_Error; Перем В_Массив, В_Объект, В_Значение; //***** Перем НомерСимвола; Перем ФлагОшибки; Перем СписокСтроковыхКонстант; Перем СтекЛексем; Перем АнализируемаяСтрока; //***** Перем ТекКаталог, ТекФайл; //***** Функция ПолучитьОбъект_ТЗ() Далее Функция ПолучитьМассив_ТЗ() Далее //***** Функция ТекущиеСимволы(Сколько) Возврат Сред(АнализируемаяСтрока, НомерСимвола, Сколько); КонецФункции //***** Функция ПрошлыйСимвол(Сдвиг) Возврат Сред(АнализируемаяСтрока, НомерСимвола - Сдвиг, 1); КонецФункции //***** Процедура ДобавитьЛексему(Лексема, Значение, Сдвиг) СтекЛексем.НоваяСтрока(); СтекЛексем.Лексема = Лексема; СтекЛексем.Значение = Значение; НомерСимвола = НомерСимвола + Сдвиг; КонецПроцедуры //***** Процедура ОбвестиОбласть(Обл) Обл.РамкаСнизу(1); Обл.РамкаСверху(1); Обл.РамкаСлева(1); Обл.РамкаСправа(1); КонецПроцедуры //***** Процедура НапечататьТЗ(Таб, ТЗ, НомС, НомК) Перем Тип, Обл1, НС, КС, Ключ, Зн, Обл2; Тип = ТЗ.ПолучитьЗначение(1, 1); НомС = НомС + 1; Обл1 = Таб.Область(НомС, НомК); ОбвестиОбласть(Обл1); Если Тип = В_Значение Тогда ТипЗн = ТЗ.ПолучитьЗначение(2, 1); Обл1.Текст = ТЗ.ПолучитьЗначение(2, 2); Обл1.ГоризонтальноеПоложение(1); Если ТипЗн = Л_Число Тогда Обл1.ГоризонтальноеПоложение(2); ИначеЕсли ТипЗн = Л_Константа Тогда Обл1.Полужирный(1); ИначеЕсли ТипЗн = Л_Строка Тогда Обл1.Контроль(4); КонецЕсли; Возврат; ИначеЕсли (Тип = В_Объект) Или (Тип = В_Массив) Тогда Обл1.Текст = Тип; Обл1.Полужирный(1); Обл1.ЦветФона(12648447); Обл1.РамкаСнизу(5); КС = ТЗ.КоличествоСтрок(); Для НС = 2 По КС Цикл НомС = НомС + 1; Обл2 = Таб.Область(НомС, НомК); Обл2.Текст = ТЗ.ПолучитьЗначение(НС, 1); Если Тип = В_Массив Тогда Обл2.ГоризонтальноеПоложение(2); КонецЕсли; ОбвестиОбласть(Обл2); НомС = НомС - 1; НапечататьТЗ(Таб, ТЗ.ПолучитьЗначение(НС, 2), НомС, НомК + 1); КонецЦикла; Иначе Сообщить("Фигня " + Тип, "!"); КонецЕсли; КонецПроцедуры //***** Процедура ВыравнятьТЗ(Таб, ОграничениеШирины) Перем НомерКол, НомерСтр, МаксШирина, Обл, ТекШирина, ТекДлина; Для НомерКол = 1 По Таб.ШиринаТаблицы() Цикл МаксШирина = 0; Для НомерСтр = 1 По Таб.ВысотаТаблицы() Цикл Обл = Таб.Область(НомерСтр, НомерКол); ТекШирина = Обл.ШиринаСтолбца(); ТекДлина = СтрДлина(СокрЛП(Обл.Текст)); МаксШирина = Макс(МаксШирина, ТекШирина, ТекДлина); КонецЦикла; Таб.Область(, НомерКол).ШиринаСтолбца(Мин(МаксШирина, ОграничениеШирины)); КонецЦикла; КонецПроцедуры //***** Процедура Напечатать_ТЗ(ТЗ) Перем Таб, НС, НК, МаксШирина, ТекДлина, Обл; Таб = СоздатьОбъект("Таблица"); МаксНК = 1; НС = 0; НК = 1; НапечататьТЗ(Таб, ТЗ, НС, НК); ВыравнятьТЗ(Таб, 30); Таб.Область(1, 1, Таб.ВысотаТаблицы(), Таб.ШиринаТаблицы()).ВертикальноеПоложение(2); Таб.Опции(0, 0); Таб.Показать("JSON"); КонецПроцедуры //***** Функция Ошибка() ФлагОшибки = 1; Возврат 0; КонецФункции //***** Функция ЧитатьКонстанту(ПервСимвол) Перем КонстантаСтр, ДлинаКонстанты; КонстантаСтр = СписокСтроковыхКонстант.Получить(ПервСимвол); ДлинаКонстанты = СтрДлина(КонстантаСтр); Если ТекущиеСимволы(ДлинаКонстанты) = КонстантаСтр Тогда ДобавитьЛексему(Л_Константа, КонстантаСтр, ДлинаКонстанты); Возврат 1; Иначе Возврат Ошибка(); КонецЕсли; КонецФункции //***** Процедура ДописатьСимвол(Стр) Стр = Стр + ТекущиеСимволы(1); НомерСимвола = НомерСимвола + 1; КонецПроцедуры //***** Функция ЧитатьЧисло() Перем ЧислоСтр; ЧислоСтр = ""; Если ТекущиеСимволы(1) = "-" Тогда ДописатьСимвол(ЧислоСтр); КонецЕсли; Если Найти(Цифры1_9, ТекущиеСимволы(1)) > 0 Тогда // не с нуля ДописатьСимвол(ЧислоСтр); Пока Найти(Цифры0_9, ТекущиеСимволы(1)) > 0 Цикл // любые цыфры ДописатьСимвол(ЧислоСтр); КонецЦикла; ИначеЕсли ТекущиеСимволы(1) = "0" Тогда //с нуля - ничего дальше ДописатьСимвол(ЧислоСтр); Иначе Возврат Ошибка(); КонецЕсли; Если ТекущиеСимволы(1) = "." Тогда // десятичная точка ДописатьСимвол(ЧислоСтр); Пока Найти(Цифры0_9, ТекущиеСимволы(1)) > 0 Цикл // любые цыфры ДописатьСимвол(ЧислоСтр); КонецЦикла; КонецЕсли; Если ВРег(ТекущиеСимволы(1)) = "E" Тогда // значок e больное или маленькое ДописатьСимвол(ЧислоСтр); Если Найти("+-", ТекущиеСимволы(1)) > 0 Тогда // унарный знак для порядка ДописатьСимвол(ЧислоСтр); КонецЕсли; Пока Найти(Цифры0_9, ТекущиеСимволы(1)) > 0 Цикл // любые цыфры ДописатьСимвол(ЧислоСтр); КонецЦикла; КонецЕсли; ДобавитьЛексему(Л_Число, ЧислоСтр, 0); Возврат 1; КонецФункции //***** Функция ЧитатьСтроку() Перем СтрокаСтр; СтрокаСтр = ""; НомерСимвола = НомерСимвола + 1; Пока (ТекущиеСимволы(1) <> Л_Кавычка) Или ((ТекущиеСимволы(1) = Л_Кавычка) И (ПрошлыйСимвол(1) = Л_Экран) И (ПрошлыйСимвол(2) <> Л_Экран)) Цикл ДописатьСимвол(СтрокаСтр); КонецЦикла; ДобавитьЛексему(Л_Строка, СтрокаСтр, 1); Возврат 1; КонецФункции //***** Функция ПрочитатьФайл(ИмяФайла) Перем Т, НомерСтрокиФайла, СтрокаРез; Т = СоздатьОбъект("Текст"); Т.Открыть(ИмяФайла); СтрокаРез = ""; Для НомерСтрокиФайла = 1 По Т.КоличествоСтрок() Цикл СтрокаРез = СтрокаРез + Т.ПолучитьСтроку(НомерСтрокиФайла); КонецЦикла; Возврат СтрокаРез; КонецФункции //***** Функция СледующаяЛексема() НомЛексемы = НомЛексемы + 1; СтекЛексем.ПолучитьСтрокуПоНомеру(НомЛексемы); ТекЛексема = СтекЛексем.Лексема; Возврат 1; КонецФункции //***** Функция ОшибкаЛексемы() Перем РезСтр, НомСтр, ТЛ, ТС; Сообщить("Ошибочная лексема № " + НомЛексемы + " : <" + ТекЛексема + ">", "!"); РезСтр = ""; Для НомСтр = НомЛексемы + 1 По СтекЛексем.КоличествоСтрок() Цикл СтекЛексем.ПолучитьСтрокуПоНомеру(НомСтр); ТЛ = СтекЛексем.Лексема; Если ТЛ = Л_Строка Тогда ТС = "<" + ТЛ + "(" + СтекЛексем.Значение + ")>"; ИначеЕсли ТЛ = Л_Константа Тогда ТС = "<" + ТЛ + "(" + СтекЛексем.Значение + ")>"; Иначе ТС = "<" + ТЛ + ">"; КонецЕсли; РезСтр = РезСтр + ТС + ","; КонецЦикла; Сообщить(Лев(РезСтр, 400), "!"); Возврат 0; КонецФункции //***** Процедура ДобавитьПару(ТЗ, Ключ, Значение) ТЗ.НоваяСтрока(); ТЗ.Ключ = Ключ; ТЗ.Значение = Значение; КонецПроцедуры //***** Функция НоваяТЗ(Тип) Перем _ТЗ; _ТЗ = СоздатьОбъект("ТаблицаЗначений"); _ТЗ.НоваяКолонка("Ключ"); _ТЗ.НоваяКолонка("Значение"); ДобавитьПару(_ТЗ, Тип, ""); Возврат _ТЗ; КонецФункции //***** Функция ПолучитьПроизвольноеЗначение_ТЗ() Перем ТЗ; Если (ТекЛексема = Л_Строка) Или (ТекЛексема = Л_Число) Или (ТекЛексема = Л_Константа) Тогда ТЗ = НоваяТЗ(В_Значение); ДобавитьПару(ТЗ, ТекЛексема, СтекЛексем.Значение); СледующаяЛексема(); Возврат ТЗ; ИначеЕсли ТекЛексема = Л_Лев_Фиг_Скобка Тогда Возврат ПолучитьОбъект_ТЗ(); ИначеЕсли ТекЛексема = Л_Лев_Кв_Скобка Тогда Возврат ПолучитьМассив_ТЗ(); КонецЕсли; Возврат ОшибкаЛексемы(); КонецФункции //***** Функция ДобавитьКлючЗначение(ТЗ) Перем НовКлюч, НовЗначение; Если ТекЛексема <> Л_Строка Тогда Возврат 0; КонецЕсли; НовКлюч = СтекЛексем.Значение; СледующаяЛексема(); Если ТекЛексема <> Л_Двоеточие Тогда Возврат ОшибкаЛексемы(); КонецЕсли; СледующаяЛексема(); НовЗначение = ПолучитьПроизвольноеЗначение_ТЗ(); Если НовЗначение = 0 Тогда Возврат 0; КонецЕсли; ДобавитьПару(ТЗ, НовКлюч, НовЗначение); Возврат 1; КонецФункции //***** Функция ПолучитьОбъект_ТЗ() Перем ТЗ; ТЗ = НоваяТЗ(В_Объект); СледующаяЛексема(); Если ТекЛексема = Л_Прав_Фиг_Скобка Тогда // пустой объект СледующаяЛексема(); Возврат ТЗ; КонецЕсли; Если ДобавитьКлючЗначение(ТЗ) = 0 Тогда // первая пара ключ-значение Возврат 0; КонецЕсли; Пока ТекЛексема = Л_Запятая Цикл // пока запятые СледующаяЛексема(); Если ДобавитьКлючЗначение(ТЗ) = 0 Тогда // пара ключ-значение Возврат 0; КонецЕсли; КонецЦикла; Если ТекЛексема = Л_Прав_Фиг_Скобка Тогда СледующаяЛексема(); Возврат ТЗ; КонецЕсли; Возврат 0; КонецФункции //***** Функция ПолучитьМассив_ТЗ() Перем ТЗ, _Ключ, _Значение; ТЗ = НоваяТЗ(В_Массив); СледующаяЛексема(); Если ТекЛексема = Л_Прав_Кв_Скобка Тогда СледующаяЛексема(); Возврат ТЗ; КонецЕсли; _Значение = ПолучитьПроизвольноеЗначение_ТЗ(); Если _Значение = 0 Тогда Возврат 0; КонецЕсли; _Ключ = 0; // JS - индексы массиворв с нуля ДобавитьПару(ТЗ, _Ключ, _Значение); Пока ТекЛексема = Л_Запятая Цикл СледующаяЛексема(); _Значение = ПолучитьПроизвольноеЗначение_ТЗ(); Если _Значение = 0 Тогда Возврат 0; КонецЕсли; _Ключ = _Ключ + 1; ДобавитьПару(ТЗ, _Ключ, _Значение); КонецЦикла; Если ТекЛексема = Л_Прав_Кв_Скобка Тогда СледующаяЛексема(); Возврат ТЗ; КонецЕсли; Возврат 0; КонецФункции //***** Функция ПрочитатьОбъект_ТЗ() Перем Рез; НомЛексемы = 0; СледующаяЛексема(); Если ТекЛексема = Л_Лев_Фиг_Скобка Тогда Рез = ПолучитьОбъект_ТЗ(); ИначеЕсли ТекЛексема = Л_Лев_Кв_Скобка Тогда Рез = ПолучитьМассив_ТЗ(); Иначе Рез = ПолучитьПроизвольноеЗначение_ТЗ(); КонецЕсли; Если (Рез = 0) Или (ТекЛексема <> Л_Финиш) Тогда ОшибкаЛексемы(); Возврат 0; КонецЕсли; Возврат Рез; КонецФункции //***** Функция СгенерироватьТЗ(НачАнализируемаяСтрока) Перем НачальныйСимвол, Рез; АнализируемаяСтрока = НачАнализируемаяСтрока; СтекЛексем = СоздатьОбъект("ТаблицаЗначений"); СтекЛексем.НоваяКолонка("Лексема" , "Строка"); СтекЛексем.НоваяКолонка("Значение", "Строка"); ФлагОшибки = 0; НомерСимвола = 1; Пока НомерСимвола <= СтрДлина(АнализируемаяСтрока) Цикл НачальныйСимвол = ТекущиеСимволы(1); Если Найти(" " + Симв(9), НачальныйСимвол) > 0 Тогда // пробелы и разделители строк пропускаем НомерСимвола = НомерСимвола + 1; ИначеЕсли НачальныйСимвол = Л_Кавычка Тогда // кавычка - читаем строку ЧитатьСтроку(); ИначеЕсли Найти(ОдносимвольныеЛексемы, НачальныйСимвол) > 0 Тогда ДобавитьЛексему(НачальныйСимвол, "", 1); ИначеЕсли Найти(ПервыеСимволыКонстант, НачальныйСимвол) > 0 Тогда // первая буква из начала константы - константа null, true, false Если ЧитатьКонстанту(НачальныйСимвол) = 0 Тогда Прервать; КонецЕсли; ИначеЕсли Найти("-" + Цифры0_9, НачальныйСимвол) > 0 Тогда // число Если ЧитатьЧисло() = 0 Тогда Прервать; КонецЕсли; Иначе // иных вариантов нет Сообщить("========= " + НомерСимвола, "!"); Сообщить(НачальныйСимвол, "!"); Сообщить("<" + НачальныйСимвол + "> " + КодСимв(НачальныйСимвол), "!"); Сообщить(ТекущиеСимволы(100), "!"); Возврат 0; КонецЕсли; КонецЦикла; Если ФлагОшибки <> 0 Тогда Сообщить("Ошибка парсинга JSON - выражения", "!"); Возврат 0; ИначеЕсли СтекЛексем.КоличествоСтрок() = 0 Тогда Сообщить("Пустой стек", "!"); Возврат 0; КонецЕсли; ДобавитьЛексему(Л_Финиш, "", 0); Возврат ПрочитатьОбъект_ТЗ(); КонецФункции //***** Функция JSON_Error(Стр = "") Если Стр <> "" Тогда Сообщить("JSON-ОШИБКА: " + Стр, "!"); КонецЕсли; Возврат JSON_Error; КонецФункции //***** Функция JSON_Type(Парам) Если ТипЗначенияСтр(Парам) <> "ТаблицаЗначений" Тогда Возврат JSON_Error(); ИначеЕсли Парам.КоличествоКолонок() <> 2 Тогда Возврат JSON_Error(); ИначеЕсли Парам.КоличествоСтрок() < 2 Тогда Возврат JSON_Error(); КонецЕсли; Возврат Парам.ПолучитьЗначение(1, 1); КонецФункции //***** Функция JSON_GetValue(Парам, Keys) Перем Тип, До, После, ПозЗакр, Л1, П2, Инд, ИндСтр, НС, КвоСтрок; Тип = JSON_Type(Парам); ПозЗакр = Найти(Keys, "]"); Если ПозЗакр = 0 Тогда ПозЗакр = СтрДлина(Keys) + 1; КонецЕсли; До = Лев(Keys, ПозЗакр); После = Сред(Keys, ПозЗакр + 1); Л1 = Лев(До, 1); П2 = Найти(До, "]"); Если Тип = JSON_Error Тогда Возврат JSON_Error("Параметра"); КонецЕсли; КвоСтрок = Парам.КоличествоСтрок(); Если До = "" Тогда // сам объект Если (Тип = В_Массив) Или (Тип = В_Объект) Тогда Возврат JSON_Error(); ИначеЕсли Тип = В_Значение Тогда Возврат Парам.ПолучитьЗначение(2, 2); Иначе Возврат JSON_Error("№ 1"); КонецЕсли; ИначеЕсли До = ".length" Тогда // размер массива или объекта. Для значения - ошибка Если (Тип = В_Массив) Или (Тип = В_Объект) Тогда Возврат Парам.КоличествоСтрок() - 1; Иначе Возврат JSON_Error("Длина скаляра"); КонецЕсли; ИначеЕсли Л1 = "[" Тогда // размер массива или объекта. Для значения - ошибка Если П2 = 0 Тогда Возврат JSON_Error("Индексация: <" + До + ">"); КонецЕсли; Инд = Сред(До, 2, П2 - 2); Если (Найти("'""", Лев(Инд, 1)) > 0) И (Найти("'""", Прав(Инд, 1)) > 0) Тогда // строковый только объект ИндСтр = Сред(Инд, 2, СтрДлина(Инд) - 2); Если Тип <> В_Объект Тогда Возврат JSON_Error("Строковый индекс <" + ИндСтр + "> только для Объекта"); КонецЕсли; НС = 0; Если Парам.НайтиЗначение(ИндСтр, НС, 1) = 1 Тогда Возврат JSON_GetValue(Парам.ПолучитьЗначение(НС, 2), После); КонецЕсли; Возврат JSON_Error("Нет индекса <" + ИндСтр + ">"); КонецЕсли; ИндЧис = 0 + Инд; Если "" + ИндЧис <> Инд Тогда // защита от <5D> Возврат JSON_Error("Ошибка 1 числового индекса <" + Инд + ">"); ИначеЕсли Цел(ИндЧис) <> ИндЧис Тогда // защита от неЦелого индекса Возврат JSON_Error("Ошибка 2 числового индекса <" + Инд + "> (нецелый)"); ИначеЕсли ИндЧис < 0 Тогда Возврат JSON_Error("Ошибка 3 числового индекса <" + Инд + "> (отрицательный)"); ИначеЕсли ИндЧис > (КвоСтрок - 2) Тогда Возврат JSON_Error("Ошибка 4 числового индекса <" + Инд + "> (" + ИндЧис + ">" + (КвоСтрок - 2) + ")"); КонецЕсли; Возврат JSON_GetValue(Парам.ПолучитьЗначение(ИндЧис + 1, 2), После); Иначе Возврат JSON_Error("Ошибка 5 <" + До + ">"); КонецЕсли; КонецФункции //***** Процедура ПриОткрытии() Перем Рез1, ТипУзла1, Зн1, Значение; ОчиститьОкноСообщений(); СтатусВозврата(0); Рез1 = СгенерироватьТЗ(ПрочитатьФайл(ТекКаталог + "j1.json")); Напечатать_ТЗ(Рез1); ТипУзла1 = JSON_Type(Рез1); Сообщить("Тип узла: " + ТипУзла1); Зн1 = JSON_GetValue(Рез1, ".length"); Сообщить("1) Размер: " + Зн1); Зн3 = JSON_GetValue(Рез1, "['1']"); Сообщить("3) ['1']: <" + Зн3 + ">"); Зн4 = JSON_GetValue(Рез1, "[1]"); Сообщить("4) [1]: <" + Зн4 + ">"); Зн5 = JSON_GetValue(Рез1, "['Массив'][6]"); Сообщить("5) [*]: <" + Зн5 + ">"); Зн6 = JSON_GetValue(Рез1, "['Соответствие']['ДопустимоеИмяСвойства']"); Сообщить("6) [*]: <" + Зн6 + ">"); КонецПроцедуры //***** Процедура ДобавитьСтроковуюКонстанту(КонстантаСтр) Перем ПервыйСимвол; ПервыйСимвол = Лев(КонстантаСтр, 1); ПервыеСимволыКонстант = ПервыеСимволыКонстант + ПервыйСимвол; СписокСтроковыхКонстант.Установить(ПервыйСимвол, КонстантаСтр); КонецПроцедуры //***** РасположениеФайла(ТекКаталог, ТекФайл); //***** Л_Лев_Фиг_Скобка = "{"; Л_Прав_Фиг_Скобка = "}"; Л_Лев_Кв_Скобка = "["; Л_Прав_Кв_Скобка = "]"; Л_Двоеточие = ":"; Л_Запятая = ","; Л_Экран = "\"; Л_Кавычка = """"; Л_Финиш = ""; Л_Число = "number"; Л_Строка = "string"; Л_Константа = "const"; ОдносимвольныеЛексемы = Л_Лев_Фиг_Скобка + Л_Прав_Фиг_Скобка + Л_Лев_Кв_Скобка + Л_Прав_Кв_Скобка + Л_Двоеточие + Л_Запятая; //***** Цифры1_9 = "123456789"; Цифры0_9 = "0" + Цифры1_9; //***** В_Массив = "###array"; В_Объект = "###object"; В_Значение = "###value"; //***** СписокСтроковыхКонстант = СоздатьОбъект("СписокЗначений"); ПервыеСимволыКонстант = ""; ДобавитьСтроковуюКонстанту("null"); ДобавитьСтроковуюКонстанту("false"); ДобавитьСтроковуюКонстанту("true"); JSON_Error = "ERROR";
В качестве примера взят файл j1.json :
{
"999": 88,
"Null": null,
"Сэкраном": "\"",
"Ложь": false,
"ОдинСимв": "1",
"1": "11111",
"Пустышка": "",
"Истина": true,
"Число (плавающая точка)": 1.001e-2,
"Число (плавающая)": -1.001e-2,
"Число (фиксированная точка)": -1000.001,
"Дата": "2011-01-01T12:00:00Z",
"Строка (двойная кавычка)": "Двойная кавычка",
"Строка (одинарная кавычка)": "Одинарная кавычка",
"Маскируемые символы": " \\ \/ \b \t \n \f \r \" ",
"Заковыристая строка": "\\n\\",
"Проблемные символы": "Спец. символы: \u0000, \u0001, \u0002, ... , \u001e, \u001f; Юникод символы: \u0421\u0430\u0448\u0430\u0020\u003a\u0029",
"Кириллические символы": "’АБВГҐДЂЃЕ?ЁЄЖЗЅИ?ІЇЙЈКЛЉМНЊОПРСТЋЌУЎФХЦЧЏШЩЪЫЬЭЮЯ",
"Идентификатор": "a763cfbb-f94f-4c67-8e13-0e96a3a7f353",
"Пустой массив": [],
"Пустой объект": {},
"Массив": [
null,
false,
true,
1.001e-2,
-1000.001,
"2011-01-01T12:00:00Z",
"Двойная кавычка",
"Одинарная кавычка",
"a763cfbb-f94f-4c67-8e13-0e96a3a7f353",
[
"Первый элемент",
"Второй элемент"
],
"Имя": "Александр",
"Отчество": "Владимирович",
"Фамилия": "Переверзев"
},
"ДопустимоеИмяСвойства": true,
"Недопустимое Имя Свойства": false
}
"Структура":
"Соответствие":
"Ссылка":
"Ссылка": "00000000-0000-0000-0000-000000000000",
"Представление": "Неизвестная ссылка"
"COMSafeArray": [
0,
1,
2,
3,
4,
5
]
Соединение = Новый HTTPСоединение("export.rbc.ru"); //готовим соединение ИмяФайла = ПолучитьИмяВременногоФайла(".txt"); //строка-образец //http://export.rbc.ru/free/cb.0/free.fcgi?period=DAILY&tickers=USD&d1=18&m1=01&y1=2009&d2=17&m2=02&y2=2009&lastdays=30&separator=TAB&data_format=BROWSER&header=1 //http://export.rbc.ru/free/cb.5/free.fcgi?period=DAILY&tickers=USDEUR_BASKET&d1=08&m1=07&y1=2009&d2=22&m2=07&y2=2009&lastdays=14&separator=TAB&data_format=BROWSER&header=1 СтрокаСоединения="/free/"+Источник+"/free.fcgi?period=DAILY&tickers="+Валюта1+"&d1="+День1+"&m1="+Месяц1+"&y1="+Год1+"&d2="+День2+"&m2="+Месяц2+"&y2="+Год2+"&separator=%7C&data_format=BROWSER"; СтрокаСоединения=СтрЗаменить(СтрокаСоединения," ",""); Попытка //соединяемся Соединение.Получить(СтрокаСоединения,ИмяФайла); Исключение Сообщить("Невозможно получить курс по адресу http://export.rbc.ru"+СтрокаСоединения); КонецПопытки; КурсыТекст=Новый ТекстовыйДокумент; //читаем результат запроса КурсыТекст.Прочитать(ИмяФайла);
// еще пример Функция ПолучитьКакСтроку(Адресс) соминет = Новый COMОбъект("MSXML2.XMLHTTP"); соминет.open ("GET", Адресс, Ложь); соминет.send(); Возврат соминет.responseText; КонецФункции Функция ПреобразоватьДату(дат) // Медот преобразования даты времен 1Сv7 //Т=Строка(Дат); //Возврат Сред(Т,7,4)+"/"+Сред(Т,4,2)+"/"+Лев(Т,2); Возврат Формат(Дат,"ДФ=""гггг/ММ/дд"""); КонецФункции Процедура КнопкаЗагрузитьКурсы(Элемент) //Список - список валют Для А = 1 по Список.Количество() цикл Если Список[а-1].Пометка тогда Сообщить("Загружаем курсы для "+Строка(Список[а-1].Значение)); Код = Строка(Список[а-1].Значение.Код); Дат = ПериодС; Пока Дат <= ПериодПо цикл Стр = ПолучитьКакСтроку("http://cbrates.rbc.ru/tsv/"+Код+"/"+ПреобразоватьДату(Дат)+".tsv"); Поз = Найти(Стр,Символы.Таб); Если Поз = 0 Тогда Дат = Дат + 86400; Продолжить; КонецЕсли; Кратность = Число(СокрЛП(Лев(стр,Поз-1))); курс = Число(СокрЛП(Сред(Стр,Поз+1,СтрДлина(Стр)-Поз))); Сообщить("Дата="+Строка(Дат)+" Курс="+Строка(курс)+" Кратность="+Строка(Кратность)); Запись = РегистрыСведений.КурсыВалют.СоздатьМенеджерЗаписи(); Запись.Период = Дат; Запись.Валюта = Список[а-1].Значение.Ссылка; Запись.Курс = Курс; Запись.Кратность = Кратность; Запись.Записать(Истина); Дат = Дат + 86400; КонецЦикла; КонецЕсли; КонецЦикла; КонецПроцедуры
// Взято с http://www.1c-club.kz IUnknown //Небольшая обработка для получения курса валют размещенной на странице Национального Банка РК. //Внимание: работоспособность данной обработки может быть нарушена, если дизайнеры сайта НБ РК изменят формат страницы с //официальным курсом валюта. Но не большой анализ нового формата и работоспособность обработки будет восстановлена. // шаблон для отображаемой на форме таблице значения перем тзПустышка; //******************************************* // ПриНачалеВыбораЗначения(стрНазвание, чисФлаг) // // Параметры: // стрНазвание - Строка. Наименование реквизита формы инициюрующей // вызов процедуры. // чисФлаг - Число. Флаг станадартной обработки иницации нажатия // кнопки выбора значения. // // Возвращаемое значение: // Нет. // // Описание: // Переопределенная процедура инициирующая при нажатии кнопки // выбора значения реквизита формы. // процедура ПриНачалеВыбораЗначения(стрНазвание, чисФлаг) // Если инициировали из реквизита "стрУРЛа" если стрНазвание = "стрУРЛа" тогда // откроем страницу с введенным URL запуститьприложение(стрУРЛа); конецесли; конецпроцедуры //******************************************* // кнПолучить() // // Параметры: // Нет // // Возвращаемое значение: // Нет. // // Описание: // Процедура получающая курсы валют с URL находящегося в // строковом реквизите формы "стрУРЛа". Пытается по указаноому URL // получить страницу и распарсить ее. // // ПРЕДУПРЕЖДЕНИЕ: // В случае измения формата данных представленных на странице, возможно // будет работать не правильно. // процедура кнПолучить() // сгенирим имя файла для временного хранения содержимого // страницы курса валют Национального банка стрИмяФайла = каталогпользователя() + "$$$$.###"; // создадим объект XMLHttpRequest олеХМЛ = создатьобъект("Microsoft.XMLHTTP"); // иницируем его типом запроса и нужным нам URL олеХМЛ.Open("GET", стрУРЛа, 0); // отправим запрос для обработки серверу олеХМЛ.Send(); // создадим "поток" через ADODDB для работы с данными олеАДО = создатьобъект("ADODB.Stream"); // зададим тип и режим потока олеАДО.Mode = 3; олеАДО.Type = 1; // откроем его олеАДО.Open(); // создадим объект для управления скриптами олеШелл = создатьобъект("MSScriptControl.ScriptControl"); // установим язык сценариев олеШелл.Language = "vbscript"; // добавим созданные объекты олеШелл.AddObject("oleADO", олеАДО); олеШелл.AddObject("oleXML", олеХМЛ); // с помощью скрипта запишем в поток ADO данные из // объекта XMLHttpRequest // то есть содержимое страницы олеШелл.Eval("oleADO.Write(oleXML.ResponseBody)"); // запишем данные во временный файл олеАДО.SaveToFile(стрИмяФайла, 2); // закроем данный поток олеАДО.Close(); // для ускорения парсера занесем весь файл в строковую // переменую с разделителем строк // для этого инициализуруем поток установкой // соотвествующим режимом и типом олеАДО.Mode= 3; олеАДО.Type = 2; // так как страница курса валют НБК имеет формат // символов UTF-8, то установим соотвествующий набор олеАДО.CharSet="UTF-8"; // откроем поток олеАДО.Open(); // загрузим содержимое нашего файла в поток олеАДО.LoadFromFile(стрИмяФайла); // обнулим временную строковую переменную стрТемп = ""; // в цикле получим из потока все строки пока олеАДО.EOS() = 0 цикл // и запишем их во временную переменую, добавив разделитель строк стрТемп = стрТемп + олеАДО.ReadText(-2) + разделительстрок; конеццикла; // закроем поток олеАДО.Close(); // удалим временный файл фс.УдалитьФайл(стрИмяФайла); // найдем в строке позицию начала блока с данными о курсе чисПозиция = найти(стрТемп, "Официальные курсы валют на"); если чисПозиция = 0 тогда // если позиции нет ... то мы имем другую страницу // или другой формат страницы... предупреждение("Не получилось получить курсы валют"); иначе // создаим временную таблицу значений // для более шустрого заполения из-за отстуствия вызова // функции перерисовки таблицы при изменении данных тзТемп = создатьобъект("ТаблицаЗначений"); // установим для нее нужный формат тзПустышка.Выгрузить(тзТемп); // отрежем все лишнее стрТемп = сред(стрТемп, чисПозиция); // получим дату курса дтКурса = дата(стрзаменить(стрполучитьстроку(стрТемп, 2), "/", ".")); // первая строка с курсом валюты находится на 18 строке от начала // после удаления мусора чисПозиция = 18; // узнаем сколько всего строк в многострочке чисКоличествоСтрок = стрколичествострок(стрТемп); // получим строку стрТекущая = стрполучитьстроку(стрТемп, чисПозиция); // если в строке есть подстрока ... то значит это наверное очередная валюта пока найти(стрТекущая, "input type=""checkbox"" name=""idval""") > 0 цикл // добавляем новую строку тзТемп.НоваяСтрока(); // получаем строку со смещением 1 от позиции стрТекущая = стрполучитьстроку(стрТемп, чисПозиция + 1); // используя фичу 1С по преобразованию, получим число // за сколько единиц валюты имеем курс в тенге тзТемп.Количество = число(стрТекущая); // путем убирания "мусора" получаем наименование валюты тзТемп.Наименование = сокрлп(стрзаменить(стрзаменить(стрТекущая, тзТемп.Количество, ""), "</td>", "")); // получаем строку со смещением 2 от позиции стрТекущая = стрполучитьстроку(стрТемп, чисПозиция + 2); // убираем html мусор стрТекущая = сокрлп(стрзаменить(стрзаменить(стрТекущая, "<td class=""gen7"" align=""center"">", ""), "</td>", "")); // получаем код валюты тзТемп.Код1 = лев(стрТекущая, 3); // получаем код валюты "Тенге" тзТемп.Код2 = прав(стрТекущая, 3); // получаем строку со смещением 5 от позиции стрТекущая = стрполучитьстроку(стрТемп, чисПозиция + 5); // очищаем от мусора и преобразуем в число... получаем курс тзТемп.Курс = число(стрзаменить(стрзаменить(стрТекущая, "<td class=""gen7"" align=""center"">", ""), "</td>", "")); // увеличиваем позицию на 17 ... чисПозиция = чисПозиция + 17; если чисПозиция > чисКоличествоСтрок тогда // если позици дальше имеющихся строк // то все курсов больше нет стрТекущая = ""; иначе // получаем очередную строку для разбора стрТекущая = стрполучитьстроку(стрТемп, чисПозиция); конецесли; конеццикла; // сформированую таблицу копируем в таблицу на форме тзТемп.Выгрузить(тзКурсов); конецесли; конецпроцедуры //******************************************* // установим значение реквизита текущим URL по которому можно получить курс валют стрУРЛа = "http://www.nationalbank.kz/?docid=460&uid=DD54B73C-802C-E8F0-E27EDF82ECF77C1D"; // формируем формат таблицы тзПустышка = создатьобъект("ТаблицаЗначений"); тзПустышка.НоваяКолонка("Количество", "число", 3, 0, "", 5); тзПустышка.НоваяКолонка("Наименование", "строка", , , "Наименование", 70); тзПустышка.НоваяКолонка("Код1", "строка", 3, , "код", 10); тзПустышка.НоваяКолонка("Код2", "строка", 3, , "код", 10); тзПустышка.НоваяКолонка("Курс", "число", 7, 2, "Курс", 10); // копируем получившийся формат в таблицу на форме тзПустышка.Выгрузить(тзКурсов);