Как программно сохранить данные JSON в присоединенные файлы в 1С

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Анализ проблемы: почему стандартная запись в справочник не работает

Рассмотрим ситуацию: разработчик создает новый элемент в справочнике ЗаказКлиентаПрисоединенныеФайлы, заполняет реквизит ФайлХранилище строкой JSON и записывает объект. На первый взгляд всё верно, но при попытке открыть файл система выдает ошибку. Выясним причину этого поведения. В архитектуре БСП справочник «Присоединенные файлы» является лишь «оберткой» или карточкой файла. Сами двоичные данные (содержимое файла) хранятся либо в регистре сведений ДвоичныеДанныеФайлов, либо во внешних томах на диске сервера.

Если мы записываем данные только в справочник, игнорируя регистр сведений или механизмы работы с томами, стандартные команды «Открыть» или «Редактировать» не находят контента. Кроме того, прямая передача текстовой строки в реквизит типа ХранилищеЗначения без предварительной конвертации в двоичные данные часто приводит к повреждению структуры файла.

Шаг 1: Правильное формирование JSON и получение двоичных данных

Для начала нам необходимо создать JSON-структуру. Чтобы избежать проблем с кодировками и блокировками файлов, проанализируем наиболее эффективный способ — формирование данных в оперативной памяти с последующей конвертацией в ДвоичныеДанные. Рассмотрим следующий код:


// 1. Создаем структуру данных
СтруктураДанных = Новый Структура;
СтруктураДанных.Вставить("ДатаФормирования", ТекущаяДата());
СтруктураДанных.Вставить("НомерЗаказа", Объект.Номер);
СтруктураДанных.Вставить("Статус", "Выгружено");

// 2. Сериализуем структуру в строку JSON
ЗаписьJSON = Новый ЗаписьJSON;
ПараметрыЗаписи = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Авто, Символы.Таб);
ЗаписьJSON.УстановитьСтроку(ПараметрыЗаписи);
ЗаписатьJSON(ЗаписьJSON, СтруктураДанных);

СтрокаJSON = ЗаписьJSON.Закрыть();

// 3. Преобразуем строку в двоичные данные (UTF-8 без BOM)
ДанныеФайла = ПолучитьДвоичныеДанныеИзСтроки(СтрокаJSON, КодировкаТекста.UTF8, Ложь);

Обратите внимание на использование ПолучитьДвоичныеДанныеИзСтроки. Это позволяет нам сразу получить объект, готовый для сохранения в базу, минуя создание временных файлов на диске. Параметр Ложь в конце функции указывает на отсутствие метки BOM, что является стандартом для большинства современных интеграционных систем.

Шаг 2: Использование стандартных механизмов БСП (Рекомендуемый способ)

Вместо того чтобы вручную создавать элементы справочников и записи в регистрах, воспользуемся программным интерфейсом БСП. Модуль РаботаСФайлами содержит все необходимые инструменты. Проанализируем использование функции ПрисоединенныйФайлИзДвоичныхДанных. Этот метод берет на себя всю «черную работу»: создание элемента справочника, регистрацию данных в хранилище и привязку к владельцу.

Разберем реализацию по шагам:


// Предположим, СсылкаНаЗаказ — это ссылка на документ ЗаказКлиента
ПараметрыФайла = Новый Структура;
ПараметрыФайла.Вставить("Автор", Пользователи.ТекущийПользователь());
ПараметрыФайла.Вставить("ИмяФайлаБезРасширения", "Data_Export_" + Формат(ТекущаяДата(), "ДФ=yyyyMMdd"));
ПараметрыФайла.Вставить("РасширениеБезТочки", "json");
ПараметрыФайла.Вставить("ДатаМодификацииУниверсальная", ТекущаяДата());

// Вызов стандартной функции БСП
НовыйФайлСсылка = РаботаСФайлами.ПрисоединенныйФайлИзДвоичныхДанных(СсылкаНаЗаказ, ПараметрыФайла, ДанныеФайла);

Если ЗначениеЗаполнено(НовыйФайлСсылка) Тогда
    Сообщить("Файл успешно сохранен и прикреплен к заказу!");
КонецЕсли;

Этот подход гарантирует, что файл будет записан именно туда, куда указано в настройках системы (в базу или в том), и для него будут созданы все необходимые служебные записи. Вам не нужно знать точное имя справочника присоединенных файлов — система определит его автоматически по типу ссылки владельца.

Шаг 3: Ручной способ записи (если БСП не используется или сильно кастомизирована)

Если по каким-то причинам вы не можете использовать РаботаСФайлами, рассмотрим, как правильно выполнить запись «вручную», чтобы избежать ошибок доступа и пустых файлов. Выясним причину ошибки «Нет доступа к файлу», которая часто упоминается на форумах. Она возникает, если объект ЗаписьJSON еще открыт в момент попытки чтения файла в ДвоичныеДанные. Всегда вызывайте Закрыть() перед использованием файла.

Алгоритм ручной записи должен выглядеть так:

  1. Создание элемента справочника ...ПрисоединенныеФайлы.
  2. Заполнение реквизитов (Наименование, Владелец, ТипХранения).
  3. Запись элемента справочника для получения ссылки.
  4. Создание записи в регистре сведений ДвоичныеДанныеФайлов (или ПрисоединенныеФайлы в старых версиях).

Посмотрим на пример кода для ручной записи:


// Создаем карточку файла
НовыйФайл = Справочники.ЗаказКлиентаПрисоединенныеФайлы.СоздатьЭлемент();
НовыйФайл.Наименование = "ExportData.json";
НовыйФайл.ВладелецФайла = СсылкаДокПриход;
НовыйФайл.ДатаСоздания = ТекущаяДата();
НовыйФайл.Расширение = "json";
НовыйФайл.ТипХраненияФайла = Перечисления.ТипыХраненияФайлов.ВИнформационнойБазе;
НовыйФайл.Записать();

// Записываем данные в регистр сведений
МенеджерЗаписи = РегистрыСведений.ДвоичныеДанныеФайлов.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Файл = НовыйФайл.Ссылка;
МенеджерЗаписи.ДвоичныеДанныеФайла = Новый ХранилищеЗначения(ДанныеФайла, Новый СжатиеДанных(9));
МенеджерЗаписи.Записать(Истина);

Важный нюанс: при ручном подходе вы берете на себя ответственность за корректность заполнения всех полей, включая размер файла и контрольные суммы, если они требуются логикой вашей конфигурации. Именно поэтому использование РаботаСФайлами предпочтительнее.

Типичные ошибки и способы их решения

Проанализируем ситуации, когда что-то идет не так:

  1. Ошибка «Файл не найден» или «Доступ запрещен»: Обычно это происходит при работе с временными файлами на стороне сервера. Убедитесь, что вы используете ПолучитьИмяВременногоФайла() и закрыли все потоки записи (ЗаписьJSON, ЗаписьТекста) перед созданием объекта ДвоичныеДанные.
  2. Файл создается, но он пустой: Проверьте, был ли вызван метод Закрыть() у объекта записи. Данные сбрасываются из буфера в поток только в этот момент.
  3. Файл не виден в списке присоединенных файлов: Проверьте реквизит ВладелецФайла. Также убедитесь, что в конфигурации для данного справочника не настроены фильтры (например, по пометке удаления).

Подводя итог, можно сказать, что наиболее надежным и современным способом является работа через ДвоичныеДанные и стандартные модули БСП. Это избавляет от необходимости манипулировать регистрами напрямую и гарантирует стабильную работу системы даже после обновлений платформы или конфигурации.

← На главную