Как правильно читать JSON с одинаковыми ключами?

1. dejurik 29.01.24 16:29 Сейчас в теме
Добрый день всем!

Читаю построчно JSON-файл с одинаковыми ключами. При записи в таблицу, последние значения затирают первые. Прошу подсказать, как правильно описать условие, при котором в таблицу попадут значения ключей только первого объекта из массива.

Пример массива (файл прикрепил к сообщению):
"stocks": [
{
"type": "fbs",
"present": 10,
"reserved": 0
},
{
"type": "fbo",
"present": 11,
"reserved": 0
},
{
"type": "crossborder",
"present": 12,
"reserved": 0
}
]

&НаКлиенте
Процедура Запрос(Команда) 
    
    Объект.ТЧДанныеJS.Очистить();
    СоответствиеПолей = Новый Соответствие;
    СоответствиеПолей.Вставить("offer_id", "Артикул"); 
    СоответствиеПолей.Вставить("type", "Наименование");  
    СоответствиеПолей.Вставить("present", "Количество");
    
    ЧтениеJS = Новый ЧтениеJSON;
    ЧтениеJS.ОткрытьФайл("C:\www\response.json"); 
    
    Результат = Новый Структура;
    ПоследнееИмяРеквизита = Неопределено;
    
    ИмяТекущегоСвойства = "";    
    Пока ЧтениеJS.Прочитать() Цикл 
        ТипJS = ЧтениеJS.ТипТекущегоЗначения;
        //тут считываем Имя(Ключ) свойства JSON  ( offer_id, type, present )
        Если ТипJS = ТипЗначенияJSON.ИмяСвойства Тогда  
            ИмяТекущегоСвойства = ЧтениеJS.ТекущееЗначение;
            Если ИмяТекущегоСвойства = "offer_id" Тогда
                СтрокаТЧ = Объект.ТЧДанныеJS.Добавить();
            КонецЕсли;
            
        //тут считываем Значение свойства JSON    
        ИначеЕсли ТипJS = ТипЗначенияJSON.Строка ИЛИ ТипJS = ТипЗначенияJSON.Число
            ИЛИ ТипJS = ТипЗначенияJSON.Булево ИЛИ ТипJS = ТипЗначенияJSON.Null Тогда
            Если ИмяТекущегоСвойства = "type" И ЧтениеJS.ТекущееЗначение = "fbs" 
                ИЛИ ИмяТекущегоСвойства = "offer_id" ИЛИ ИмяТекущегоСвойства = "present" Тогда 
                
                //по имени свойста JSON получаем соответствие реквизита ТЧ 
                ИмяРеквизитаТЧ = СоответствиеПолей.Получить(ИмяТекущегоСвойства);
                //если соответствие найдено, тогда заполняем реквизит в строке ТЧ   
                Если ИмяРеквизитаТЧ <> Неопределено Тогда 
                    СтрокаТЧ[ИмяРеквизитаТЧ] = ЧтениеJS.ТекущееЗначение; 
                КонецЕсли; 
            КонецЕсли;
        КонецЕсли;     
    КонецЦикла;
    ЧтениеJS.Закрыть();
    
