Как правильно сформировать структуру JSON для работы с онлайн-кассами в 1С 7.7?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При разработке механизмов взаимодействия 1С:Предприятия 7.7 с современными онлайн-кассами (ККТ) через Web-интерфейс или драйверы (например, АТОЛ 10) основной сложностью становится отсутствие встроенных средств работы с форматом JSON. В отличие от версии 8.3, где существуют объекты ЗаписьJSON и ЧтениеJSON, в «семерке» программистам приходится либо собирать строки вручную, либо использовать внешние компоненты и COM-объекты.

В данной статье мы разберем несколько подходов к генерации корректных JSON-запросов, проанализируем их плюсы и минусы, а также выясним, почему «ручная» склейка строк может стать источником серьезных ошибок при печати чеков.

Проблема ручной сборки JSON-строки

Рассмотрим стандартный подход, который часто выбирают разработчики на начальном этапе. Он заключается в последовательной проверке заполненности полей и склеивании их в одну длинную строку. Разберем пример функции для формирования объекта operator (кассир):


Функция ОбъектОператор(name, vatin="")
    name  = СокрЛП(name);
    vatin = СокрЛП(vatin);
    
    Если ПустаяСтрока(name)=1 Тогда 
        Сообщить("ОбъектОператор: Параметр name не заполнен!");
        Возврат "null";
    КонецЕсли;
    
    MainSection = """operator"":{""name"":""" + name + """";
    
    Если ПустоеЗначение(vatin)=0 Тогда  
        MainSection = MainSection + ",""vatin"":""" + vatin + """";
    КонецЕсли;      
    
    MainSection = MainSection + "}";
    Возврат MainSection;
КонецФункции

Проанализируем этот код. Основная проблема здесь заключается в управлении разделителями (запятыми) и экранировании спецсимволов. Если параметров становится больше (например, 10-15 тегов для позиции товара), количество условий Если растет в геометрической прогрессии, а риск забыть или поставить лишнюю запятую превращает отладку в кошмар. Более того, если в имени оператора встретится кавычка (например, ООО "Ромашка"), сформированный JSON будет невалидным, и касса вернет ошибку.

Метод 1: Использование Списка Значений как универсальной структуры

Одним из элегантных решений для 1С 7.7 является использование объекта СписокЗначений для хранения пар «Ключ-Значение». Мы можем создать универсальную функцию, которая будет обходить этот список и формировать JSON автоматически. Рассмотрим пример функции, которая преобразует СписокЗначений в JSON-объект:


Функция СформироватьJSONИзСписка(лСЗ)
    Перем ТекстJSON, Сч, Ключ, Значение, ТипЗнач;
    ТекстJSON = "{";
    Для Сч = 1 По лСЗ.РазмерСписка() Цикл
        Значение = лСЗ.ПолучитьЗначение(Сч, Ключ);
        // Пропускаем пустые значения, если это критично для ККТ
        Если ПустоеЗначение(Значение) = 1 Тогда
            Продолжить;
        КонецЕсли;
        
        // Добавляем запятую перед всеми элементами, кроме первого
        Если СтрДлина(ТекстJSON) > 1 Тогда
            ТекстJSON = ТекстJSON + ",";
        КонецЕсли;
        
        ТекстJSON = ТекстJSON + """" + Ключ + """:";
        
        // Определяем тип и добавляем кавычки только для строк
        Если ТипЗначенияСтр(Значение) = "Число" Тогда
            ТекстJSON = ТекстJSON + Строка(Значение);
        Иначе
            // Здесь должна быть функция ЭкранироватьСпецСимволы(Значение)
            ТекстJSON = ТекстJSON + """" + Значение + """";
        КонецЕсли;
    КонецЦикла;
    ТекстJSON = ТекстJSON + "}";
    Возврат ТекстJSON;
КонецФункции

Такой подход позволяет писать код в стиле «конструктора», что гораздо нагляднее и проще для восприятия:


лСЗ = СоздатьОбъект("СписокЗначений");
лСЗ.ДобавитьЗначение("Иванов И.И.", "name");
лСЗ.ДобавитьЗначение("123456789012", "vatin");
Запрос = СформироватьJSONИзСписка(лСЗ);

Метод 2: Применение Scripting.Dictionary

Для создания более сложных, вложенных структур идеально подходит COM-объект Scripting.Dictionary. Он работает быстрее, чем СписокЗначений, и позволяет создавать настоящие деревья объектов, которые легко сериализовать в JSON. Выясним преимущества этого метода:

  1. Уникальность ключей: Объект автоматически контролирует, чтобы вы не добавили один и тот же параметр дважды.
  2. Вложенность: В качестве значения одного словаря можно передать другой словарь (объект) или СписокЗначений (массив).
  3. Отсутствие лишних данных: Вы можете написать рекурсивную функцию обхода, которая просто не будет включать в итоговую строку ключи с пустыми значениями.

Это особенно важно для драйверов АТОЛ 10-й версии. Согласно формату фискальных данных (ФФД), многие теги являются необязательными. Если вы передадите в JSON пустое поле "vatin": "", драйвер может выдать ошибку «Некорректный реквизит», тогда как полное отсутствие этого поля в структуре будет воспринято корректно.

Метод 3: Использование MSScriptControl.ScriptControl (JavaScript)

Если вам нужно гарантировать 100% валидность JSON без написания собственных парсеров, можно делегировать эту задачу среде JavaScript через COM-объект MSScriptControl.ScriptControl. Проанализируем, как это работает:


// Создаем объект скрипта
sc = СоздатьОбъект("MSScriptControl.ScriptControl");
sc.Language = "JScript";
// Добавляем вспомогательную функцию
sc.AddCode("function toJSON(obj) { return JSON.stringify(obj); }");

// В JScript можно динамически создавать объекты
// В 1С 7.7 мы можем передать данные через Dictionary
// и вызвать метод stringify

Этот метод позволяет избежать проблем с экранированием символов \, ", /, а также корректно обрабатывать переносы строк в названиях товаров, что часто встречается в розничной торговле.

Обработка ответов от ККТ (Парсинг JSON)

Не менее важной задачей является разбор ответа от веб-сервиса кассы. Рассмотрим пример рекурсивной процедуры, предложенной участниками сообщества, которая разбирает JSON-строку и заполняет СписокЗначений:


Процедура ЗаполнитьДанныеИзОтветаJSON(Результат, ТекстJSON, ТипДанных)
    ТекстJSON = СокрЛП(Сред(ТекстJSON, 2));    
    НомерЗначения = 0;
    Пока ТекстJSON <> "" Цикл
        ПервыйСимвол = Лев(ТекстJSON, 1);
        Если ПервыйСимвол = "{" Тогда
            Значение = СоздатьОбъект("СписокЗначений");
            ЗаполнитьДанныеИзОтветаJSON(Значение, ТекстJSON, "Структура");
            // Логика добавления в Результат...
        ИначеЕсли ПервыйСимвол = "]" Тогда
            // Обработка закрытия массива...
            Возврат;
        // ... (далее идет логика поиска двоеточия и извлечения ключей)
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Важный нюанс: При парсинге ответов в 1С 7.7 штатными средствами необходимо предварительно очищать строку от экранированных кавычек \" и других спецсимволов с помощью функции СтрЗаменить(), чтобы алгоритм поиска разделителей работал корректно.

Рекомендации по реализации

Подведем итоги и сформируем рекомендации для разработки обмена с онлайн-кассами:

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

← На главную