Работа с JSON из 1С

Захотел брать в таблицы jqgrid данные из 1С. Казалось бы простая задача, сформировать в 1С массив JSON. Однако оказалось не все так просто. В УПП 1.3 общих функций для работы с JSON нет. А в Управлении Торговлей — есть. Пришлось выдернуть нужные функции оттуда.

Итак, необходимо переписать аналог вот этого куска кода в PHP, который формирует JSOIN нужного формата:

        $responce=new stdClass();
	$responce->page = $page;
	$responce->total = $total_pages;
	$responce->records = $count;
	$i=0;
	while($row = mysqli_fetch_array($result)) {
	    $responce->rows[$i]['id']=$row['id'];
	    if ($row['active']=="1")
		{$responce->rows[$i]['cell']=array("<img src=controller/client/themes/".$cfg->theme."/ico/accept.png>",$row['id'],$row['name'],$row['comment']);} else
		{$responce->rows[$i]['cell']=array("<img src=controller/client/themes/".$cfg->theme."/ico/cancel.png>",$row['id'],$row['name'],$row['comment']);};
	    $i++;
	}
	echo json_encode($responce);

, на языке 1С:

	Запрос = Новый Запрос;
 	Запрос.Текст = 	 	
	"ВЫБРАТЬ
	|	ТоварыНаСкладахОстатки.Склад КАК Склад,
	|	ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура,
	|	ТоварыНаСкладахОстатки.СерияНоменклатуры КАК СерияНоменклатуры,
	|	СУММА(ТоварыНаСкладахОстатки.КоличествоОстаток) КАК КоличествоОстаток
	|ИЗ
	|	РегистрНакопления.ТоварыНаСкладах.Остатки(&дата, ) КАК ТоварыНаСкладахОстатки
	|ГДЕ
	|	ТоварыНаСкладахОстатки.Номенклатура В ИЕРАРХИИ(&Номенклатура)
	|
	|СГРУППИРОВАТЬ ПО
	|	ТоварыНаСкладахОстатки.Номенклатура,
	|	ТоварыНаСкладахОстатки.СерияНоменклатуры,
	|	ТоварыНаСкладахОстатки.Склад
	|
	|УПОРЯДОЧИТЬ ПО
	|	Склад,
	|	Номенклатура,
	|	СерияНоменклатуры
	|ИТОГИ
	|	СУММА(КоличествоОстаток)
	|ПО
	|	Склад,
	|	Номенклатура";

   	  Запрос.УстановитьПараметр("Номенклатура",справочники.Номенклатура.НайтиПоНаименованию(kode));
	  Запрос.УстановитьПараметр("дата",КонецДня(ТекущаяДата()));         
	  Результат = Запрос.Выполнить().Выгрузить();  
	    Данные = Новый Структура;
		Данные.Вставить("page", 1);
		Данные.Вставить("total", 1);
		Данные.Вставить("records", Результат.Количество());
		Данные.Вставить("rows", Новый Массив);	  
		ном=0;
		для каждого стр из Результат цикл
			ном=ном+1;
			cell=Новый Массив;
			cell.добавить(ном);
			cell.добавить(стр.Склад);
			cell.добавить(стр.Номенклатура);
			cell.добавить(стр.СерияНоменклатуры);
			cell.добавить(стр.КоличествоОстаток);
 		  Данные.rows.Добавить(Новый Структура("id,cell",ном,cell));			
	  конеццикла;
		рез = СформироватьСтрокуJSONИзСтруктуры(Данные);	 
	возврат рез;

Ну и «выдернутый» из УТ код:

Функция ПреобразоватьвСистему(Число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");

		ИначеЕсли ТипЗнч(Элемент) = Тип("Дата") Тогда
			// преобразование в 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 + Формат(Элемент.Значение, "БЛ=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, ":");
				Если Поз = 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, "Массив");

		Результат.Вставить("Значение", МассивДанных);

	КонецЕсли;

	Возврат Результат;

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

Вот еще хорошие примеры взятые с просторов интернета:

////////////////////////////////////////////////////////
// преобразование простой структуры
Данные = Новый Структура("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"}]

Комментарии:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Лимит времени истёк. Пожалуйста, перезагрузите CAPTCHA.

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.