КонецПроцедуры
Показать
Прикрепленные файлы:
response.json
По теме из базы знаний
Найденные решения
31. dejurik 04.02.24 04:20 Сейчас в теме
(30) К сожалению, все сломалось, при чтении в строку :(
В итоге нашел простое решение. После чтения первого "type": "fbs", создаю переменную type с текущим значением = "fbs" и на следующем шаге очищаю ее, после прочтения значения "present". Собственно код ниже, работает корректно как с файлом, так и со строкой, может кому пригодится.
     
&НаКлиенте
  Процедура ЗапросНаOzon(Команда) 
     Объект.ТЧДанныеJS.Очистить();
     СоответствиеПолей = Новый Соответствие;
     СоответствиеПолей.Вставить("offer_id", "Артикул");
     СоответствиеПолей.Вставить("type", "Наименование");  
     СоответствиеПолей.Вставить("present", "Количество");
     
     ЧтениеJS = Новый ЧтениеJSON;
     ЧтениеJS.ОткрытьФайл("C:\www\response.json");   
     
     ИмяТекущегоСвойстваJS = "";    
     Пока ЧтениеJS.Прочитать() Цикл 
         ТипJS = ЧтениеJS.ТипТекущегоЗначения;
         //считываем Имя(Ключ) свойства JSON  ( offer_id, type, present )
         Если ТипJS = ТипЗначенияJSON.ИмяСвойства Тогда  
             ИмяТекущегоСвойстваJS = ЧтениеJS.ТекущееЗначение;
             Если ИмяТекущегоСвойстваJS = "offer_id" Тогда
                 СтрокаТЧ = Объект.ТЧДанныеJS.Добавить();
             КонецЕсли;
         //считываем Значение свойства JSON    
         ИначеЕсли ТипJS = ТипЗначенияJSON.Строка ИЛИ ТипJS = ТипЗначенияJSON.Число Тогда
             //считываем offer_id    
             Если ИмяТекущегоСвойстваJS = "offer_id" Тогда 
                 ИмяРеквизитаТЧ = СоответствиеПолей.Получить(ИмяТекущегоСвойстваJS); //по имени свойста JSON получаем соответствие реквизита ТЧ  
                 Если ИмяРеквизитаТЧ <> Неопределено Тогда //если нашли имя реквизита в соответствии, тогда
                     СтрокаТЧ[ИмяРеквизитаТЧ] = ЧтениеJS.ТекущееЗначение; //при соответствии ИмяРеквизитаТЧ заполняем ТекущееЗначение в строке ТЧ 
                 КонецЕсли;
             //считываем type
             ИначеЕсли ИмяТекущегоСвойстваJS = "type" И ЧтениеJS.ТекущееЗначение = "fbs" Тогда
                 type = ЧтениеJS.ТекущееЗначение;
                 ИмяРеквизитаТЧ = СоответствиеПолей.Получить(ИмяТекущегоСвойстваJS);   
                 Если ИмяРеквизитаТЧ <> Неопределено Тогда 
                     СтрокаТЧ[ИмяРеквизитаТЧ] = ЧтениеJS.ТекущееЗначение;   
                 КонецЕсли;      
             //считываем present
             ИначеЕсли    ИмяТекущегоСвойстваJS = "present" Тогда 
                  Если type = "fbs" Тогда 
                     ИмяРеквизитаТЧ = СоответствиеПолей.Получить(ИмяТекущегоСвойстваJS);  
                     Если ИмяРеквизитаТЧ <> Неопределено Тогда 
                         СтрокаТЧ[ИмяРеквизитаТЧ] = ЧтениеJS.ТекущееЗначение;  
                         type = ""
                     КонецЕсли;  
                 КонецЕсли;
             КонецЕсли;   
         КонецЕсли; 
     КонецЦикла;
     ЧтениеJS.Закрыть();
 КонецПроцедуры 

Показать
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. user2033930 29.01.24 17:05 Сейчас в теме
Проверять наличие существующей строки в таблице не предлагать?
PhoenixAOD; dejurik; +2 Ответить 7
3. dejurik 29.01.24 17:10 Сейчас в теме
(2) Буду рад, любой подсказке.
4. user2033930 29.01.24 17:11 Сейчас в теме
(3) А я разве не подсказал?
5. dejurik 29.01.24 17:25 Сейчас в теме
(4) Проверяемая строка имеет тип "число" с пустым значением (в отладчике вижу "0" в этой ячейке), Пока не понял, какую проверку прикрутить, чтобы в цикле не проходить по ней повторно.
6. user2033930 29.01.24 17:27 Сейчас в теме
(5) Причем тут строка, если я тебе про таблицу говорю?
7. dejurik 29.01.24 17:36 Сейчас в теме
(6)

1. На первом шаге я создаю строку в таблице с ячейками: (Артикул, Наименование, Количество)
2. Далее записываю в эту строку значение Артикул
3. Затем записываю значение Наименование
4. Записываю значение Количество

На каком этапе проверять наличие строки ?
9. user2033930 29.01.24 18:11 Сейчас в теме
(7) На моменте обработки любого элемента массива из джинсового файла.
12. пользователь 29.01.24 18:30
Сообщение было скрыто модератором.
...
8. Said-We 29.01.24 17:56 Сейчас в теме
(1) А где тут одинаковые ключи?
Условно массив одинаковых структур, например: справочник "stocks" или табличная часть "stocks" какого-то документа.
10. user2033930 29.01.24 18:16 Сейчас в теме
(8) Да у него в другом проблема. У него в файле разные концепции маркетплейсов в массивах (FBO, FBS, etc) а он хочет записывать только первый.
Проблема архитектуры. Что-то не то напроектировал.
Ну и с таблицами работать не умеет...
Fox-trot; +1 Ответить
11. user2033930 29.01.24 18:25 Сейчас в теме
(10) Судя по коду - он строку добавляет в любом случае, а реквизитом её заполняет только в случае концепции FBS. Что уже не халяль.
13. dejurik 29.01.24 19:10 Сейчас в теме
Этом мой первый опыт, поэтому архитектура тут пока не в приоритете. Мне важно понять принцип. Возможно правильный путь это читать JSON в структуру и из нее уже адресно обращаться к данным массива, но я пока иду путем потокового чтения.
Ну и собственно опыта нет вообще, потому мучаюсь, как умею. Уже несколько дней сижу над этим условием, перечитал по теме и перепробовал разного. По какому условию проверять строку в таблице, не врубаюсь. В потоке текущие значения меняются, не пойму, к чему привязаться. Покажите путь или, что прочитать в справке?
14. user2033930 29.01.24 19:22 Сейчас в теме
(13)
По какому условию проверять строку в таблице, не врубаюсь.
Я тебе не писал про строку. Я тебе писал про таблицу.
В потоке текущие значения меняются, не пойму, к чему привязаться.
В потоке - меняются. В таблице - нет.
Покажите путь или, что прочитать в справке?
Сколько раз я уже написал слово "таблица"?
15. dejurik 29.01.24 19:33 Сейчас в теме
(14)
Проверять наличие существующей строки в таблице не предлагать?


Тогда я вообще запутался. Можешь объяснить, что нужно сделать с таблицей ?
16. user2033930 29.01.24 19:49 Сейчас в теме
(15) Проверить в ней наличие нужных строк.
Ты не путай строку таблицы со строкой джинсы.
19. dejurik 31.01.24 00:18 Сейчас в теме
(16)
В правильном направлении иду ?

Если Объект.ТЧДанныеJS.НайтиСтроки(Новый Структура("Наименование", "fbs")) <> Неопределено Тогда
22. user2033930 31.01.24 09:57 Сейчас в теме
(19) Нет. Что возвращает метод НайтиСтроки()? Лень прочитать СП?
23. dejurik 31.01.24 10:11 Сейчас в теме
(21)
(22)
Не лень, читаю. К сожалению пока не могу найти примеры под свой случай. НайтиСтроки - возвращает массив, далее, как я понимаю, нужно его перебрать в цикле и найти искомое. Вот тут сейчас и мучаюсь, т.к. не пойму пока, как правильно это сделать.

&НаКлиенте
 Процедура ЗапросНаOzon(Команда) 
     
     Объект.ТЧДанныеJS.Очистить();
     СоответствиеПолей = Новый Соответствие;
     СоответствиеПолей.Вставить("offer_id", "Артикул"); 
     СоответствиеПолей.Вставить("type", "Наименование");  
     СоответствиеПолей.Вставить("present", "Количество");
     
     ЧтениеJS = Новый ЧтениеJSON;
     ЧтениеJS.ОткрытьФайл("C:\www\response.json"); 
     
     ИмяТекущегоСвойства = "";    
     Пока ЧтениеJS.Прочитать() Цикл 
         ТипJS = ЧтениеJS.ТипТекущегоЗначения;
         //тут считываем Имя(Ключ) свойства JSON  ( offer_id, type, present )   
         Если ТипJS = ТипЗначенияJSON.ИмяСвойства Тогда  
             ИмяТекущегоСвойства = ЧтениеJS.ТекущееЗначение;
             Если ИмяТекущегоСвойства = "offer_id" Тогда
                 СтрокаТЧ = Объект.ТЧДанныеJS.Добавить();
             КонецЕсли;
             //тут считываем Значение свойства JSON    
         ИначеЕсли ТипJS = ТипЗначенияJSON.Строка ИЛИ ТипJS = ТипЗначенияJSON.Число  
             ИЛИ ТипJS = ТипЗначенияJSON.Булево ИЛИ ТипJS = ТипЗначенияJSON.Null Тогда
             
             Если ИмяТекущегоСвойства = "type" И ЧтениеJS.ТекущееЗначение = "fbs" 
                 ИЛИ ИмяТекущегоСвойства = "offer_id" ИЛИ ИмяТекущегоСвойства = "present"  Тогда
             
                 //по имени свойста JSON получаем соответствие реквизита ТЧ 
                 ИмяРеквизитаТЧ = СоответствиеПолей.Получить(ИмяТекущегоСвойства);
                 //если соответствие найдено, тогда заполняем реквизит в строке ТЧ   
                 Если ИмяРеквизитаТЧ <> Неопределено Тогда //если мы нашли имя реквизита в соответствии, тогда
                     
                     //Если в табличной части в колонке "Наименование" есть строка с пустым значением, тогда  
                     Для каждого ИскомаяСтрокаТЧ Из Объект.ТЧДанныеJS.НайтиСтроки(Новый Структура("Наименование", "")) Цикл
                     КонецЦикла;
                     
                     СтрокаТЧ[ИмяРеквизитаТЧ] = ЧтениеJS.ТекущееЗначение; //при соответствии ИмяРеквизитаТЧ заполняем ТекущееЗначение в строке ТЧ 
                 КонецЕсли;  
             КонецЕсли;
         КонецЕсли;
     КонецЦикла;
     
     ЧтениеJS.Закрыть();
     
 КонецПроцедуры  

Показать
26. dejurik 02.02.24 08:11 Сейчас в теме
(25)
(16)
(22)

Если я правильно разобрался, то проверка наличия строки не дает нужный результат. Если проверяю наличие данных в "Наименовании", тогда Количество будет перезаписываться новым значением. Собственно проверка по количеству в значении = 0 или количество строк < 1 тоже ничего не дает (т.к. строка присутствует до проверки). Пните в нужную сторону.

так проверяю наличие строки:
                 МассивСтрокТЧ = Объект.ТЧДанныеJS.НайтиСтроки(Новый Структура("Наименование", "fbs"));
                  Для каждого ИскомаяСтрокаТЧ Из МассивСтрокТЧ Цикл  
                     Если ИскомаяСтрокаТЧ.Наименование = "fbs" Тогда
                         ЕстьСтрока = Истина;  
                     Иначе   
                         ЕстьСтрока = Ложь;  
                     КонецЕсли;
                 КонецЦикла;


весь код (с проверкой по количеству в значении):
&НаКлиенте
 Процедура ЗапросНаOzon(Команда) 
     Объект.ТЧДанныеJS.Очистить();
     СоответствиеПолей = Новый Соответствие;
     СоответствиеПолей.Вставить("offer_id", "Артикул");
     СоответствиеПолей.Вставить("type", "Наименование");  
     СоответствиеПолей.Вставить("present", "Количество");
     
     ЧтениеJS = Новый ЧтениеJSON;
     ЧтениеJS.ОткрытьФайл("C:\www\response.json"); 
     
     ИмяТекущегоСвойстваJS = "";    
     Пока ЧтениеJS.Прочитать() Цикл 
         ТипJS = ЧтениеJS.ТипТекущегоЗначения;
         //тут считываем Имя(Ключ) свойства JSON 
         Если ТипJS = ТипЗначенияJSON.ИмяСвойства Тогда  
             ИмяТекущегоСвойстваJS = ЧтениеJS.ТекущееЗначение;  
             //добавляем новую строку в ТЧ
             Если ИмяТекущегоСвойстваJS = "offer_id" Тогда
                 СтрокаТЧ = Объект.ТЧДанныеJS.Добавить();
             КонецЕсли; 
             //считываем offer_id    
         ИначеЕсли ТипJS = ТипЗначенияJSON.Строка И ИмяТекущегоСвойстваJS = "offer_id" Тогда
             ИмяРеквизитаТЧ = СоответствиеПолей.Получить(ИмяТекущегоСвойстваJS);
             Если ИмяРеквизитаТЧ <> Неопределено Тогда 
                 СтрокаТЧ[ИмяРеквизитаТЧ] = ЧтениеJS.ТекущееЗначение;
             КонецЕсли;
             //считываем type    
         ИначеЕсли ТипJS = ТипЗначенияJSON.Строка И ИмяТекущегоСвойстваJS = "type" И ЧтениеJS.ТекущееЗначение = "fbs" Тогда
             ИмяРеквизитаТЧ = СоответствиеПолей.Получить(ИмяТекущегоСвойстваJS);  
             Если ИмяРеквизитаТЧ <> Неопределено Тогда 
                 СтрокаТЧ[ИмяРеквизитаТЧ] = ЧтениеJS.ТекущееЗначение; 
                 
                 МассивСтрокТЧ = Объект.ТЧДанныеJS.НайтиСтроки(Новый Структура("Наименование", "fbs"));
                  Для каждого ИскомаяСтрокаТЧ Из МассивСтрокТЧ Цикл  
                     Если ИскомаяСтрокаТЧ.Количество = 0 Тогда
                         ЕстьСтрока = Истина;  
                     Иначе   
                         ЕстьСтрока = Ложь;  
                     КонецЕсли;
                 КонецЦикла;
             КонецЕсли;
             //считываем present    
         ИначеЕсли ТипJS = ТипЗначенияJSON.Число И ИмяТекущегоСвойстваJS = "present" Тогда 
             Если ЕстьСтрока = Истина Тогда
                                
             ИмяРеквизитаТЧ = СоответствиеПолей.Получить(ИмяТекущегоСвойстваJS);   
             Если ИмяРеквизитаТЧ <> Неопределено Тогда 
                 СтрокаТЧ[ИмяРеквизитаТЧ] = ЧтениеJS.ТекущееЗначение;
             КонецЕсли;  
             КонецЕсли;
         КонецЕсли;
     КонецЦикла; 
     ЧтениеJS.Закрыть(); 
 КонецПроцедуры  
Показать
27. user2033930 02.02.24 09:27 Сейчас в теме
(26) Так ты сразу строку и обрабатывай в этом цикле. Ты же видишь, что у тебя переменная ЕстьСтрока примет значение только для последней строки цикла.
28. dejurik 02.02.24 14:23 Сейчас в теме
(27)
Так тоже не работает.
 &НаКлиенте
 Процедура ЗапросНаOzon(Команда) 
     Объект.ТЧДанныеJS.Очистить();
     СоответствиеПолей = Новый Соответствие;
     СоответствиеПолей.Вставить("offer_id", "Артикул");
     СоответствиеПолей.Вставить("type", "Наименование");  
     СоответствиеПолей.Вставить("present", "Количество");
     
     ЧтениеJS = Новый ЧтениеJSON;
     ЧтениеJS.ОткрытьФайл("C:\www\response.json"); 
     
     ИмяТекущегоСвойстваJS = "";    
     Пока ЧтениеJS.Прочитать() Цикл 
         ТипJS = ЧтениеJS.ТипТекущегоЗначения;
         //тут считываем Имя(Ключ) свойства JSON  ( offer_id, type, present )   
         Если ТипJS = ТипЗначенияJSON.ИмяСвойства Тогда  
             ИмяТекущегоСвойстваJS = ЧтениеJS.ТекущееЗначение;  
             //добавляем новую строку в ТЧ
             Если ИмяТекущегоСвойстваJS = "offer_id" Тогда
                 СтрокаТЧ = Объект.ТЧДанныеJS.Добавить();
             КонецЕсли; 
             //считываем offer_id    
         ИначеЕсли ТипJS = ТипЗначенияJSON.Строка И ИмяТекущегоСвойстваJS = "offer_id" Тогда
             ИмяРеквизитаТЧ = СоответствиеПолей.Получить(ИмяТекущегоСвойстваJS);  
             Если ИмяРеквизитаТЧ <> Неопределено Тогда 
                 СтрокаТЧ[ИмяРеквизитаТЧ] = ЧтениеJS.ТекущееЗначение;  
             КонецЕсли;
             //считываем type    
         ИначеЕсли ТипJS = ТипЗначенияJSON.Строка И ИмяТекущегоСвойстваJS = "type" И ЧтениеJS.ТекущееЗначение = "fbs" Тогда
             ИмяРеквизитаТЧ = СоответствиеПолей.Получить(ИмяТекущегоСвойстваJS);  
             Если ИмяРеквизитаТЧ <> Неопределено Тогда 
                 СтрокаТЧ[ИмяРеквизитаТЧ] = ЧтениеJS.ТекущееЗначение;  
             КонецЕсли;     
         ИначеЕсли    ТипJS = ТипЗначенияJSON.Число И ИмяТекущегоСвойстваJS = "present" Тогда      
             МассивСтрокТЧ = Объект.ТЧДанныеJS.НайтиСтроки(Новый Структура("Наименование", "fbs"));
             Для каждого ИскомаяСтрокаТЧ Из МассивСтрокТЧ Цикл  
                 Если ИскомаяСтрокаТЧ.Количество < 1 Тогда
                     //считываем present    
                     Если ТипJS = ТипЗначенияJSON.Число И ИмяТекущегоСвойстваJS = "present" Тогда 
                         ИмяРеквизитаТЧ = СоответствиеПолей.Получить(ИмяТекущегоСвойстваJS);  
                         Если ИмяРеквизитаТЧ <> Неопределено Тогда 
                             СтрокаТЧ[ИмяРеквизитаТЧ] = ЧтениеJS.ТекущееЗначение;  
                         КонецЕсли;  
                     КонецЕсли;
                 КонецЕсли
             КонецЦикла; 
         КонецЕсли;
     КонецЦикла; 
     ЧтениеJS.Закрыть(); 
 КонецПроцедуры 
Показать
29. dejurik 02.02.24 15:03 Сейчас в теме
(28)
Если быть точнее, то если первый present = 0, тогда в таблицу запишется 0 и следующий present перезапишет его. Плюс к этому, еще и обработка длится дольше в разы.

Например, при таких значениях JSON, в табличку запишется "11"
{
"type": "fbs",
"present": 0,
"reserved": 0
},
{
"type": "fbo",
"present": 11,
"reserved": 0
},
{
"type": "crossborder",
"present": 12,
"reserved": 0
}
17. dvk09 2 30.01.24 05:24 Сейчас в теме
А чем такой метод не подходит:
    ЧтениеJSON = Новый ЧтениеJSON;
    ЧтениеJSON.УстановитьСтроку(СтрокаJSON);
    Данные = ПрочитатьJSON(ЧтениеJSON);

18. dvk09 2 30.01.24 11:18 Сейчас в теме
Хотя в этом случае возможно и так сработает:
    ЧтениеJSON = Новый ЧтениеJSON;
    ЧтениеJSON.ОткрытьФайл("C:\www\response.json");
    Данные = ПрочитатьJSON(ЧтениеJSON);



На выходе в Данные попадёт объект (массив или структура, может ещё соответствие, но тут не нужно).
В этом случае будет структура со свойством "stocks" в котором будет массив структур.
Обходите массив и проверяете какие свойства у каждого элемента массива.
Ну и заполняете если нужно. (Есть ещё замечательная функция ЗаполнитьЗначенияСвойств...)

Я бы так делал, не стал бы самостоятельно JSON разбирать.
Хотя в старых разработках разбирал, и до сих пор работает...
dejurik; o4karek; +2 Ответить
20. dejurik 31.01.24 00:44 Сейчас в теме
(18)
(17)
Читаю файл только для теста, чтобы видеть, когда происходить перезапись количества. В оригинале я разбираю HTTP-запрос как раз этим методом:

 ЧтениеJS = Новый ЧтениеJSON;
ЧтениеJS.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку("UTF-8"));     
ДанныеJS = ПрочитатьJSON(ЧтениеJS);


