1c 77 выгрузка в JSON

1. slim747 18.02.24 19:02 Сейчас в теме
Добрый день уважаемые программисты. Столкнулся с проблемой выгрузки данных в формат .json. Вроде тема достаточно избитая но грамотного ответа так и не нашел. Проблема осталась, решение ищу. Подскажите, по сути json это тот же текстовый файл, только структуры определенной. Можно ли его создать как текстовый (определенной структуры конечно), а потом под формат .json определить?
По теме из базы знаний
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. user856012 13 18.02.24 19:13 Сейчас в теме
(1)
Можно ли его создать как текстовый (определенной структуры конечно), а потом под формат .json определить?
Не можно, а нужно - просто указать полное (с расширением) имя при сохранении.
3. starjevschik 18.02.24 20:58 Сейчас в теме
Есть целая библиотека, чтобы подружить 7.7. и json. Спасибо добрым людям
//автор Трапезников Дмитрий (trad) trad00@ya.ru

//defcls.prm
//#класс JSON = КОП_JSON.ert
//#{
//#  Неопределенный ЧтениеJSON(Строка Стр, Число Поз = 1);
//#  Строка ЗаписьJSON(Неопределенный Значение, Число ПереносСтрок = 0, Строка Отступ = "");
//#  Неопределенный ЗагрузитьJSON(Строка ИмяФайла);
//#  void СохранитьJSON(Строка ИмяФайла, Неопределенный Значение, Число ПереносСтрок = 0, Строка Отступ = "");
//#}

//Соответствие значений JSON значениям 1С
//Запись - Структура
//Массив - СписокЗначений
//Число - Число
//Строка - Строка с поддержкой  \', \", \\, \/, \t, \n, \r, \f, \b; без поддержки \uFFFF.
//Литерал true - "true"
//Литерал false - "false"
//Литерал null - "null"


Перем ИспользоватьScriptControl Экспорт;
Перем мСкрипт;


//*******************************************
Функция Unicode2Ascii(КодСимволаUnicode)
	
	Перем СимвAscii;
	
	bindata = СоздатьОбъект("Binarydata");
	bindata.Кодировка = 2;
    bindata.ЗаписатьДанные(КодСимволаUnicode, 1);
	bindata.Перейти(0, 0);
	bindata.ПрочитатьСтроку(СимвAscii);
	
	Возврат СимвAscii;
	
КонецФункции


//*******************************************
Функция ПолучитьСимволUnicode(HEX)
	
	КодСимволаUnicode = 0;
	Множитель = 1;
	Для Тек = 1 По СтрДлина(Лев(HEX, 4)) Цикл
		КодСимволаUnicode = КодСимволаUnicode * 16;
		ЦифраHEX = Сред(HEX, Тек, 1);
		Код = КодСимв(ЦифраHEX);
		Если (Код >= 48) И (Код <= 57) Тогда //0..9
			Код = Код - 48;
		ИначеЕсли (Код >= 65) И (Код <= 70) Тогда //A..F
			Код = Код - 55;
		ИначеЕсли (Код >= 97) И (Код <= 102) Тогда //a..f
			Код = Код - 87;
		КонецЕсли;
		КодСимволаUnicode = КодСимволаUnicode + Код;
	КонецЦикла;
	
	Возврат Unicode2Ascii(КодСимволаUnicode);
	
КонецФункции


//*******************************************
Функция ЧтениеJSON(Стр, Поз = 1) Экспорт Далее


//*******************************************
Функция ЭтоПробельныйСимвол(Символ)
	
	Если Символ = " " Тогда
		Возврат 1;
	ИначеЕсли Символ = Симв(9) Тогда
		Возврат 1;
	ИначеЕсли Символ = Симв(10) Тогда
		Возврат 1;
	ИначеЕсли Символ = Симв(13) Тогда
		Возврат 1;
	ИначеЕсли Символ = Симв(160) Тогда
		Возврат 1;
	Иначе
		Возврат 0;
	КонецЕсли;

КонецФункции


