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

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

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

Понимание разницы между ссылкой и объектом

Первая и самая важная деталь, которую мы должны усвоить: методы сохранения данных работают по-разному в зависимости от того, что мы им передаем. Если передать методу ЗначениеВФайл или любому сериализатору ссылку (ДокументСсылка), система сохранит только уникальный идентификатор (GUID) документа. При попытке восстановления мы получим ту же самую ссылку на тот же самый документ в базе, но никакие изменения, сделанные в памяти, не сохранятся.

Для того чтобы сохранить текущее состояние данных (реквизиты, табличные части), мы должны работать с типом Объект (например, ДокументОбъект или СправочникОбъект). Проанализируем, какими способами это можно сделать.

Способ 1: Сериализация в XML

Это классический и наиболее универсальный метод. Он позволяет превратить объект в текстовый формат, который легко прочитать или передать. Разберем по шагам, как реализовать сохранение объекта в строку XML и его последующее чтение.

Сохранение объекта в XML:


// Предположим, у нас есть переменная ДокументОбъект, полученная через ПолучитьОбъект()
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку(); // Будем сохранять в строку для наглядности

// Записываем объект. НазначениеТипаXML.Явное помогает избежать проблем при десериализации
ЗаписатьXML(ЗаписьXML, ДокументОбъект, НазначениеТипаXML.Явное);

ТекстXML = ЗаписьXML.Закрыть();
// Теперь переменную ТекстXML можно сохранить в текстовый файл через ТекстовыйДокумент

Восстановление объекта из XML:


ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(ТекстXML);

// Метод ПрочитатьXML создает НОВЫЙ экземпляр объекта в памяти
НовыйОбъект = ПрочитатьXML(ЧтениеXML);

// Важно: объект находится в памяти. Чтобы он попал в базу, нужно вызвать:
// НовыйОбъект.Записать();

Способ 2: Использование JSON и Сериализатора XDTO

Рассмотрим более современный подход, доступный в платформе 8.3. Формат JSON компактнее, чем XML, и работает быстрее. Для этого мы будем использовать СериализаторXDTO.

Этот метод удобен тем, что он автоматически обрабатывает структуру объекта 1С, включая все его вложенные части.

Пример записи в JSON:


ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();

// Используем глобальный контекст СериализаторXDTO
СериализаторXDTO.ЗаписатьJSON(ЗаписьJSON, ДокументОбъект, НазначениеТипаXML.Явное);

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

При восстановлении через СериализаторXDTO.ПрочитатьJSON мы получим готовый объект, с которым можно работать так же, как и в случае с XML.

Способ 3: Внутренний формат (ЗначениеВФайл и ЗначениеВСтрокуВнутр)

Выясним причину популярности и опасности встроенных методов 1С. Методы ЗначениеВФайл и ЗначениеВСтрокуВнутр сохраняют данные во внутреннем формате системы (похожем на структуру в фигурных скобках).

Важные нюансы:

  1. Как мы уже выяснили, передавать нужно именно ДокументОбъект.
  2. Опасность: формат ЗначениеВСтрокуВнутр завязан на внутренние идентификаторы метаданных. Если вы переименуете реквизит в конфигураторе или удалите его, старые файлы могут перестать читаться корректно.
  3. Этот способ подходит для «быстрого» сохранения здесь и сейчас, но не рекомендуется для долгосрочного хранения данных или обмена между разными базами.

Способ 4: Хранилище значения

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


// Сохраняем объект в хранилище (оно автоматически сжимает данные)
Хранилище = Новый ХранилищеЗначения(ДокументОбъект, Новый СжатиеДанных(9));

// Теперь это хранилище можно записать в реквизит с типом "ХранилищеЗначения"
// Извлечение:
ВосстановленныйОбъект = Хранилище.Получить();

Особенности работы в клиент-серверном режиме

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

Правильный алгоритм работы будет следующим:

  1. На сервере формируем данные (XML или JSON).
  2. Помещаем результат во Временное хранилище через ПоместитьВоВременноеХранилище().
  3. На клиенте получаем адрес хранилища и используем ПолучитьФайл(), чтобы предложить пользователю сохранить документ на его компьютер.

Высокая производительность с FastInfoset

Если наш документ содержит десятки тысяч строк в табличных частях, обычный XML может стать слишком тяжелым. В этом случае мы рекомендуем использовать формат FastInfoset (бинарный XML). Чтобы его задействовать, при открытии файла для записи нужно указать соответствующий параметр:

ЗаписьXML.ОткрытьФайл(ПутьКФайлу, , , , Истина);

Это позволит значительно уменьшить размер файла и ускорить процесс сериализации.

Резюме

Мы рассмотрели основные способы программной работы с состоянием объектов. Для большинства задач сериализация через XML или JSON является самым надежным и гибким решением. Главное — всегда помнить, что для сохранения данных нужно оперировать Объектом, а после восстановления — не забывать вызывать метод Записать(), если данные должны физически обновиться в базе данных.

← На главную