Метод со структурой я обязательно реализую после того, как разберусь с построчным чтением.

может ещё соответствие, но тут не нужно)

Раз уж зашел разговор, как я понимаю, соответствие может обрабатывать ключи с пробелами или другими символами, которые не принимает 1С (если такие появятся в будущем). Как считаете, нужно это учитывать при разработке ?
21. dvk09 2 31.01.24 09:20 Сейчас в теме
(20) Да, соответствие нужно именно для тех случаев, когда имя свойства содержит запрещённые символы для имён свойств структуры.
24. dvk09 2 31.01.24 11:18 Сейчас в теме
Функция ПолучитьМассивДанных(Чтение)
    Массив = Новый Массив;
    Пока Чтение.Прочитать() Цикл
        Если Чтение.ТипТекущегоЗначения = ТипЗначенияJSON.НачалоОбъекта Тогда
            Структура = Новый Структура;
        ИначеЕсли Чтение.ТипТекущегоЗначения = ТипЗначенияJSON.ИмяСвойства Тогда
            ИмяСвойства = Чтение.ТекущееЗначение;
        ИначеЕсли Чтение.ТипТекущегоЗначения = ТипЗначенияJSON.Строка Тогда
            Структура.Вставить(ИмяСвойства, Чтение.ТекущееЗначение);
        ИначеЕсли Чтение.ТипТекущегоЗначения = ТипЗначенияJSON.Число Тогда
            Структура.Вставить(ИмяСвойства, Чтение.ТекущееЗначение);
        ИначеЕсли Чтение.ТипТекущегоЗначения = ТипЗначенияJSON.Булево Тогда
            Структура.Вставить(ИмяСвойства, Чтение.ТекущееЗначение);
        ИначеЕсли Чтение.ТипТекущегоЗначения = ТипЗначенияJSON.КонецОбъекта Тогда
            Массив.Добавить(Структура);
        ИначеЕсли Чтение.ТипТекущегоЗначения = ТипЗначенияJSON.НачалоМассива И НЕ (Структура = Неопределено) Тогда
            Структура.Вставить(ИмяСвойства, ПолучитьМассивДанных(Чтение));
        ИначеЕсли Чтение.ТипТекущегоЗначения = ТипЗначенияJSON.КонецМассива Тогда
            Возврат Массив;
        КонецЕсли;
    КонецЦикла;