//*******************************************
//При входе Поз указывает на {
//При выходе Поз указывает на }
Функция ЧтениеJSON_Структура(Стр, Поз)
	
	ЗначениеСтруктура = СоздатьОбъект("Структура");
    
	Длина = СтрДлина(Стр);
	Ключ = "";
	ЧитаемКлюч = 0;
	Пока Поз <= Длина Цикл
		
		Поз = Поз + 1;
		Символ = Сред(Стр, Поз, 1);
		
		Если Символ = """" Тогда
			Если ЧитаемКлюч = 0 Тогда
				ЧитаемКлюч = 1;
			Иначе
				ЧитаемКлюч = 0;
			КонецЕсли;
		ИначеЕсли ЧитаемКлюч = 1 Тогда
			Ключ = Ключ + Символ;
		ИначеЕсли Символ = ":" Тогда
			Поз = Поз + 1;
			Значение = ЧтениеJSON(Стр, Поз);
			ЗначениеСтруктура.Вставить(Ключ, Значение);
			Ключ = "";
		ИначеЕсли Символ = "}" Тогда
			Прервать;
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат ЗначениеСтруктура;
	
КонецФункции


//*******************************************
//При входе Поз указывает на [
//При выходе Поз указывает на ]
Функция ЧтениеJSON_Массив(Стр, Поз)
	
	ЗначениеМассив = СоздатьОбъект("СписокЗначений");
	
	Длина = СтрДлина(Стр);
	Пока Поз <= Длина Цикл
		
		Поз = Поз + 1;
		Символ = Сред(Стр, Поз, 1);
		
		Если Символ = "]" Тогда
			Прервать;
		ИначеЕсли ЭтоПробельныйСимвол(Символ) = 1 Тогда
			Продолжить;
		Иначе
			ЭлементМассива = ЧтениеJSON(Стр, Поз);
			Если ТипЗначения(ЭлементМассива) > 0 Тогда
				ЗначениеМассив.ДобавитьЗначение(ЭлементМассива);
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	
	Возврат ЗначениеМассив;
	
КонецФункции


//*******************************************
//При входе Поз указывает на "
//При выходе Поз указывает на "
Функция ЧтениеJSON_Строка(Стр, Поз)
	
	ЗначениеСтрока = "";
	
	Длина = СтрДлина(Стр);
	Пока Поз <= Длина Цикл
		
		Поз = Поз + 1;
		Символ = Сред(Стр, Поз, 1);
		
		Если Символ = "\" Тогда //экранированные символы (\', \", \\, \/, \t, \n, \r, \f, \b, \uFFFF)
			Поз = Поз + 1;
			Символ = Сред(Стр, Поз, 1);
			Если Символ = "t" Тогда
				Символ = Симв(9);
			ИначеЕсли Символ = "n" Тогда
				Символ = Симв(10);
			ИначеЕсли Символ = "r" Тогда
				Символ = Симв(13);
			ИначеЕсли Символ = "f" Тогда
				Символ = Симв(12);
			ИначеЕсли Символ = "b" Тогда
				Символ = Симв(8);
			ИначеЕсли Символ = "u" Тогда
				Символ = ПолучитьСимволUnicode(Сред(Стр, Поз + 1, 4));
				Поз = Поз + 4;
			КонецЕсли;
		ИначеЕсли Символ = """" Тогда
			//конец строки
			Прервать;
		КонецЕсли;
		
		ЗначениеСтрока = ЗначениеСтрока + Символ;
	КонецЦикла;

	Возврат ЗначениеСтрока;
	
КонецФункции


//*******************************************
//При входе Поз указывает на первую цифру или десятичную точку или минус
//При выходе Поз указывает на символ за последней цифрой
Функция ЧтениеJSON_Число(Стр, Поз)
	
	ЗначениеЧисло = 0;
	Знак = 1;
	
	Длина = СтрДлина(Стр);
	ДесятичныйДелитель = 0;
	Пока Поз <= Длина Цикл
		
		Символ = Сред(Стр, Поз, 1);

		Если Символ = "." Тогда
			ДесятичныйДелитель = 1;
		ИначеЕсли Символ = "-" Тогда
			Знак = -1;
		ИначеЕсли (Символ >= "0") И (Символ <= "9") Тогда
			Если ДесятичныйДелитель = 0 Тогда
				ЗначениеЧисло = ЗначениеЧисло * 10;
				ЗначениеЧисло = ЗначениеЧисло + Число(Символ);
			Иначе
				ДесятичныйДелитель = ДесятичныйДелитель * 10;
				ЗначениеЧисло = ЗначениеЧисло + Число(Символ) / ДесятичныйДелитель;
			КонецЕсли;
		Иначе
			Поз = Поз - 1;
			Прервать;
		КонецЕсли;
		
		Поз = Поз + 1;
		
	КонецЦикла;
	
	Возврат Знак * ЗначениеЧисло;
	
