Добрый день всем!

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

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

```1c
    &НаКлиенте
    Процедура Запрос(Команда)

    Объект.ТЧДанные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.Закрыть();

    КонецПроцедуры
```
---
К сожалению, все сломалось, при чтении в строку :(
В итоге нашел простое решение. После чтения первого "type": "fbs", создаю переменную type с текущим значением = "fbs" и на следующем шаге очищаю ее, после прочтения значения "present". Собственно код ниже, работает корректно как с файлом, так и со строкой, может кому пригодится.

```1c
    &НаКлиенте
    Процедура ЗапросНа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.Закрыть();
    КонецПроцедуры
```
---
Проверять наличие существующей строки в таблице не предлагать?
---
Буду рад, любой подсказке.
---
А я разве не подсказал?
---
Проверяемая строка имеет тип "число" с пустым значением (в отладчике вижу "0" в этой ячейке), Пока не понял, какую проверку прикрутить, чтобы в цикле не проходить по ней повторно.
---
Причем тут строка, если я тебе про таблицу говорю?
---
1. На первом шаге я создаю строку в таблице с ячейками: (Артикул, Наименование, Количество)
2. Далее записываю в эту строку значение Артикул
3. Затем записываю значение Наименование
4. Записываю значение Количество

На каком этапе проверять наличие строки ?
---
На моменте обработки любого элемента массива из джинсового файла.
---
Сообщение было скрыто модератором.
---
А где тут одинаковые ключи?
Условно массив одинаковых структур, например: справочник "stocks" или табличная часть "stocks" какого-то документа.
---
Да у него в другом проблема. У него в файле разные концепции маркетплейсов в массивах (FBO, FBS, etc) а он хочет записывать только первый.
Проблема архитектуры. Что-то не то напроектировал.
Ну и с таблицами работать не умеет...
---
Судя по коду - он строку добавляет в любом случае, а реквизитом её заполняет только в случае концепции FBS. Что уже не халяль.
---
Этом мой первый опыт, поэтому архитектура тут пока не в приоритете. Мне важно понять принцип. Возможно правильный путь это читать JSON в структуру и из нее уже адресно обращаться к данным массива, но я пока иду путем потокового чтения.
Ну и собственно опыта нет вообще, потому мучаюсь, как умею. Уже несколько дней сижу над этим условием, перечитал по теме и перепробовал разного. По какому условию проверять строку в таблице, не врубаюсь. В потоке текущие значения меняются, не пойму, к чему привязаться. Покажите путь или, что прочитать в справке?
---
По какому условию проверять строку в таблице, не врубаюсь. Я тебе не писал про строку. Я тебе писал про таблицу.
В потоке текущие значения меняются, не пойму, к чему привязаться. В потоке - меняются. В таблице - нет.
Покажите путь или, что прочитать в справке? Сколько раз я уже написал слово "таблица"?
---
Проверять наличие существующей строки в таблице не предлагать?

Тогда я вообще запутался. Можешь объяснить, что нужно сделать с таблицей ?
---
Проверить в ней наличие нужных строк.
Ты не путай строку таблицы со строкой джинсы.
---
В правильном направлении иду ?

```1c
    Если Объект.ТЧДанныеJS.НайтиСтроки(Новый Структура("Наименование", "fbs")) <> Неопределено Тогда
```
---
Нет. Что возвращает метод НайтиСтроки()? Лень прочитать СП?
---
(22)
Не лень, читаю. К сожалению пока не могу найти примеры под свой случай. НайтиСтроки - возвращает массив, далее, как я понимаю, нужно его перебрать в цикле и найти искомое. Вот тут сейчас и мучаюсь, т.к. не пойму пока, как правильно это сделать.

```1c
    &НаКлиенте
    Процедура ЗапросНа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.Закрыть();

    КонецПроцедуры
```
---
(16)
(22)

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

так проверяю наличие строки:

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

весь код (с проверкой по количеству в значении):

```1c
    &НаКлиенте
    Процедура ЗапросНа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.Закрыть();
    КонецПроцедуры
```
---
Так ты сразу строку и обрабатывай в этом цикле. Ты же видишь, что у тебя переменная ЕстьСтрока примет значение только для последней строки цикла.
---
Так тоже не работает.

```1c
    &НаКлиенте
    Процедура ЗапросНа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.Закрыть();
    КонецПроцедуры
```
---
Если быть точнее, то если первый present = 0, тогда в таблицу запишется 0 и следующий present перезапишет его. Плюс к этому, еще и обработка длится дольше в разы.

Например, при таких значениях JSON, в табличку запишется "11"
                    {
                        "type": "fbs",
                        "present": 0,
                        "reserved": 0
                    },
                    {
                        "type": "fbo",
                        "present": 11,
                        "reserved": 0
                    },
                    {
                        "type": "crossborder",
                        "present": 12,
                        "reserved": 0
                    }
---
А чем такой метод не подходит:

```1c
    ЧтениеJSON = Новый ЧтениеJSON;
    ЧтениеJSON.УстановитьСтроку(СтрокаJSON);
    Данные = ПрочитатьJSON(ЧтениеJSON);
```
---
Хотя в этом случае возможно и так сработает:

```1c
    ЧтениеJSON = Новый ЧтениеJSON;
    ЧтениеJSON.ОткрытьФайл("C:\www\response.json");
    Данные = ПрочитатьJSON(ЧтениеJSON);
```

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

Я бы так делал, не стал бы самостоятельно JSON разбирать.
Хотя в старых разработках разбирал, и до сих пор работает...
---
(17)
 Читаю файл только для теста, чтобы видеть, когда происходить перезапись количества. В оригинале я разбираю HTTP-запрос как раз этим методом:

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

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

может ещё соответствие, но тут не нужно)
Раз уж зашел разговор, как я понимаю, соответствие может обрабатывать ключи с пробелами или другими символами, которые не принимает 1С (если такие появятся в будущем). Как считаете, нужно это учитывать при разработке ?
---
Да, соответствие нужно именно для тех случаев, когда имя свойства содержит запрещённые символы для имён свойств структуры.
---
```1c
    Функция ПолучитьМассивДанных(Чтение)
    Массив = Новый Массив;
    Пока Чтение.Прочитать() Цикл
    Если Чтение.ТипТекущегоЗначения = ТипЗначенияJSON.НачалоОбъекта Тогда
    Структура = Новый Структура;
    ИначеЕсли Чтение.ТипТекущегоЗначения = ТипЗначенияJSON.ИмяСвойства Тогда
    ИмяСвойства = Чтение.ТекущееЗначение;
    ИначеЕсли Чтение.ТипТекущегоЗначения = ТипЗначенияJSON.Строка Тогда
    Структура.Вставить(ИмяСвойства, Чтение.ТекущееЗначение);
    ИначеЕсли Чтение.ТипТекущегоЗначения = ТипЗначенияJSON.Число Тогда
    Структура.Вставить(ИмяСвойства, Чтение.ТекущееЗначение);
    ИначеЕсли Чтение.ТипТекущегоЗначения = ТипЗначенияJSON.Булево Тогда
    Структура.Вставить(ИмяСвойства, Чтение.ТекущееЗначение);
    ИначеЕсли Чтение.ТипТекущегоЗначения = ТипЗначенияJSON.КонецОбъекта Тогда
    Массив.Добавить(Структура);
    ИначеЕсли Чтение.ТипТекущегоЗначения = ТипЗначенияJSON.НачалоМассива И НЕ (Структура = Неопределено) Тогда
    Структура.Вставить(ИмяСвойства, ПолучитьМассивДанных(Чтение));
    ИначеЕсли Чтение.ТипТекущегоЗначения = ТипЗначенияJSON.КонецМассива Тогда
    Возврат Массив;
    КонецЕсли;
    КонецЦикла;
    КонецФункции
```
---
Этим когда-то пользовался... Это только кусочек, но подумать есть над чем.
---
Пока придумал такой способ - костыль, но хотя бы рабочий. После записи значения "type", сохраняю в переменную текущею строку и увеличиваю ее на единицу (это число следующей строки для записи), и далее сравниваю уже с этой переменной. Если следующая текущая строка совпадает с переменной, тогда записываю, иначе пропускаю.

```1c
    &НаКлиенте
    Процедура ЗапросНа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.Закрыть();
    КонецПроцедуры
```
---
К сожалению, все сломалось, при чтении в строку :(
В итоге нашел простое решение. После чтения первого "type": "fbs", создаю переменную type с текущим значением = "fbs" и на следующем шаге очищаю ее, после прочтения значения "present". Собственно код ниже, работает корректно как с файлом, так и со строкой, может кому пригодится.

```1c
    &НаКлиенте
    Процедура ЗапросНа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.Закрыть();
    КонецПроцедуры
```