КонецФункции

Показать
25. dvk09 2 31.01.24 11:21 Сейчас в теме
(24) Этим когда-то пользовался... Это только кусочек, но подумать есть над чем.
30. dejurik 02.02.24 19:25 Сейчас в теме
Пока придумал такой способ - костыль, но хотя бы рабочий. После записи значения "type", сохраняю в переменную текущею строку и увеличиваю ее на единицу (это число следующей строки для записи), и далее сравниваю уже с этой переменной. Если следующая текущая строка совпадает с переменной, тогда записываю, иначе пропускаю.
&НаКлиенте
 Процедура ЗапросНаOzon(Команда) 
     Объект.ТЧДанныеJS.Очистить();
     СоответствиеПолей = Новый Соответствие;
     СоответствиеПолей.Вставить("offer_id", "Артикул");
     СоответствиеПолей.Вставить("type", "Наименование");  
     СоответствиеПолей.Вставить("present", "Количество");
     
     ЧтениеJS = Новый ЧтениеJSON;
     ЧтениеJS.ОткрытьФайл("C:\www\response.json"); 
     
     ИмяТекущегоСвойстваJS = "";    
     Пока ЧтениеJS.Прочитать() Цикл 
         ТипJS = ЧтениеJS.ТипТекущегоЗначения;
         //тут считываем Имя(Ключ) свойства JSON  ( offer_id, type, present )   
         Если ТипJS = ТипЗначенияJSON.ИмяСвойства Тогда  
             ИмяТекущегоСвойстваJS = ЧтениеJS.ТекущееЗначение;  
             //добавляем новую строку в ТЧ
             Если ИмяТекущегоСвойстваJS = "offer_id" Тогда
                 СтрокаТЧ = Объект.ТЧДанныеJS.Добавить();
             КонецЕсли; 
             //считываем offer_id    
         ИначеЕсли ТипJS = ТипЗначенияJSON.Строка И ИмяТекущегоСвойстваJS = "offer_id" Тогда
             ИмяРеквизитаТЧ = СоответствиеПолей.Получить(ИмяТекущегоСвойстваJS);   
             Если ИмяРеквизитаТЧ <> Неопределено Тогда 
                 СтрокаТЧ[ИмяРеквизитаТЧ] = ЧтениеJS.ТекущееЗначение;  
             КонецЕсли;
             //считываем type    
         ИначеЕсли ТипJS = ТипЗначенияJSON.Строка И ИмяТекущегоСвойстваJS = "type" И ЧтениеJS.ТекущееЗначение = "fbs" Тогда
             ИмяРеквизитаТЧ = СоответствиеПолей.Получить(ИмяТекущегоСвойстваJS);  
             Если ИмяРеквизитаТЧ <> Неопределено Тогда
                 СтрокаТЧ[ИмяРеквизитаТЧ] = ЧтениеJS.ТекущееЗначение;  
             КонецЕсли;      
             СохраненнаяСтрокаJS = ЧтениеJS.ТекущаяСтрока + 1; //сохраняем текущую строку и увеличиваем ее на единицу
             //считываем present
         ИначеЕсли    ТипJS = ТипЗначенияJSON.Число И ИмяТекущегоСвойстваJS = "present" Тогда 
             Если СохраненнаяСтрокаJS = ЧтениеJS.ТекущаяСтрока Тогда 
                 ИмяРеквизитаТЧ = СоответствиеПолей.Получить(ИмяТекущегоСвойстваJS);   
                 Если ИмяРеквизитаТЧ <> Неопределено Тогда 
                     СтрокаТЧ[ИмяРеквизитаТЧ] = ЧтениеJS.ТекущееЗначение;
                 КонецЕсли;  
             КонецЕсли;
         КонецЕсли
     КонецЦикла; 
     ЧтениеJS.Закрыть(); 
 КонецПроцедуры 