КонецФункции


//*******************************************
Функция ПолучитьСкрипт()
	
	Если ПустоеЗначение(мСкрипт) = 1 Тогда
		
		мСкрипт =  СоздатьОбъект("MSScriptControl.ScriptControl");
		мСкрипт.Language = "jscript";
		Код = "
		|function parseJSON(strJSON) {
		|	var tmpFunc = (
		|		new Function('return('+strJSON+');')
		|	)();
		|	return(tmpFunc);
		|}
		|
		|// Получить элемент массива
		|function aGet(Array, index) {
		|	return(Array[index]);
		|}
		|
		|// Получить ключ пары по индексу
		|function oKey(Obj, index) {
		|	var size = 0, key;
		|	for (key in Obj) {
		|		if (size == index)
		|			break;
		|		if (Obj.hasOwnProperty(key))
		|			size++;
		|	}
		|	return(key);
		|}
		|
		|// Получить значение пары по ключу
		|function oValueByKey(Obj, key) {
		|	return(Obj[key]);
		|}
		|
		|//Получить количество пар в объекте
		|Object.size = function(obj) {
		|	var size = 0, key;
		|	for (key in obj) {
		|		if (obj.hasOwnProperty(key)) size++;
		|	}
		|	return(size);
		|}
		|
		|//Получить размер объекта (количество пар в нём)
		|function oSize(Obj) {
		|	return(Object.size(Obj));
		|}
		|
		|// Получить тип объекта (number, string, object, array)
		|function eType(Element) {
		|	if (Element instanceof Array) {
		|		return(""array"");
		|	} else if (Object.prototype.toString.call(Element) === '[object Array]') {
		|		return(""array"");
		|	} else {
		|		return(typeof(Element));
		|	}
		|}
		|";
		мСкрипт.AddCode(Код);
	КонецЕсли;
	
	Возврат мСкрипт;
	
КонецФункции


//*******************************************
Функция ЧтениеОбъектаСкрипт(Скрипт, Объект)
	
	Значение = ПолучитьПустоеЗначение();
	
	ТипОбъекта = Скрипт.run("eType", Объект);
	
	Если ТипОбъекта = "object" Тогда
		
		Значение = СоздатьОбъект("Структура");
		Для Тек = 0 По Скрипт.run("oSize", Объект) - 1 Цикл
			КлючЭлемента = Скрипт.run("oKey", Объект, Тек);
			ЗначениеЭлемента = Скрипт.run("oValueByKey", Объект, КлючЭлемента);
			Значение.Вставить(КлючЭлемента, ЧтениеОбъектаСкрипт(Скрипт, ЗначениеЭлемента));
		КонецЦикла;  

	ИначеЕсли ТипОбъекта = "array" Тогда
		
		Значение = СоздатьОбъект("СписокЗначений");
		Для Тек = 0 По Объект.length - 1 Цикл
			ЗначениеЭлемента = Скрипт.run("aGet", Объект, Тек);
			Значение.ДобавитьЗначение(ЧтениеОбъектаСкрипт(Скрипт, ЗначениеЭлемента));
		КонецЦикла;
	
	ИначеЕсли ТипОбъекта = "string" Тогда
		
		Значение = Объект;
		
	ИначеЕсли ТипОбъекта = "number" Тогда
		
		Значение = Окр(Объект, 10);
		
	ИначеЕсли ТипОбъекта = "undefined" Тогда
		
		Значение = ПолучитьПустоеЗначение();
		
	Иначе
		Сообщить(ТипОбъекта);
	КонецЕсли;
	
	Возврат Значение;
	
КонецФункции