Показать
31. dejurik 04.02.24 04:20 Сейчас в теме
(30) К сожалению, все сломалось, при чтении в строку :(
В итоге нашел простое решение. После чтения первого "type": "fbs", создаю переменную type с текущим значением = "fbs" и на следующем шаге очищаю ее, после прочтения значения "present". Собственно код ниже, работает корректно как с файлом, так и со строкой, может кому пригодится.
     
&НаКлиенте
  Процедура ЗапросНаOzon(Команда) 
     Объект.ТЧДанныеJS.Очистить();
     СоответствиеПолей = Новый Соответствие;
     СоответствиеПолей.Вставить("offer_id", "Артикул");
     СоответствиеПолей.Вставить("type", "Наименование");  
     СоответствиеПолей.Вставить("present", "Количество");
     
     ЧтениеJS = Новый ЧтениеJSON;
     ЧтениеJS.ОткрытьФайл("C:\www\response.json");   
     
     ИмяТекущегоСвойстваJS = "";    
     Пока ЧтениеJS.Прочитать() Цикл 
         ТипJS = ЧтениеJS.ТипТекущегоЗначения;
         //считываем Имя(Ключ) свойства JSON  ( offer_id, type, present )
         Если ТипJS = ТипЗначенияJSON.ИмяСвойства Тогда  
             ИмяТекущегоСвойстваJS = ЧтениеJS.ТекущееЗначение;
             Если ИмяТекущегоСвойстваJS = "offer_id" Тогда
                 СтрокаТЧ = Объект.ТЧДанныеJS.Добавить();
             КонецЕсли;
         //считываем Значение свойства JSON    
         ИначеЕсли ТипJS = ТипЗначенияJSON.Строка ИЛИ ТипJS = ТипЗначенияJSON.Число Тогда
             //считываем offer_id    
             Если ИмяТекущегоСвойстваJS = "offer_id" Тогда 
                 ИмяРеквизитаТЧ = СоответствиеПолей.Получить(ИмяТекущегоСвойстваJS); //по имени свойста JSON получаем соответствие реквизита ТЧ  
                 Если ИмяРеквизитаТЧ <> Неопределено Тогда //если нашли имя реквизита в соответствии, тогда
                     СтрокаТЧ[ИмяРеквизитаТЧ] = ЧтениеJS.ТекущееЗначение; //при соответствии ИмяРеквизитаТЧ заполняем ТекущееЗначение в строке ТЧ 
                 КонецЕсли;
             //считываем type
             ИначеЕсли ИмяТекущегоСвойстваJS = "type" И ЧтениеJS.ТекущееЗначение = "fbs" Тогда
                 type = ЧтениеJS.ТекущееЗначение;
                 ИмяРеквизитаТЧ = СоответствиеПолей.Получить(ИмяТекущегоСвойстваJS);   
                 Если ИмяРеквизитаТЧ <> Неопределено Тогда 
                     СтрокаТЧ[ИмяРеквизитаТЧ] = ЧтениеJS.ТекущееЗначение;   
                 КонецЕсли;      
             //считываем present
             ИначеЕсли    ИмяТекущегоСвойстваJS = "present" Тогда 
                  Если type = "fbs" Тогда 
                     ИмяРеквизитаТЧ = СоответствиеПолей.Получить(ИмяТекущегоСвойстваJS);  
                     Если ИмяРеквизитаТЧ <> Неопределено Тогда 
                         СтрокаТЧ[ИмяРеквизитаТЧ] = ЧтениеJS.ТекущееЗначение;  
                         type = ""
                     КонецЕсли;  
                 КонецЕсли;
             КонецЕсли;   
         КонецЕсли; 
     КонецЦикла;
     ЧтениеJS.Закрыть();
 КонецПроцедуры 

Показать
Оставьте свое сообщение

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