//*******************************************
Функция ЧтениеJSON(Стр, Поз = 1) Экспорт
	
	Значение = ПолучитьПустоеЗначение();
	
	Если ИспользоватьScriptControl = 0 Тогда
			
		Длина = СтрДлина(Стр);
		Пока Поз <= Длина Цикл
			Символ = Сред(Стр, Поз, 1);
			Если Символ = "{" Тогда
				//Структура
				Значение = ЧтениеJSON_Структура(Стр, Поз);
			ИначеЕсли Символ = "[" Тогда
				//Массив
				Значение = ЧтениеJSON_Массив(Стр, Поз);
			ИначеЕсли (Символ >= "0") И (Символ <= "9") ИЛИ (Символ = ".") ИЛИ (Символ = "-") Тогда
				//Число
				Значение = ЧтениеJSON_Число(Стр, Поз);
			ИначеЕсли Символ = """" Тогда
				//Строка
				Значение = ЧтениеJSON_Строка(Стр, Поз);
			ИначеЕсли Нрег(Сред(Стр, Поз, 4)) = "true" Тогда
				//литерал true
				Поз = Поз + 3;
				//Значение = ?(мСпособЛитерала = 1, "true", 1);
				Значение = "true";
			ИначеЕсли Нрег(Сред(Стр, Поз, 5)) = "false" Тогда
				//литерал false
				Поз = Поз + 4;
				//Значение = ?(мСпособЛитерала = 1, "false", 0);
				Значение = "false";
			ИначеЕсли Нрег(Сред(Стр, Поз, 4)) = "null" Тогда
				//литерал null
				Поз = Поз + 3;
				//Значение = ?(мСпособЛитерала = 1, "null", 0);
				//Значение = "null";
				Значение = ПолучитьПустоеЗначение();
			Иначе
				Поз = Поз + 1;
				Продолжить;
			КонецЕсли;
			Прервать;
		КонецЦикла;
		
	Иначе
		
		Если СтрДлина(Стр) > 0 Тогда
			Скрипт = ПолучитьСкрипт();
			
			Попытка
				OleExSup = СоздатьОбъект("OleExSup");
			Исключение
				Попытка
				    ЗагрузитьВнешнююКомпоненту("OLEExSup.dll");
				    //Сообщить("Компонента OLEExSup загружена!");
				Исключение
				    Сообщить("Пытались, но не загрузили компоненту OLEExSup :(");
				КонецПопытки;	
				OleExSup = СоздатьОбъект("OleExSup");
			КонецПопытки;
			Рез = OleExSup.ВызватьОЛЕМетод(Скрипт, "run", "parseJSON", Стр);
			//Рез = Скрипт.run("parseJSON", Стр);
			
			Значение = ЧтениеОбъектаСкрипт(Скрипт, Рез);
			
		КонецЕсли;
		
	КонецЕсли;
	
	Возврат Значение;
	
КонецФункции


//*******************************************
Функция ЗагрузитьJSON(ИмяФайла) Экспорт
	
	Значение = ПолучитьПустоеЗначение();
	Файл = СоздатьОбъект("BinaryData");
	Файл.Кодировка = 3;
	Если Файл.ПодключитьсяКФайлу(ИмяФайла, 2, 1) = 1 Тогда
		СтрJSON = "";
		Стр = "";
		Пока Файл.ПрочитатьСтроку(Стр) = 1 Цикл
			Если ПустаяСтрока(СтрJSON) = 0 Тогда
				СтрJSON = СтрJSON + РазделительСтрок;
			КонецЕсли;
			СтрJSON = СтрJSON + Стр;
		КонецЦикла;
		Значение = ЧтениеJSON(СтрJSON);
	КонецЕсли;

	Возврат Значение;
	
КонецФункции


//*******************************************
Функция ЗаписьJSON(Значение, ПереносСтрок = 0, Отступ = "") Экспорт
	
	Если ПереносСтрок = 1 Тогда
		Отступ1 = РазделительСтрок + Отступ;
		Отступ2 = Отступ1 + " ";
		Двоеточие = " : ";
	Иначе
		Отступ1 = "";
		Отступ2 = "";
		Двоеточие = ":";
	КонецЕсли;
	
	Стр = "";
	Если ТипЗначенияСтр(Значение) = "Структура" Тогда
		Стр = Стр + "{";
		Для Тек = 1 По Значение.Количество() Цикл
			ИмяСвойства = "";
			ЗначениеСвойства = Значение.Получить(Тек, ИмяСвойства);
			Стр = Стр + Отступ2 + """" + ИмяСвойства + """" + Двоеточие + ЗаписьJSON(ЗначениеСвойства, ПереносСтрок, Отступ + " ");
			Если Тек < Значение.Количество() Тогда
				Стр = Стр + ", ";
			КонецЕсли;
		КонецЦикла;
		Стр = Стр + ?(Значение.Количество() > 0, Отступ1, "") + "}";
		
	ИначеЕсли ТипЗначенияСтр(Значение) = "СписокЗначений" Тогда
		Стр = Стр + "[";
		Для Тек = 1 По Значение.РазмерСписка() Цикл
			ЗначениеЭлемента = Значение.ПолучитьЗначение(Тек);
			Стр = Стр + Отступ2 + ЗаписьJSON(ЗначениеЭлемента, ПереносСтрок, Отступ + " ");
			Если Тек < Значение.РазмерСписка() Тогда
				Стр = Стр + ", ";
			КонецЕсли;
		КонецЦикла;
		Стр = Стр + ?(Значение.РазмерСписка() > 0, Отступ1, "") + "]";
		
	ИначеЕсли ТипЗначенияСтр(Значение) = "Строка" Тогда
		Если Значение = "true" Тогда
			Стр = Стр + "true";
		ИначеЕсли Значение = "false" Тогда
			Стр = Стр + "false";
		ИначеЕсли Значение = "null" Тогда
			Стр = Стр + "null";
		Иначе
			СтрЗначение = Значение;
			СтрЗначение = СтрЗаменить(СтрЗначение, "\",  "\\");
			СтрЗначение = СтрЗаменить(СтрЗначение, "/",  "\/");
			СтрЗначение = СтрЗаменить(СтрЗначение, """", "\""");
			СтрЗначение = СтрЗаменить(СтрЗначение, Симв(8),  "\b");
			СтрЗначение = СтрЗаменить(СтрЗначение, Симв(9),  "\t");
			СтрЗначение = СтрЗаменить(СтрЗначение, Симв(10), "\n");
			СтрЗначение = СтрЗаменить(СтрЗначение, Симв(12), "\f");
			СтрЗначение = СтрЗаменить(СтрЗначение, Симв(13), "\r");
			Стр = Стр + """" + СтрЗначение + """";
		КонецЕсли;
		
	ИначеЕсли ТипЗначенияСтр(Значение) = "Число" Тогда
		Стр = Стр + Строка(Значение);
		
	ИначеЕсли ТипЗначенияСтр(Значение) = "Дата" Тогда
		СтрЗначение = Формат(Значение, "ДГГГГММДД");
		СтрЗначение = Лев(СтрЗначение, 4) + "-" + Сред(СтрЗначение, 5, 2) + "-" + Прав(СтрЗначение, 2);
		Стр = Стр + """" + СтрЗначение + """";
	ИначеЕсли Значение = ПолучитьПустоеЗначение() Тогда
		Стр = Стр + "null";
	КонецЕсли;
	
	Возврат Стр;
	
КонецФункции


//*******************************************
Процедура СохранитьJSON(ИмяФайла, Значение, ПереносСтрок = 0, Отступ = "") Экспорт
	
	СтрJSON = ЗаписьJSON(Значение, ПереносСтрок, Отступ);
	
	Файл = СоздатьОбъект("BinaryData");
	Если Файл.ПодключитьсяКФайлу(ИмяФайла, 2, 2) = 1 Тогда
		Файл.ЗаписатьСтроку(СтрJSON, 1);
	КонецЕсли;
	
КонецПроцедуры


//*******************************************
Процедура Конструктор()
	
	ИспользоватьScriptControl = 0;
	
КонецПроцедуры

Показать
4. slim747 18.02.24 22:18 Сейчас в теме
ОК. Буду разбирать информацию. Благодарю за помощь.
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот